packages/build-tools/utils/manifest.js
async function getTwigNamespaceConfig(relativeFrom, extraNamespaces = {}) {
  const config = await getConfig();
  const namespaces = {};
  const allDirs = [];
  const manifest = await getBoltManifest();
  const global = manifest.components.global;
  const individual = manifest.components.individual;

  [global, individual].forEach(componentList => {
    componentList.forEach(component => {
      if (!component.twigNamespace) {
        return;
      }

      const dir = relativeFrom
        ? path.relative(relativeFrom, component.dir)
        : component.dir;

      namespaces[component.basicName] = {
        recursive: true,
        paths: [dir],
      };

      allDirs.push(dir);
    });
  });

  const namespaceConfigFile = Object.assign(
    {
      // Can hit anything with `@bolt`
      bolt: {
        recursive: true,
        paths: [...allDirs],
      },
      'bolt-data': {
        recursive: true,
        paths: [config.dataDir],
      },
    },
    namespaces,
  );

  // `extraNamespaces` serves two purposes:
  // 1. To add extra namespaces that have not been declared
  // 2. To add extra paths to previously declared namespaces
  //    Assuming we've already declared the `foo` namespaces to look in `~/my-dir1`
  //    Then someone uses `extraNamespaces` to declare that `foo` will look in `~/my-dir2`
  //    This will not overwrite it, but *prepend* to the paths, resulting in a namespace setting like this:
  //    'foo': {
  //      paths: ['~/my-dir2', '~/my-dir1']
  //    }
  //    This causes the folder declared in `extraNamespaces` to be looked in first for templates, before our default;
  //    allowing end user developers to selectively overwrite some templates.
  if (extraNamespaces) {
    Object.keys(extraNamespaces).forEach(namespace => {
      const settings = extraNamespaces[namespace];
      if (
        namespaceConfigFile[namespace] &&
        settings.paths !== undefined // make sure the paths config is defined before trying to merge
      ) {
        // merging the two, making sure the paths from `extraNamespaces` go first
        namespaceConfigFile[namespace].paths = [
          ...settings.paths,
          ...namespaceConfigFile[namespace].paths,
        ];

        // don't add a new namespace key if the paths config option wasn't defined. prevents PHP errors if a namespace key was defined but no paths specified.
      } else if (settings.paths !== undefined) {
        namespaceConfigFile[namespace] = settings;
      }
    });
  }

  return namespaceConfigFile;
}
async function getTwigNamespaceConfig(relativeFrom, extraNamespaces = {}) {
  const config = await getConfig();
  const namespaces = {};
  const allDirs = [];
  const manifest = await getBoltManifest();
  const global = manifest.components.global;
  const individual = manifest.components.individual;

  [global, individual].forEach(componentList => {
    componentList.forEach(component => {
      if (!component.twigNamespace) {
        return;
      }

      const dir = relativeFrom
        ? path.relative(relativeFrom, component.dir)
        : component.dir;

      namespaces[component.basicName] = {
        recursive: true,
        paths: [dir],
      };

      allDirs.push(dir);
    });
  });

  const namespaceConfigFile = Object.assign(
    {
      // Can hit anything with `@bolt`
      bolt: {
        recursive: true,
        paths: [...allDirs],
      },
      'bolt-data': {
        recursive: true,
        paths: [config.dataDir],
      },
    },
    namespaces,
  );

  // `extraNamespaces` serves two purposes:
  // 1. To add extra namespaces that have not been declared
  // 2. To add extra paths to previously declared namespaces
  //    Assuming we've already declared the `foo` namespaces to look in `~/my-dir1`
  //    Then someone uses `extraNamespaces` to declare that `foo` will look in `~/my-dir2`
  //    This will not overwrite it, but *prepend* to the paths, resulting in a namespace setting like this:
  //    'foo': {
  //      paths: ['~/my-dir2', '~/my-dir1']
  //    }
  //    This causes the folder declared in `extraNamespaces` to be looked in first for templates, before our default;
  //    allowing end user developers to selectively overwrite some templates.
  if (extraNamespaces) {
    Object.keys(extraNamespaces).forEach(namespace => {
      const settings = extraNamespaces[namespace];
      if (
        namespaceConfigFile[namespace] &&
        settings.paths !== undefined // make sure the paths config is defined before trying to merge
      ) {
        // merging the two, making sure the paths from `extraNamespaces` go first
        namespaceConfigFile[namespace].paths = [
          ...settings.paths,
          ...namespaceConfigFile[namespace].paths,
        ];

        // don't add a new namespace key if the paths config option wasn't defined. prevents PHP errors if a namespace key was defined but no paths specified.
      } else if (settings.paths !== undefined) {
        namespaceConfigFile[namespace] = settings;
      }
    });
  }

  return namespaceConfigFile;
}
async function getTwigNamespaceConfig ( relativeFrom , extraNamespaces = { } ) { const config = await getConfig ( ) ; const namespaces = { } ; const allDirs = [ ] ; const manifest = await getBoltManifest ( ) ; const global = manifest . components . global ; const individual = manifest . components . individual ; [ global , individual ] . forEach ( componentList => { componentList . forEach ( component => { if ( ! component . twigNamespace ) { return ; } const dir = relativeFrom ? path . relative ( relativeFrom , component . dir ) : component . dir ; namespaces [ component . basicName ] = { recursive : true , paths : [ dir ] , } ; allDirs . push ( dir ) ; } ) ; } ) ; const namespaceConfigFile = Object . assign ( { // Can hit anything with `@bolt` bolt : { recursive : true , paths : [ ... allDirs ] , } , 'bolt-data' : { recursive : true , paths : [ config . dataDir ] , } , } , namespaces , ) ; // `extraNamespaces` serves two purposes: // 1. To add extra namespaces that have not been declared // 2. To add extra paths to previously declared namespaces //    Assuming we've already declared the `foo` namespaces to look in `~/my-dir1` //    Then someone uses `extraNamespaces` to declare that `foo` will look in `~/my-dir2` //    This will not overwrite it, but *prepend* to the paths, resulting in a namespace setting like this: //    'foo': { //      paths: ['~/my-dir2', '~/my-dir1'] //    } //    This causes the folder declared in `extraNamespaces` to be looked in first for templates, before our default; //    allowing end user developers to selectively overwrite some templates. if ( extraNamespaces ) { Object . keys ( extraNamespaces ) . forEach ( namespace => { const settings = extraNamespaces [ namespace ] ; if ( namespaceConfigFile [ namespace ] && settings . paths !== undefined // make sure the paths config is defined before trying to merge ) { // merging the two, making sure the paths from `extraNamespaces` go first namespaceConfigFile [ namespace ] . paths = [ ... settings . paths , ... namespaceConfigFile [ namespace ] . paths , ] ; // don't add a new namespace key if the paths config option wasn't defined. prevents PHP errors if a namespace key was defined but no paths specified. } else if ( settings . paths !== undefined ) { namespaceConfigFile [ namespace ] = settings ; } } ) ; } return namespaceConfigFile ; }
Builds config for Twig Namespaces
@param relativeFrom {string} - If present, the path will be relative from this, else it will be absolute.
@param extraNamespaces {object} - Extra namespaces to add to file in [this format](https://packagist.org/packages/evanlovely/plugin-twig-namespaces)
@async
@see writeTwigNamespaceFile
@returns {Promise<object>}
Builds config for Twig Namespaces