From 1b0439b55ce28cb9d0fd5e02b15a56fba255f537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Tue, 22 Aug 2023 17:26:54 +0100 Subject: [PATCH] feat(misc): use helper to determine project name and root in npm-package generator (#18710) --- .../workspace/generators/npm-package.json | 16 +++++- packages/workspace/generators.json | 2 +- .../src/generators/npm-package/npm-package.ts | 57 +++++++++++++++---- .../src/generators/npm-package/schema.json | 12 +++- 4 files changed, 70 insertions(+), 17 deletions(-) diff --git a/docs/generated/packages/workspace/generators/npm-package.json b/docs/generated/packages/workspace/generators/npm-package.json index a53e97dd4d0af..d99864c55518f 100644 --- a/docs/generated/packages/workspace/generators/npm-package.json +++ b/docs/generated/packages/workspace/generators/npm-package.json @@ -1,6 +1,6 @@ { "name": "npm-package", - "factory": "./src/generators/npm-package/npm-package#npmPackageGenerator", + "factory": "./src/generators/npm-package/npm-package#npmPackageGeneratorInternal", "schema": { "$schema": "http://json-schema.org/schema", "$id": "NxWorkspaceNpmPackage", @@ -14,7 +14,17 @@ "description": "Package name.", "$default": { "$source": "argv", "index": 0 }, "x-prompt": "What name of your npm package?", - "pattern": "^[a-zA-Z].*$" + "pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$" + }, + "directory": { + "type": "string", + "description": "A directory where the package is placed.", + "alias": "dir" + }, + "projectNameAndRootFormat": { + "description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).", + "type": "string", + "enum": ["as-provided", "derived"] } }, "required": ["name"], @@ -22,7 +32,7 @@ }, "description": "Create a minimal NPM package.", "x-type": "library", - "implementation": "/packages/workspace/src/generators/npm-package/npm-package#npmPackageGenerator.ts", + "implementation": "/packages/workspace/src/generators/npm-package/npm-package#npmPackageGeneratorInternal.ts", "aliases": [], "hidden": false, "path": "/packages/workspace/src/generators/npm-package/schema.json", diff --git a/packages/workspace/generators.json b/packages/workspace/generators.json index 85b88d6d00a2e..f2448a5a519ef 100644 --- a/packages/workspace/generators.json +++ b/packages/workspace/generators.json @@ -88,7 +88,7 @@ "description": "Fixes projects configuration" }, "npm-package": { - "factory": "./src/generators/npm-package/npm-package#npmPackageGenerator", + "factory": "./src/generators/npm-package/npm-package#npmPackageGeneratorInternal", "schema": "./src/generators/npm-package/schema.json", "description": "Create a minimal NPM package.", "x-type": "library" diff --git a/packages/workspace/src/generators/npm-package/npm-package.ts b/packages/workspace/src/generators/npm-package/npm-package.ts index d3986785cf3ab..8c192f9ef1b79 100644 --- a/packages/workspace/src/generators/npm-package/npm-package.ts +++ b/packages/workspace/src/generators/npm-package/npm-package.ts @@ -3,21 +3,45 @@ import { convertNxGenerator, formatFiles, generateFiles, - getWorkspaceLayout, - names, Tree, writeJson, } from '@nx/devkit'; +import { + determineProjectNameAndRootOptions, + type ProjectNameAndRootFormat, +} from '@nx/devkit/src/generators/project-name-and-root-utils'; import { join } from 'path'; import { getImportPath } from '../../utilities/get-import-path'; export interface ProjectOptions { name: string; + directory?: string; + projectNameAndRootFormat?: ProjectNameAndRootFormat; +} +interface NormalizedProjectOptions extends ProjectOptions { + projectRoot: string; } -function normalizeOptions(options: ProjectOptions): ProjectOptions { - options.name = names(options.name).fileName; - return options; +async function normalizeOptions( + tree: Tree, + options: ProjectOptions +): Promise { + const { projectName, projectRoot } = await determineProjectNameAndRootOptions( + tree, + { + name: options.name, + projectType: 'library', + directory: options.directory, + projectNameAndRootFormat: options.projectNameAndRootFormat, + callingGenerator: '@nx/workspace:npm-package', + } + ); + + return { + ...options, + name: projectName, + projectRoot, + }; } function addFiles(projectRoot: string, tree: Tree, options: ProjectOptions) { @@ -34,21 +58,30 @@ function addFiles(projectRoot: string, tree: Tree, options: ProjectOptions) { } export async function npmPackageGenerator(tree: Tree, options: ProjectOptions) { - options = normalizeOptions(options); + return await npmPackageGeneratorInternal(tree, { + projectNameAndRootFormat: 'derived', + ...options, + }); +} - const { libsDir } = getWorkspaceLayout(tree); - const projectRoot = join(libsDir, options.name); +export async function npmPackageGeneratorInternal( + tree: Tree, + _options: ProjectOptions +) { + const options = await normalizeOptions(tree, _options); addProjectConfiguration(tree, options.name, { - root: projectRoot, + root: options.projectRoot, }); - const fileCount = tree.children(projectRoot).length; - const projectJsonExists = tree.exists(join(projectRoot, 'project.json')); + const fileCount = tree.children(options.projectRoot).length; + const projectJsonExists = tree.exists( + join(options.projectRoot, 'project.json') + ); const isEmpty = fileCount === 0 || (fileCount === 1 && projectJsonExists); if (isEmpty) { - addFiles(projectRoot, tree, options); + addFiles(options.projectRoot, tree, options); } await formatFiles(tree); diff --git a/packages/workspace/src/generators/npm-package/schema.json b/packages/workspace/src/generators/npm-package/schema.json index 8ff754734e6af..241cf815a3ae2 100644 --- a/packages/workspace/src/generators/npm-package/schema.json +++ b/packages/workspace/src/generators/npm-package/schema.json @@ -14,7 +14,17 @@ "index": 0 }, "x-prompt": "What name of your npm package?", - "pattern": "^[a-zA-Z].*$" + "pattern": "(?:^@[a-zA-Z0-9-*~][a-zA-Z0-9-*._~]*\\/[a-zA-Z0-9-~][a-zA-Z0-9-._~]*|^[a-zA-Z][^:]*)$" + }, + "directory": { + "type": "string", + "description": "A directory where the package is placed.", + "alias": "dir" + }, + "projectNameAndRootFormat": { + "description": "Whether to generate the project name and root directory as provided (`as-provided`) or generate them composing their values and taking the configured layout into account (`derived`).", + "type": "string", + "enum": ["as-provided", "derived"] } }, "required": ["name"]