File

libs/nx/src/generators/library/updaters/add-project-config/add-project-config.ts

Index

Properties

Properties

configFile
Type string
plugin
Type string
targetName
Type string
import {
  addProjectConfiguration,
  ExpandedPluginConfiguration,
  joinPathFragments,
  PluginConfiguration,
  readNxJson,
  Tree,
  updateNxJson
} from '@nx/devkit';
import { findMatchingConfigFiles } from '@nx/devkit/internal';
import { ExpandedLibraryGeneratorSchema } from '../../generator';

interface InferencePlugin {
  plugin: string;
  targetName: string;
  configFile: string;
}

const inferencePlugins: InferencePlugin[] = [
  { plugin: '@nx/eslint/plugin', targetName: 'lint', configFile: 'eslint.config.mjs' },
  { plugin: '@nx/jest/plugin', targetName: 'test', configFile: 'jest.config.ts' }
];

const getProjectConfiguration = (options: ExpandedLibraryGeneratorSchema) => {
  return {
    name: options.projectName,
    projectType: 'library' as const,
    root: options.projectRoot,
    sourceRoot: joinPathFragments(options.projectRoot, 'src'),
    schematics: {
      '@nx/angular:component': {
        style: 'scss'
      }
    },
    prefix: options.prefix,
    targets: {
      build: {
        executor: '@nx/angular:package',
        configurations: {
          production: {}
        },
        options: {
          project: `${options.projectRoot}/ng-package.json`,
          tsConfig: `${options.projectRoot}/tsconfig.lib.json`
        },
        dependsOn: ['^build'],
        inputs: ['production', '^production']
      },
      'test-accessibility': {
        command: 'jest --config jest.a11y.config.ts --passWithNoTests',
        options: { cwd: options.projectRoot },
        configurations: {
          ci: { ci: true, coverage: true }
        },
        cache: true,
        inputs: ['default', '^production', '{workspaceRoot}/jest.preset.js']
      }
    }
  };
};

function usesTargetName(registration: PluginConfiguration, targetName: string) {
  if (typeof registration === 'string') {
    return true;
  }
  const options = registration.options as { targetName?: string } | undefined;
  return (options?.targetName ?? targetName) === targetName;
}

function matchesConfigFile(registration: PluginConfiguration, configFile: string) {
  if (typeof registration === 'string') {
    return true;
  }
  return (
    findMatchingConfigFiles([configFile], registration.include ?? [], registration.exclude ?? [])
      .length > 0
  );
}

function canIncludeConfigFile(
  registration: PluginConfiguration,
  configFile: string,
  projectPattern: string
): registration is ExpandedPluginConfiguration & { include: string[] } {
  if (typeof registration === 'string' || !registration.include) {
    return false;
  }
  return (
    findMatchingConfigFiles([configFile], [projectPattern], registration.exclude ?? []).length > 0
  );
}

function ensureInferencePlugin(
  tree: Tree,
  { plugin, targetName, configFile }: InferencePlugin,
  projectRoot: string
) {
  const nxJson = readNxJson(tree) ?? {};
  nxJson.plugins ??= [];
  const projectPattern = `${projectRoot}/*`;
  const projectConfigFile = joinPathFragments(projectRoot, configFile);

  const pluginRegistrations = nxJson.plugins.filter(
    (entry) => (typeof entry === 'string' ? entry : entry.plugin) === plugin
  );
  const registrationsWithTargetName = pluginRegistrations.filter((entry) =>
    usesTargetName(entry, targetName)
  );

  if (registrationsWithTargetName.some((entry) => matchesConfigFile(entry, projectConfigFile))) {
    return;
  }

  const scopedRegistration = registrationsWithTargetName.find((entry) =>
    canIncludeConfigFile(entry, projectConfigFile, projectPattern)
  );

  if (scopedRegistration) {
    scopedRegistration.include.push(projectPattern);
    updateNxJson(tree, nxJson);
    return;
  }

  nxJson.plugins.push(
    pluginRegistrations.length > 0
      ? { plugin, include: [projectPattern], options: { targetName } }
      : { plugin, options: { targetName } }
  );
  updateNxJson(tree, nxJson);
}

export async function addProjectConfig(tree: Tree, options: ExpandedLibraryGeneratorSchema) {
  const projectConfiguration = getProjectConfiguration(options);
  addProjectConfiguration(tree, options.projectName, projectConfiguration);

  for (const inferencePlugin of inferencePlugins) {
    ensureInferencePlugin(tree, inferencePlugin, options.projectRoot);
  }
}

results matching ""

    No results matching ""