feat(nest): use helper to determine project name and root in project generators (#18701)
This commit is contained in:
parent
a668e0b7d6
commit
e1b76e26f8
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "application",
|
||||
"factory": "./src/generators/application/application",
|
||||
"factory": "./src/generators/application/application#applicationGeneratorInternal",
|
||||
"schema": {
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"$id": "NxNestApplicationGenerator",
|
||||
@ -13,12 +13,18 @@
|
||||
"description": "The name of the application.",
|
||||
"type": "string",
|
||||
"$default": { "$source": "argv", "index": 0 },
|
||||
"x-prompt": "What name would you like to use for the node application?"
|
||||
"x-prompt": "What name would you like to use for the node application?",
|
||||
"pattern": "^[a-zA-Z][^:]*$"
|
||||
},
|
||||
"directory": {
|
||||
"description": "The directory of the new application.",
|
||||
"type": "string"
|
||||
},
|
||||
"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"]
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
@ -82,7 +88,7 @@
|
||||
"aliases": ["app"],
|
||||
"x-type": "application",
|
||||
"description": "Create a NestJS application.",
|
||||
"implementation": "/packages/nest/src/generators/application/application.ts",
|
||||
"implementation": "/packages/nest/src/generators/application/application#applicationGeneratorInternal.ts",
|
||||
"hidden": false,
|
||||
"path": "/packages/nest/src/generators/application/schema.json",
|
||||
"type": "generator"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "library",
|
||||
"factory": "./src/generators/library/library",
|
||||
"factory": "./src/generators/library/library#libraryGeneratorInternal",
|
||||
"schema": {
|
||||
"$schema": "http://json-schema.org/schema",
|
||||
"$id": "NxNestLibraryGenerator",
|
||||
@ -19,13 +19,19 @@
|
||||
"description": "Library name.",
|
||||
"type": "string",
|
||||
"$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": {
|
||||
"description": "A directory where the library is placed.",
|
||||
"type": "string",
|
||||
"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"]
|
||||
},
|
||||
"linter": {
|
||||
"description": "The tool to use for running lint checks.",
|
||||
"type": "string",
|
||||
@ -143,7 +149,7 @@
|
||||
"aliases": ["lib"],
|
||||
"x-type": "library",
|
||||
"description": "Create a new NestJS library.",
|
||||
"implementation": "/packages/nest/src/generators/library/library.ts",
|
||||
"implementation": "/packages/nest/src/generators/library/library#libraryGeneratorInternal.ts",
|
||||
"hidden": false,
|
||||
"path": "/packages/nest/src/generators/library/schema.json",
|
||||
"type": "generator"
|
||||
|
||||
@ -108,7 +108,7 @@
|
||||
},
|
||||
"generators": {
|
||||
"application": {
|
||||
"factory": "./src/generators/application/application",
|
||||
"factory": "./src/generators/application/application#applicationGeneratorInternal",
|
||||
"schema": "./src/generators/application/schema.json",
|
||||
"aliases": ["app"],
|
||||
"x-type": "application",
|
||||
@ -128,7 +128,7 @@
|
||||
"hidden": true
|
||||
},
|
||||
"library": {
|
||||
"factory": "./src/generators/library/library",
|
||||
"factory": "./src/generators/library/library#libraryGeneratorInternal",
|
||||
"schema": "./src/generators/library/schema.json",
|
||||
"aliases": ["lib"],
|
||||
"x-type": "library",
|
||||
|
||||
@ -15,7 +15,17 @@ export async function applicationGenerator(
|
||||
tree: Tree,
|
||||
rawOptions: ApplicationGeneratorOptions
|
||||
): Promise<GeneratorCallback> {
|
||||
const options = normalizeOptions(tree, rawOptions);
|
||||
return await applicationGeneratorInternal(tree, {
|
||||
projectNameAndRootFormat: 'derived',
|
||||
...rawOptions,
|
||||
});
|
||||
}
|
||||
|
||||
export async function applicationGeneratorInternal(
|
||||
tree: Tree,
|
||||
rawOptions: ApplicationGeneratorOptions
|
||||
): Promise<GeneratorCallback> {
|
||||
const options = await normalizeOptions(tree, rawOptions);
|
||||
const initTask = await initGenerator(tree, {
|
||||
skipPackageJson: options.skipPackageJson,
|
||||
unitTestRunner: options.unitTestRunner,
|
||||
|
||||
@ -9,7 +9,7 @@ export function createFiles(tree: Tree, options: NormalizedOptions): void {
|
||||
joinPathFragments(options.appProjectRoot, 'src'),
|
||||
{
|
||||
tmpl: '',
|
||||
name: options.name,
|
||||
name: options.appProjectName,
|
||||
root: options.appProjectRoot,
|
||||
}
|
||||
);
|
||||
|
||||
@ -1,31 +1,32 @@
|
||||
import { extractLayoutDirectory, Tree } from '@nx/devkit';
|
||||
import { getWorkspaceLayout, joinPathFragments, names } from '@nx/devkit';
|
||||
import { Tree } from '@nx/devkit';
|
||||
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||
import { Linter } from '@nx/linter';
|
||||
import type { Schema as NodeApplicationGeneratorOptions } from '@nx/node/src/generators/application/schema';
|
||||
import type { ApplicationGeneratorOptions, NormalizedOptions } from '../schema';
|
||||
|
||||
export function normalizeOptions(
|
||||
export async function normalizeOptions(
|
||||
tree: Tree,
|
||||
options: ApplicationGeneratorOptions
|
||||
): NormalizedOptions {
|
||||
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
|
||||
options.directory
|
||||
);
|
||||
|
||||
const appDirectory = projectDirectory
|
||||
? `${names(projectDirectory).fileName}/${names(options.name).fileName}`
|
||||
: names(options.name).fileName;
|
||||
|
||||
const appProjectRoot = options.rootProject
|
||||
? '.'
|
||||
: joinPathFragments(
|
||||
layoutDirectory ?? getWorkspaceLayout(tree).appsDir,
|
||||
appDirectory
|
||||
);
|
||||
): Promise<NormalizedOptions> {
|
||||
const {
|
||||
projectName: appProjectName,
|
||||
projectRoot: appProjectRoot,
|
||||
projectNameAndRootFormat,
|
||||
} = await determineProjectNameAndRootOptions(tree, {
|
||||
name: options.name,
|
||||
projectType: 'application',
|
||||
directory: options.directory,
|
||||
projectNameAndRootFormat: options.projectNameAndRootFormat,
|
||||
rootProject: options.rootProject,
|
||||
callingGenerator: '@nx/nest:application',
|
||||
});
|
||||
options.rootProject = appProjectRoot === '.';
|
||||
options.projectNameAndRootFormat = projectNameAndRootFormat;
|
||||
|
||||
return {
|
||||
...options,
|
||||
strict: options.strict ?? false,
|
||||
appProjectName,
|
||||
appProjectRoot,
|
||||
linter: options.linter ?? Linter.EsLint,
|
||||
unitTestRunner: options.unitTestRunner ?? 'jest',
|
||||
|
||||
@ -1,8 +1,10 @@
|
||||
import { Linter } from '@nx/linter';
|
||||
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||
import type { Linter } from '@nx/linter';
|
||||
|
||||
export interface ApplicationGeneratorOptions {
|
||||
name: string;
|
||||
directory?: string;
|
||||
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
||||
frontendProject?: string;
|
||||
linter?: Linter;
|
||||
skipFormat?: boolean;
|
||||
@ -17,5 +19,6 @@ export interface ApplicationGeneratorOptions {
|
||||
}
|
||||
|
||||
interface NormalizedOptions extends ApplicationGeneratorOptions {
|
||||
appProjectName: string;
|
||||
appProjectRoot: Path;
|
||||
}
|
||||
|
||||
@ -13,12 +13,18 @@
|
||||
"$source": "argv",
|
||||
"index": 0
|
||||
},
|
||||
"x-prompt": "What name would you like to use for the node application?"
|
||||
"x-prompt": "What name would you like to use for the node application?",
|
||||
"pattern": "^[a-zA-Z][^:]*$"
|
||||
},
|
||||
"directory": {
|
||||
"description": "The directory of the new application.",
|
||||
"type": "string"
|
||||
},
|
||||
"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"]
|
||||
},
|
||||
"skipFormat": {
|
||||
"description": "Skip formatting files.",
|
||||
"type": "boolean",
|
||||
|
||||
@ -15,10 +15,7 @@ export function addProject(tree: Tree, options: NormalizedOptions): void {
|
||||
executor: '@nx/js:tsc',
|
||||
outputs: ['{options.outputPath}'],
|
||||
options: {
|
||||
outputPath:
|
||||
options.libsDir && options.libsDir !== '.'
|
||||
? `dist/${options.libsDir}/${options.projectDirectory}`
|
||||
: `dist/${options.projectDirectory}`,
|
||||
outputPath: `dist/${options.projectRoot}`,
|
||||
tsConfig: `${options.projectRoot}/tsconfig.lib.json`,
|
||||
packageJson: `${options.projectRoot}/package.json`,
|
||||
main: `${options.projectRoot}/src/index.ts`,
|
||||
|
||||
@ -1,33 +1,31 @@
|
||||
import { Tree } from '@nx/devkit';
|
||||
import { determineProjectNameAndRootOptions } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||
import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope';
|
||||
import type { LibraryGeneratorSchema as JsLibraryGeneratorSchema } from '@nx/js/src/utils/schema';
|
||||
import { Linter } from '@nx/linter';
|
||||
import {
|
||||
extractLayoutDirectory,
|
||||
getWorkspaceLayout,
|
||||
joinPathFragments,
|
||||
names,
|
||||
Tree,
|
||||
} from '@nx/devkit';
|
||||
import type { LibraryGeneratorOptions, NormalizedOptions } from '../schema';
|
||||
import { getNpmScope } from '@nx/js/src/utils/package-json/get-npm-scope';
|
||||
|
||||
export function normalizeOptions(
|
||||
export async function normalizeOptions(
|
||||
tree: Tree,
|
||||
options: LibraryGeneratorOptions
|
||||
): NormalizedOptions {
|
||||
const { layoutDirectory, projectDirectory } = extractLayoutDirectory(
|
||||
options.directory
|
||||
);
|
||||
const { 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'), '-');
|
||||
const fileName = options.simpleName ? name : projectName;
|
||||
const projectRoot = joinPathFragments(libsDir, fullProjectDirectory);
|
||||
): Promise<NormalizedOptions> {
|
||||
const {
|
||||
projectName,
|
||||
names: projectNames,
|
||||
projectRoot,
|
||||
importPath,
|
||||
} = await determineProjectNameAndRootOptions(tree, {
|
||||
name: options.name,
|
||||
projectType: 'library',
|
||||
directory: options.directory,
|
||||
importPath: options.importPath,
|
||||
projectNameAndRootFormat: options.projectNameAndRootFormat,
|
||||
callingGenerator: '@nx/nest:library',
|
||||
});
|
||||
|
||||
const fileName = options.simpleName
|
||||
? projectNames.projectSimpleName
|
||||
: projectNames.projectFileName;
|
||||
const parsedTags = options.tags
|
||||
? options.tags.split(',').map((s) => s.trim())
|
||||
: [];
|
||||
@ -41,14 +39,13 @@ export function normalizeOptions(
|
||||
linter: options.linter ?? Linter.EsLint,
|
||||
parsedTags,
|
||||
prefix: getNpmScope(tree), // we could also allow customizing this
|
||||
projectDirectory: fullProjectDirectory,
|
||||
projectName,
|
||||
projectRoot,
|
||||
importPath,
|
||||
service: options.service ?? false,
|
||||
target: options.target ?? 'es6',
|
||||
testEnvironment: options.testEnvironment ?? 'node',
|
||||
unitTestRunner: options.unitTestRunner ?? 'jest',
|
||||
libsDir,
|
||||
};
|
||||
|
||||
return normalized;
|
||||
|
||||
@ -17,7 +17,17 @@ export async function libraryGenerator(
|
||||
tree: Tree,
|
||||
rawOptions: LibraryGeneratorOptions
|
||||
): Promise<GeneratorCallback> {
|
||||
const options = normalizeOptions(tree, rawOptions);
|
||||
return await libraryGeneratorInternal(tree, {
|
||||
projectNameAndRootFormat: 'derived',
|
||||
...rawOptions,
|
||||
});
|
||||
}
|
||||
|
||||
export async function libraryGeneratorInternal(
|
||||
tree: Tree,
|
||||
rawOptions: LibraryGeneratorOptions
|
||||
): Promise<GeneratorCallback> {
|
||||
const options = await normalizeOptions(tree, rawOptions);
|
||||
await jsLibraryGenerator(tree, toJsLibraryGeneratorOptions(options));
|
||||
const installDepsTask = addDependencies(tree);
|
||||
deleteFiles(tree, options);
|
||||
|
||||
@ -1,11 +1,13 @@
|
||||
import { Linter } from '@nx/linter';
|
||||
import { UnitTestRunner } from '../utils';
|
||||
import type { ProjectNameAndRootFormat } from '@nx/devkit/src/generators/project-name-and-root-utils';
|
||||
import type { Linter } from '@nx/linter';
|
||||
import type { UnitTestRunner } from '../utils';
|
||||
|
||||
export interface LibraryGeneratorOptions {
|
||||
name: string;
|
||||
buildable?: boolean;
|
||||
controller?: boolean;
|
||||
directory?: string;
|
||||
projectNameAndRootFormat?: ProjectNameAndRootFormat;
|
||||
global?: boolean;
|
||||
importPath?: string;
|
||||
linter?: Linter;
|
||||
@ -38,8 +40,6 @@ export interface NormalizedOptions extends LibraryGeneratorOptions {
|
||||
fileName: string;
|
||||
parsedTags: string[];
|
||||
prefix: string;
|
||||
projectDirectory: string;
|
||||
projectName: string;
|
||||
projectRoot: Path;
|
||||
libsDir: string;
|
||||
}
|
||||
|
||||
@ -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": {
|
||||
"description": "A directory where the library is placed.",
|
||||
"type": "string",
|
||||
"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"]
|
||||
},
|
||||
"linter": {
|
||||
"description": "The tool to use for running lint checks.",
|
||||
"type": "string",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user