UNPKG

@nestjs/cli

Version:

Nest - modern, fast, powerful node.js web framework (@cli)

100 lines (99 loc) 5.5 kB
import { red } from 'ansis'; import * as path from 'path'; import { getValueOrDefault } from '../lib/compiler/helpers/get-value-or-default.js'; import { Collection, CollectionFactory, SchematicOption, } from '../lib/schematics/index.js'; import { MESSAGES } from '../lib/ui/index.js'; import { loadConfiguration } from '../lib/utils/load-configuration.js'; import { askForProjectName, getSpecFileSuffix, moveDefaultProjectToStart, shouldAskForProject, shouldGenerateFlat, shouldGenerateSpec, } from '../lib/utils/project-utils.js'; import { AbstractAction } from './abstract.action.js'; export class GenerateAction extends AbstractAction { async handle(context) { await generateFiles(context); } } const generateFiles = async (context) => { const configuration = await loadConfiguration(); const collectionOption = context.collection; const schematic = context.schematic; const appName = context.project ?? ''; const specFileSuffix = context.specFileSuffix; const collection = CollectionFactory.create(collectionOption || configuration.collection || Collection.NESTJS); const schematicOptions = mapContextToSchematicOptions(context); schematicOptions.push(new SchematicOption('language', configuration.language)); const configurationProjects = configuration.projects; let sourceRoot = appName ? getValueOrDefault(configuration, 'sourceRoot', appName) : configuration.sourceRoot; const specValue = typeof context.spec === 'boolean' ? context.spec : context.spec.value; const specPassedAsInput = typeof context.spec === 'boolean' ? false : context.spec.passedAsInput; const flatValue = context.flat !== undefined ? !!context.flat : false; const specFileSuffixValue = specFileSuffix; let generateSpec = shouldGenerateSpec(configuration, schematic, appName, specValue, specPassedAsInput); let generateFlat = shouldGenerateFlat(configuration, appName, flatValue); let generateSpecFileSuffix = getSpecFileSuffix(configuration, appName, specFileSuffixValue); // If you only add a `lib` we actually don't have monorepo: true BUT we do have "projects" // Ensure we don't run for new app/libs schematics if (shouldAskForProject(schematic, configurationProjects, appName)) { const defaultLabel = ' [ Default ]'; let defaultProjectName = configuration.sourceRoot + defaultLabel; for (const property in configurationProjects) { if (configurationProjects[property].sourceRoot === configuration.sourceRoot) { defaultProjectName = property + defaultLabel; break; } } const projects = moveDefaultProjectToStart(configuration, defaultProjectName, defaultLabel); const selectedProjectName = (await askForProjectName(MESSAGES.PROJECT_SELECTION_QUESTION, projects)); const project = selectedProjectName.replace(defaultLabel, ''); if (project !== configuration.sourceRoot) { sourceRoot = configurationProjects[project].sourceRoot; } if (selectedProjectName !== defaultProjectName) { // Only overwrite if the appName is not the default- as it has already been loaded above generateSpec = shouldGenerateSpec(configuration, schematic, selectedProjectName, specValue, specPassedAsInput); generateFlat = shouldGenerateFlat(configuration, selectedProjectName, flatValue); generateSpecFileSuffix = getSpecFileSuffix(configuration, selectedProjectName, specFileSuffixValue); } } if (configuration.generateOptions?.baseDir) { sourceRoot = path.join(sourceRoot, configuration.generateOptions.baseDir); } schematicOptions.push(new SchematicOption('sourceRoot', sourceRoot)); schematicOptions.push(new SchematicOption('spec', generateSpec)); schematicOptions.push(new SchematicOption('flat', generateFlat)); schematicOptions.push(new SchematicOption('specFileSuffix', generateSpecFileSuffix)); schematicOptions.push(new SchematicOption('format', context.format)); try { if (!schematic) { throw new Error('Unable to find a schematic for this configuration'); } await collection.execute(schematic, schematicOptions); } catch (error) { if (error && error.message) { console.error(red(error.message)); } } }; const mapContextToSchematicOptions = (context) => { const options = []; // Only include fields that schematics expect; exclude those handled separately if (context.name !== undefined) options.push(new SchematicOption('name', context.name)); if (context.path !== undefined) options.push(new SchematicOption('path', context.path)); if (context.dryRun) options.push(new SchematicOption('dry-run', true)); if (context.collection !== undefined) options.push(new SchematicOption('collection', context.collection)); if (context.project !== undefined) options.push(new SchematicOption('project', context.project)); if (context.skipImport !== undefined) options.push(new SchematicOption('skipImport', context.skipImport)); if (context.type !== undefined) options.push(new SchematicOption('type', context.type)); if (context.crud !== undefined) options.push(new SchematicOption('crud', context.crud)); // 'schematic', 'spec', 'flat', 'specFileSuffix' are handled separately return options; };