From 6a7a29440f7a875c2f0df8e6ee98bc0b89874470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Mon, 14 Aug 2023 15:52:18 +0100 Subject: [PATCH] feat(node): use helper to determine project name and root directory in library generator --- .../packages/node/generators/library.json | 12 +++- packages/node/generators.json | 2 +- .../node/src/generators/library/library.ts | 69 +++++++++---------- .../node/src/generators/library/schema.d.ts | 4 +- .../node/src/generators/library/schema.json | 8 ++- 5 files changed, 53 insertions(+), 42 deletions(-) diff --git a/docs/generated/packages/node/generators/library.json b/docs/generated/packages/node/generators/library.json index 47c5f4a86eab81..15a267219010e8 100644 --- a/docs/generated/packages/node/generators/library.json +++ b/docs/generated/packages/node/generators/library.json @@ -1,6 +1,6 @@ { "name": "library", - "factory": "./src/generators/library/library", + "factory": "./src/generators/library/library#libraryGeneratorInternal", "schema": { "$schema": "http://json-schema.org/schema", "cli": "nx", @@ -19,13 +19,19 @@ "type": "string", "description": "Library name", "$default": { "$source": "argv", "index": 0 }, - "x-prompt": "What name would you like to use for the library?" + "x-prompt": "What name would you like to use for the library?", + "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 lib 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"] + }, "simpleModuleName": { "description": "Keep the module name simple (when using `--directory`).", "type": "boolean", @@ -131,7 +137,7 @@ "aliases": ["lib"], "x-type": "library", "description": "Create a node library.", - "implementation": "/packages/node/src/generators/library/library.ts", + "implementation": "/packages/node/src/generators/library/library#libraryGeneratorInternal.ts", "hidden": false, "path": "/packages/node/src/generators/library/schema.json", "type": "generator" diff --git a/packages/node/generators.json b/packages/node/generators.json index 59c0edb0f32cb1..2cb40420be18f1 100644 --- a/packages/node/generators.json +++ b/packages/node/generators.json @@ -18,7 +18,7 @@ "description": "Create a node application." }, "library": { - "factory": "./src/generators/library/library", + "factory": "./src/generators/library/library#libraryGeneratorInternal", "schema": "./src/generators/library/schema.json", "aliases": ["lib"], "x-type": "library", diff --git a/packages/node/src/generators/library/library.ts b/packages/node/src/generators/library/library.ts index f63a6e4f055d0c..574d2996b2e640 100644 --- a/packages/node/src/generators/library/library.ts +++ b/packages/node/src/generators/library/library.ts @@ -1,10 +1,8 @@ import { convertNxGenerator, - extractLayoutDirectory, formatFiles, generateFiles, GeneratorCallback, - getWorkspaceLayout, joinPathFragments, names, offsetFromRoot, @@ -15,26 +13,31 @@ import { updateProjectConfiguration, updateTsConfigsToJs, } from '@nx/devkit'; -import { Schema } from './schema'; +import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils'; import { libraryGenerator as jsLibraryGenerator } from '@nx/js'; - -import { join } from 'path'; -import { addSwcDependencies } from '@nx/js/src/utils/swc/add-swc-dependencies'; import { addSwcConfig } from '@nx/js/src/utils/swc/add-swc-config'; +import { addSwcDependencies } from '@nx/js/src/utils/swc/add-swc-dependencies'; +import { join } from 'path'; import { initGenerator } from '../init/init'; -import { getImportPath } from '@nx/js/src/utils/get-import-path'; +import { Schema } from './schema'; export interface NormalizedSchema extends Schema { name: string; fileName: string; projectRoot: string; - projectDirectory: string; parsedTags: string[]; compiler: 'swc' | 'tsc'; } export async function libraryGenerator(tree: Tree, schema: Schema) { - const options = normalizeOptions(tree, schema); + return await libraryGeneratorInternal(tree, { + projectNameAndRootFormat: 'derived', + ...schema, + }); +} + +export async function libraryGeneratorInternal(tree: Tree, schema: Schema) { + const options = await normalizeOptions(tree, schema); const tasks: GeneratorCallback[] = [ await initGenerator(tree, { ...options, @@ -75,37 +78,39 @@ export async function libraryGenerator(tree: Tree, schema: Schema) { export default libraryGenerator; export const librarySchematic = convertNxGenerator(libraryGenerator); -function normalizeOptions(tree: Tree, options: Schema): NormalizedSchema { - const { layoutDirectory, projectDirectory } = extractLayoutDirectory( - options.directory - ); - const { npmScope, libsDir: defaultLibsDir } = getWorkspaceLayout(tree); - const libsDir = layoutDirectory ?? defaultLibsDir; - const name = names(options.name).fileName; - const fullProjectDirectory = projectDirectory - ? `${names(projectDirectory).fileName}/${name}` - : name; - - const projectName = fullProjectDirectory.replace(new RegExp('/', 'g'), '-'); +async function normalizeOptions( + tree: Tree, + options: Schema +): Promise { + const { + projectName, + names: projectNames, + projectRoot, + importPath, + } = await determineProjectNameAndRootOptions(tree, { + name: options.name, + projectType: 'library', + directory: options.directory, + importPath: options.importPath, + projectNameAndRootFormat: options.projectNameAndRootFormat, + }); + const fileName = getCaseAwareFileName({ - fileName: options.simpleModuleName ? name : projectName, + fileName: options.simpleModuleName + ? projectNames.projectSimpleName + : projectNames.projectFileName, pascalCaseFiles: options.pascalCaseFiles, }); - const projectRoot = joinPathFragments(libsDir, fullProjectDirectory); const parsedTags = options.tags ? options.tags.split(',').map((s) => s.trim()) : []; - const importPath = - options.importPath || getImportPath(tree, fullProjectDirectory); - return { ...options, fileName, name: projectName, projectRoot, - projectDirectory: fullProjectDirectory, parsedTags, importPath, }; @@ -151,21 +156,13 @@ function updateProject(tree: Tree, options: NormalizedSchema) { } const project = readProjectConfiguration(tree, options.name); - const { libsDir } = getWorkspaceLayout(tree); - - const rootProject = options.projectRoot === '.' || options.projectRoot === ''; project.targets = project.targets || {}; project.targets.build = { executor: `@nx/js:${options.compiler}`, outputs: ['{options.outputPath}'], options: { - outputPath: joinPathFragments( - 'dist', - rootProject - ? options.projectDirectory - : `${libsDir}/${options.projectDirectory}` - ), + outputPath: joinPathFragments('dist', options.projectRoot), tsConfig: `${options.projectRoot}/tsconfig.lib.json`, packageJson: `${options.projectRoot}/package.json`, main: `${options.projectRoot}/src/index` + (options.js ? '.js' : '.ts'), diff --git a/packages/node/src/generators/library/schema.d.ts b/packages/node/src/generators/library/schema.d.ts index 837f21a69a9cd8..2d8454c7681f7b 100644 --- a/packages/node/src/generators/library/schema.d.ts +++ b/packages/node/src/generators/library/schema.d.ts @@ -1,8 +1,10 @@ -import { Linter } from '@nx/linter'; +import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-directory-utils'; +import type { Linter } from '@nx/linter'; export interface Schema { name: string; directory?: string; + projectNameAndRootFormat?: ProjectNameAndRootFormat; simpleModuleName?: boolean; skipTsConfig?: boolean; skipFormat?: boolean; diff --git a/packages/node/src/generators/library/schema.json b/packages/node/src/generators/library/schema.json index c66e679f4d005e..2bf7cb184627e6 100644 --- a/packages/node/src/generators/library/schema.json +++ b/packages/node/src/generators/library/schema.json @@ -19,13 +19,19 @@ "$source": "argv", "index": 0 }, - "x-prompt": "What name would you like to use for the library?" + "x-prompt": "What name would you like to use for the library?", + "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 lib 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"] + }, "simpleModuleName": { "description": "Keep the module name simple (when using `--directory`).", "type": "boolean",