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