diff --git a/libs/server/src/lib/utils/get-generators.ts b/libs/server/src/lib/utils/get-generators.ts index 453c806e81..4aebf80aa9 100644 --- a/libs/server/src/lib/utils/get-generators.ts +++ b/libs/server/src/lib/utils/get-generators.ts @@ -94,7 +94,7 @@ async function readWorkspaceGeneratorsCollection( data: { name, collection: collectionName, - options: await normalizeSchema(schemaJson.json), + options: await normalizeSchema(schemaJson.json, 'nx'), description: schemaJson.json.description ?? '', type, }, diff --git a/libs/server/src/lib/utils/ng-version.ts b/libs/server/src/lib/utils/ng-version.ts new file mode 100644 index 0000000000..08c739542c --- /dev/null +++ b/libs/server/src/lib/utils/ng-version.ts @@ -0,0 +1,37 @@ +import { workspaceDependencyPath } from '@nx-console/npm'; +import { WorkspaceConfigurationStore } from '@nx-console/vscode/configuration'; + +declare function __non_webpack_require__(importPath: string): any; + +let ngPackageJson: { version: string }; +let loadedNgPackage = false; +export async function ngVersion(): Promise { + if (!loadedNgPackage) { + const workspacePath = WorkspaceConfigurationStore.instance.get( + 'nxWorkspacePath', + '' + ); + + const packagePath = await workspaceDependencyPath( + workspacePath, + '@angular/cli' + ); + + if (!packagePath) { + return 0; + } + + ngPackageJson = __non_webpack_require__(packagePath + '/package.json'); + loadedNgPackage = true; + } + + if (!ngPackageJson) { + return 0; + } + const ngPackageVersion = ngPackageJson.version; + const majorVersion = ngPackageVersion.split('.')[0]; + if (!majorVersion) { + return 0; + } + return +majorVersion; +} diff --git a/libs/server/src/lib/utils/read-projects.ts b/libs/server/src/lib/utils/read-projects.ts index ae617f7476..c53e7f7efe 100644 --- a/libs/server/src/lib/utils/read-projects.ts +++ b/libs/server/src/lib/utils/read-projects.ts @@ -58,6 +58,7 @@ function readDefaultValues(configurations: any, name: string): DefaultValue[] { export async function readBuilderSchema( basedir: string, builder: string, + workspaceType: 'ng' | 'nx', projectDefaults?: { [name: string]: string } ): Promise { try { @@ -87,7 +88,11 @@ export async function readBuilderSchema( path.dirname(buildersJson.path) ); - return await normalizeSchema(builderSchema.json, projectDefaults); + return await normalizeSchema( + builderSchema.json, + workspaceType, + projectDefaults + ); } catch (e) { // todo: make this a utility function to be used in more places. const stringifiedError = e.toString ? e.toString() : JSON.stringify(e); diff --git a/libs/server/src/lib/utils/utils.spec.ts b/libs/server/src/lib/utils/utils.spec.ts index 33176b9683..079d67f663 100644 --- a/libs/server/src/lib/utils/utils.spec.ts +++ b/libs/server/src/lib/utils/utils.spec.ts @@ -17,10 +17,13 @@ describe('utils', () => { options: Schema['properties'], required: string[] = [] ): Promise => { - const r = await normalizeSchema({ - properties: { ...options }, - required, - }); + const r = await normalizeSchema( + { + properties: { ...options }, + required, + }, + 'nx' + ); return r; }; @@ -41,28 +44,34 @@ describe('utils', () => { }); it('should sort positional arguments by ascending order', async () => { - const r = await normalizeSchema({ - properties: { - a: { $default: { $source: 'argv', index: 0 } }, - b: { $default: { $source: 'argv', index: 2 } }, - c: { $default: { $source: 'argv', index: 1 } }, + const r = await normalizeSchema( + { + properties: { + a: { $default: { $source: 'argv', index: 0 } }, + b: { $default: { $source: 'argv', index: 2 } }, + c: { $default: { $source: 'argv', index: 1 } }, + }, + required: [], }, - required: [], - }); + 'nx' + ); expect(r.map((x) => x.name)).toEqual(['a', 'c', 'b']); }); it('should sort required arguments', async () => { - const r = await normalizeSchema({ - properties: { - a: { $default: { $source: 'argv', index: 1 } }, - b: {}, - c: {}, - d: { $default: { $source: 'argv', index: 0 } }, - e: {}, + const r = await normalizeSchema( + { + properties: { + a: { $default: { $source: 'argv', index: 1 } }, + b: {}, + c: {}, + d: { $default: { $source: 'argv', index: 0 } }, + e: {}, + }, + required: ['c', 'e'], }, - required: ['c', 'e'], - }); + 'nx' + ); expect(r.map((x) => x.name)).toMatchInlineSnapshot(` Array [ "d", diff --git a/libs/server/src/lib/utils/utils.ts b/libs/server/src/lib/utils/utils.ts index 39f507b14f..a0a32df409 100644 --- a/libs/server/src/lib/utils/utils.ts +++ b/libs/server/src/lib/utils/utils.ts @@ -4,6 +4,7 @@ import type { WorkspaceJsonConfiguration, NxJsonConfiguration, } from '@nrwl/devkit'; +import { names } from '@nrwl/devkit'; import { ItemsWithEnum, @@ -27,6 +28,7 @@ import { getOutputChannel } from './output-channel'; import { toNewFormat } from 'nx/src/config/workspaces'; import { PosixFS, ZipOpenFS } from '@yarnpkg/fslib'; import { getLibzipSync as libzip } from '@yarnpkg/libzip'; +import { ngVersion } from './ng-version'; const zipOpenFs = new ZipOpenFS({ libzip }); export const crossFs = new PosixFS(zipOpenFs); @@ -175,9 +177,11 @@ export async function readAndCacheJsonFile( export async function normalizeSchema( s: Schema, + workspaceType: 'ng' | 'nx', projectDefaults?: GeneratorDefaults ): Promise { - const options = schemaToOptions(s); + const hyphenate = workspaceType === 'ng' && (await ngVersion()) >= 14; + const options = schemaToOptions(s, { hyphenate }); const requiredFields = new Set(s.required || []); const nxOptions = options.map((option) => { @@ -322,7 +326,10 @@ export function toWorkspaceFormat( return newFormat; } -function schemaToOptions(schema: Schema): CliOption[] { +function schemaToOptions( + schema: Schema, + config?: { hyphenate: boolean } +): CliOption[] { return Object.keys(schema.properties || {}).reduce( (cliOptions, option) => { const currentProperty = schema.properties[option]; @@ -336,9 +343,9 @@ function schemaToOptions(schema: Schema): CliOption[] { if (!visible) { return cliOptions; } - + const name = config?.hyphenate ? names(option).fileName : option; cliOptions.push({ - name: option, + name, positional, ...currentProperty, }); diff --git a/libs/vscode/tasks/src/lib/cli-task-commands.ts b/libs/vscode/tasks/src/lib/cli-task-commands.ts index cebdd0bb77..e6a9346080 100644 --- a/libs/vscode/tasks/src/lib/cli-task-commands.ts +++ b/libs/vscode/tasks/src/lib/cli-task-commands.ts @@ -283,7 +283,8 @@ async function selectCliCommandAndPromptForFlags( const builderDefinition = await verifyBuilderDefinition( projectName, target, - json + json, + workspaceType ); const { validBuilder, diff --git a/libs/vscode/tasks/src/lib/select-generator.ts b/libs/vscode/tasks/src/lib/select-generator.ts index f907b68344..02a5cfa0a8 100644 --- a/libs/vscode/tasks/src/lib/select-generator.ts +++ b/libs/vscode/tasks/src/lib/select-generator.ts @@ -61,7 +61,8 @@ export async function getGeneratorOptions( workspacePath: string, collectionName: string, generatorName: string, - generatorPath: string + generatorPath: string, + workspaceType: 'ng' | 'nx' ): Promise { const generatorSchema = await readAndCacheJsonFile(generatorPath); const workspaceDefaults = await readWorkspaceJsonDefaults(workspacePath); @@ -69,7 +70,7 @@ export async function getGeneratorOptions( workspaceDefaults && workspaceDefaults[collectionName] && workspaceDefaults[collectionName][generatorName]; - return await normalizeSchema(generatorSchema.json, defaults); + return await normalizeSchema(generatorSchema.json, workspaceType, defaults); } export async function selectGenerator( @@ -120,7 +121,8 @@ export async function selectGenerator( workspacePath, selection.collectionName, selection.generator.name, - selection.collectionPath + selection.collectionPath, + workspaceType )); const positional = `${selection.collectionName}:${selection.generator.name}`; return { diff --git a/libs/vscode/verify/src/lib/verify-builder-definition.ts b/libs/vscode/verify/src/lib/verify-builder-definition.ts index 9945718330..6d3a0058f5 100644 --- a/libs/vscode/verify/src/lib/verify-builder-definition.ts +++ b/libs/vscode/verify/src/lib/verify-builder-definition.ts @@ -58,7 +58,8 @@ const RUN_ONE_OPTIONS = [ export async function verifyBuilderDefinition( project: string, command: string, - workspaceJson: WorkspaceJsonConfiguration + workspaceJson: WorkspaceJsonConfiguration, + workspaceType: 'ng' | 'nx' ): Promise<{ validBuilder: boolean; builderName: string; @@ -89,6 +90,7 @@ export async function verifyBuilderDefinition( const options = await readBuilderSchema( workspacePath(), executorName, + workspaceType, commandDef.options ); diff --git a/libs/vscode/webview/src/lib/get-task-execution-schema.ts b/libs/vscode/webview/src/lib/get-task-execution-schema.ts index 8ee3344634..c5c2d3a337 100644 --- a/libs/vscode/webview/src/lib/get-task-execution-schema.ts +++ b/libs/vscode/webview/src/lib/get-task-execution-schema.ts @@ -67,7 +67,8 @@ export async function getTaskExecutionSchema( const { validBuilder, options } = await verifyBuilderDefinition( selection.projectName, selection.command, - json + json, + workspaceType ); if (!validBuilder) { return; @@ -136,7 +137,8 @@ export async function getTaskExecutionSchema( const { validBuilder, options } = await verifyBuilderDefinition( selectedProject.projectName, command, - json + json, + workspaceType ); if (!validBuilder) { return;