Configures an OpenLayers VectorTileSource object from the provided
Mapbox GL style object.
@param {Object} glSource The Mapbox GL map source of type 'vector'.
@param {string} accessToken The user's Mapbox tiles access token .
@param {Object} fetchOptions Options to use for fetch calls.

@returns {Object} Configured OpenLayers VectorTileSource.
function configureMvtSource(glSource, accessToken, fetchOptions) {
  if (glSource.tiles) {
    return new Promise((resolve, reject) => {
      // predefine the source in-case since it's needed for the tile_url_fn
      let source;
      let tile_url_fn;
      let tile_load_fn;
      // check the first tile to see if we need to do BBOX subsitution
      if (glSource.tiles[0].indexOf(BBOX_STRING) !== -1) {
        tile_url_fn = function(urlTileCoord, pixelRatio, projection) {
          // copy the src string.
          let img_src = glSource.tiles[0].slice();
          // check to see if a cache invalidation has been requested.
          const ck = source.get('_ck');
          if (ck !== undefined) {
            img_src = addParam(img_src, '_ck', ck);
          }
          const bbox = source.getTileGrid().getTileCoordExtent(urlTileCoord);
          return img_src.replace(BBOX_STRING, bbox.toString());
        };
      }
      if (fetchOptions.headers && fetchOptions.headers.get('Authorization')) {
        tile_load_fn = authVectorTileLoader(fetchOptions);
      }
      source = new VectorTileSource({
        urls: glSource.tiles,
        tileGrid: createXYZ({
          tileSize: 512,
          maxZoom: 'maxzoom' in glSource ? glSource.maxzoom : 22,
          minZoom: glSource.minzoom,
        }),
        attributions: glSource.attribution,
        format: new MvtFormat(),
        crossOrigin: 'crossOrigin' in glSource ? glSource.crossOrigin : 'anonymous',
        tileUrlFunction: tile_url_fn,
        tileLoadFunction: tile_load_fn,
      });
      resolve(source);
    });
  } else {
    let url = getTileJSONUrl(glSource, accessToken);
    return fetch(url, fetchOptions).then((response) => {
      if (response.ok) {
        return response.json();
      }
    })
      .then((json) => {
        return new VectorTileSource({
          crossOrigin: 'crossOrigin' in glSource ? glSource.crossOrigin : 'anonymous',
          attributions: json.attribution,
          format: new MvtFormat(),
          tileGrid: createXYZ({
            minZoom: json.minzoom,
            maxZoom: json.maxzoom,
            tileSize: 512
          }),
          urls: json.tiles,
        });
      });
  }
}