import {
Tree,
installPackagesTask,
joinPathFragments,
logger,
readJson,
workspaceLayout
} from '@nx/devkit';
import { LibraryGeneratorSchema } from './schema';
import { addBbDependenciesToLibrary } from './updaters/add-library-dependencies/add-library-dependencies';
import { addProjectConfig } from './updaters/add-project-config/add-project-config';
import { addTemplates } from './updaters/add-templates/add-templates';
import { addWorkspaceDependencies } from './updaters/add-workspace-dependencies/add-workspace-dependencies';
import { updateBaseTsconfigJson } from './updaters/update-base-tsconfig-json/update-base-tsconfig-json';
import { updateGitignore } from './updaters/update-gitignore/update-gitignore';
import { updatePackageJson } from './updaters/update-package-json/update-package-json';
export interface ProjectDetails {
projectName: string;
projectRoot: string;
}
export interface ExpandedLibraryGeneratorSchema extends Omit<LibraryGeneratorSchema, 'name'> {
projectName: string;
projectRoot: string;
}
function getExpandedOptions(options: LibraryGeneratorSchema): ExpandedLibraryGeneratorSchema {
// extract a name from the given library name that we can use as a
// folder name, e.g. "@allianz/my-library" -> "my-library"
const projectDirectoryName = options.name.includes('/')
? options.name.substring(options.name.indexOf('/') + 1)
: options.name;
const projectRoot = joinPathFragments(workspaceLayout().libsDir, projectDirectoryName);
return {
projectName: options.name,
projectRoot,
category: options.category,
prefix: options.prefix
};
}
function verifyWorkspaceSetup(tree: Tree) {
const packageJsonPath = '/package.json';
if (!tree.exists(packageJsonPath)) {
throw new Error(
`Cannot read package.json. Please take a look at the TALY documentation to learn more about the workspace setup: https://taly.frameworks.allianz.io/additional-documentation/getting-started.html`
);
}
const packageJson = readJson(tree, packageJsonPath);
const dependencies = [
...Object.keys(packageJson.dependencies || []),
...Object.keys(packageJson.devDependencies || [])
];
// The following dependencies are required for the library generation and
// will be automatically added when the Nx angular-monorepo preset is used.
// If a dependency is missing, this is an indicator that the Nx workspace
// is set up incorrectly.
const includesRequiredDependencies =
dependencies.includes('@angular-devkit/core') &&
dependencies.includes('@angular-devkit/schematics') &&
dependencies.includes('@nx/angular');
const baseTsconfigJsonExists = tree.exists('tsconfig.base.json');
if (!includesRequiredDependencies || !baseTsconfigJsonExists) {
throw new Error(
'The workspace does not fulfill the necessary prerequisites. Please take a look at the TALY documentation to learn more about the workspace setup: https://taly.frameworks.allianz.io/additional-documentation/getting-started.html'
);
}
}
export default async function library(tree: Tree, options: LibraryGeneratorSchema) {
const expandedOptions = getExpandedOptions(options);
const projectDetails = {
projectName: expandedOptions.projectName,
projectRoot: expandedOptions.projectRoot
};
verifyWorkspaceSetup(tree);
addTemplates(tree, expandedOptions);
addBbDependenciesToLibrary(tree, expandedOptions);
await addProjectConfig(tree, expandedOptions);
updatePackageJson(tree, projectDetails);
updateBaseTsconfigJson(tree, projectDetails);
updateGitignore(tree);
addWorkspaceDependencies(tree);
return () => {
// Nx sets npm_config_legacy_peer_deps = true by default inside the `installPackagesTask` (https://github.com/nrwl/nx/blob/5ded713c3c487bd28874e75b1623ece07a79d91d/packages/nx/src/utils/package-manager.ts#L130)
// We have to explicitly set it to prevent the default behavior
process.env['npm_config_legacy_peer_deps'] ??= 'false';
installPackagesTask(tree, true);
logger.warn(
'This command updated your workspace dependencies. Please review them to ensure they are compatible with your project.'
);
};
}