Revision 80776951675e2d55bae5159756ce793888ad986a authored by George Kalpakas on 26 November 2021, 17:46:30 UTC, committed by Dylan Hunn on 29 November 2021, 17:38:06 UTC
Previously, the mock packages created for `UmdDependencyHost`'s tests,
specified the entry-point as `esm2015`. This does not matter in tests,
since the packages are explicitly passed to the `UmdDependencyHost`
(while in reality the appropriate host would be determined based on the
name of the entry-point property - in this case, detecting the
entry-point as ES2015 and not UMD).

However, in order to avoid confusion, this commit updates the test
packages to use `main` (the default property used for the UMD format in
`package.json` files).

PR Close #44245
1 parent de0975c
Raw File
build-ngsw-config.js
// Imports
const {basename, dirname, resolve: resolvePath} = require('canonical-path');
const {mkdirSync, readFileSync, writeFileSync} = require('fs');
const {parse: parseJson} = require('json5');


// Constants
const FIREBASE_CONFIG_PATH = resolvePath(__dirname, '../firebase.json');
const NGSW_CONFIG_TEMPLATE_PATH = resolvePath(__dirname, '../ngsw-config.template.json');
const NGSW_CONFIG_OUTPUT_PATH = resolvePath(__dirname, '../src/generated/ngsw-config.json');

// Run
_main();

// Helpers
function _main() {
  const firebaseConfig = readJson(FIREBASE_CONFIG_PATH);
  const ngswConfig = readJson(NGSW_CONFIG_TEMPLATE_PATH);

  const firebaseRedirects = firebaseConfig.hosting.redirects;

  // Check that there are no regex-based redirects.
  const regexBasedRedirects = firebaseRedirects.filter(({regex}) => regex !== undefined);
  if (regexBasedRedirects.length > 0) {
    throw new Error(
      'The following redirects use `regex`, which is currently not supported by ' +
      `${basename(__filename)}:` +
      regexBasedRedirects.map(x => `\n  - ${JSON.stringify(x)}`).join(''));
  }

  // Check that there are no unsupported glob characters/patterns.
  const redirectsWithUnsupportedGlobs = firebaseRedirects
    .filter(({source}) => !/^(?:[/\w\-.*]|:\w+|@\([\w\-.|]+\))+$/.test(source));
  if (redirectsWithUnsupportedGlobs.length > 0) {
    throw new Error(
      'The following redirects use glob characters/patterns that are currently not supported by ' +
      `${basename(__filename)}:` +
      redirectsWithUnsupportedGlobs.map(x => `\n  - ${JSON.stringify(x)}`).join(''));
  }

  // Compute additional ignore glob patterns to be added to `navigationUrls`.
  const additionalNavigationUrls = firebaseRedirects
    // Grab the redirect source glob.
    .map(({source}) => source)
    // Ignore redirects for files (since these are already ignored by the SW).
    .filter(glob => /\/[^/.]*$/.test(glob))
    // Convert each Firebase-specific glob to a SW-compatible glob.
    .map(glob => `!${glob.replace(/:\w+/g, '*').replace(/@(\([\w\-.|]+\))/g, '$1')}`)
    // Add optional trailing `/` for globs that don't end with `*`.
    .map(glob => /\w$/.test(glob) ? `${glob}\/{0,1}` : glob)
    // Remove more specific globs that are covered by more generic ones.
    .filter((glob, _i, globs) => !isGlobRedundant(glob, globs))
    // Sort the generated globs alphabetically.
    .sort();

  // Add the additional `navigationUrls` globs and save the config.
  ngswConfig.navigationUrls.push(...additionalNavigationUrls);

  mkdirSync(dirname(NGSW_CONFIG_OUTPUT_PATH), {recursive: true});
  writeJson(NGSW_CONFIG_OUTPUT_PATH, ngswConfig);
}

function isGlobRedundant(glob, globs) {
  // Find all globs that could cover other globs.
  // For simplicity, we only consider globs ending with `/**`.
  const genericGlobs = globs.filter(g => g.endsWith('/**'));

  // A glob is redundant if it starts with the path of a potentially generic glob (excluding the
  // trailing `**`) followed by a word character or a `*`.
  // For example, `/foo/bar/baz` is covered (and thus made redundant) by `/foo/**`, but `/foo/{0,1}`
  // is not.
  return genericGlobs.some(g => {
    const pathPrefix = g.slice(0, -2);
    return (glob !== g) && glob.startsWith(pathPrefix) &&
      /^[\w*]/.test(glob.slice(pathPrefix.length));
  });
}

function readJson(filePath) {
  return parseJson(readFileSync(filePath, 'utf8'));
}

function writeJson(filePath, obj) {
  return writeFileSync(filePath, `${JSON.stringify(obj, null, 2)}\n`);
}
back to top