From c43c7a1be90eef00bcba2263d243d48d97ad54a3 Mon Sep 17 00:00:00 2001 From: mrmeku Date: Tue, 26 Nov 2019 13:47:20 -0700 Subject: [PATCH] feat(server): Use angular-cli's built in parser (#913) --- .../src/app/ng-task/ng-task-commands.ts | 2 +- apps/vscode/src/app/ng-task/select-flags.ts | 2 +- apps/vscode/src/app/select-schematic.ts | 6 +- .../verify-builder-definition.ts | 15 +- .../get-task-execution-schema.ts | 9 +- libs/schema/src/index.ts | 16 +- .../src/lib/read-schematic-collections.ts | 190 ------------------ libs/server/src/lib/utils/read-projects.ts | 40 +--- .../lib/utils/read-schematic-collections.ts | 107 +++++----- libs/server/src/lib/utils/utils.spec.ts | 20 +- libs/server/src/lib/utils/utils.ts | 145 ++++++------- .../autocomplete/autocomplete.component.ts | 2 +- .../src/lib/field/field.component.html | 40 ++-- .../src/lib/input/input.component.html | 2 +- .../src/lib/select/select.component.html | 1 + .../src/lib/task-execution-form.component.ts | 14 +- 16 files changed, 185 insertions(+), 426 deletions(-) delete mode 100644 libs/server/src/lib/read-schematic-collections.ts diff --git a/apps/vscode/src/app/ng-task/ng-task-commands.ts b/apps/vscode/src/app/ng-task/ng-task-commands.ts index 39395ae357..4ac32af547 100644 --- a/apps/vscode/src/app/ng-task/ng-task-commands.ts +++ b/apps/vscode/src/app/ng-task/ng-task-commands.ts @@ -82,7 +82,7 @@ async function selectNgCliCommandAndPromptForFlags(command: string) { return; // Do not execute a command if user clicks out of VSCode UI. } - const { validBuilder, schema } = verifyBuilderDefinition( + const { validBuilder, schema } = await verifyBuilderDefinition( selection.projectName, command, json diff --git a/apps/vscode/src/app/ng-task/select-flags.ts b/apps/vscode/src/app/ng-task/select-flags.ts index d72384e38d..354dd54775 100644 --- a/apps/vscode/src/app/ng-task/select-flags.ts +++ b/apps/vscode/src/app/ng-task/select-flags.ts @@ -81,7 +81,7 @@ function promptForFlagValue(flagToSet: NgTaskFlagQuickPickItem) { placeHolder }); } else if (flagToSet.schema.enum && flagToSet.schema.enum.length) { - return window.showQuickPick([...flagToSet.schema.enum], { + return window.showQuickPick([...flagToSet.schema.enum.map(String)], { placeHolder }); } else { diff --git a/apps/vscode/src/app/select-schematic.ts b/apps/vscode/src/app/select-schematic.ts index b5220b83a3..288ad461a1 100644 --- a/apps/vscode/src/app/select-schematic.ts +++ b/apps/vscode/src/app/select-schematic.ts @@ -3,17 +3,17 @@ import { readAllSchematicCollections } from '@angular-console/server'; import { QuickPickItem, window } from 'vscode'; import { join } from 'path'; -export function selectSchematic(workspacePath: string) { +export async function selectSchematic(workspacePath: string) { interface GenerateQuickPickItem extends QuickPickItem { collectionName: string; schematic: Schematic; } - const schematics = readAllSchematicCollections( + const schematics = (await readAllSchematicCollections( workspacePath, join('tools', 'schematics'), // TODO: Make these values auto detectable / configurable 'workspace-schematic' // TODO: Make these values auto detectable / configurable - ) + )) .map((c): GenerateQuickPickItem[] => c.schematics.map( (s): GenerateQuickPickItem => ({ diff --git a/apps/vscode/src/app/verify-workspace/verify-builder-definition.ts b/apps/vscode/src/app/verify-workspace/verify-builder-definition.ts index dd87387971..858b536e6f 100644 --- a/apps/vscode/src/app/verify-workspace/verify-builder-definition.ts +++ b/apps/vscode/src/app/verify-workspace/verify-builder-definition.ts @@ -1,15 +1,19 @@ import { Schema } from '@angular-console/schema'; -import { readSchema } from '@angular-console/server'; +import { readBuilderSchema } from '@angular-console/server'; import { window } from 'vscode'; import { angularJsonTreeProvider } from '../angular-json-tree/angular-json-tree-provider'; import { getTelemetry } from '../telemetry'; import { ngTaskProvider } from '../ng-task/ng-task-provider'; -export function verifyBuilderDefinition( +export async function verifyBuilderDefinition( project: string, command: string, angularJson: any -): { validBuilder: boolean; builderName: string; schema: Array } { +): Promise<{ + validBuilder: boolean; + builderName: string; + schema: Array; +}> { const projects = angularJson.projects || {}; const projectDef = projects[project] || {}; const architectDef = projectDef.architect || {}; @@ -40,7 +44,10 @@ export function verifyBuilderDefinition( }; } - const schema = readSchema(ngTaskProvider.getWorkspacePath(), builderName); + const schema = await readBuilderSchema( + ngTaskProvider.getWorkspacePath(), + builderName + ); if (!schema) { window diff --git a/apps/vscode/src/app/workspace-tree/get-task-execution-schema.ts b/apps/vscode/src/app/workspace-tree/get-task-execution-schema.ts index f88155abd8..805c378e2f 100644 --- a/apps/vscode/src/app/workspace-tree/get-task-execution-schema.ts +++ b/apps/vscode/src/app/workspace-tree/get-task-execution-schema.ts @@ -1,4 +1,4 @@ -import { readArchitectDef, readSchema } from '@angular-console/server'; +import { readArchitectDef, readBuilderSchema } from '@angular-console/server'; import { TaskExecutionSchema } from '@angular-console/vscode-ui/feature-task-execution-form'; import { window } from 'vscode'; @@ -40,7 +40,7 @@ export async function getTaskExecutionSchema( if (!selectedProject) return; - const { validBuilder, schema } = verifyBuilderDefinition( + const { validBuilder, schema } = await verifyBuilderDefinition( selectedProject.projectName, command, json @@ -84,12 +84,12 @@ export async function getTaskExecutionSchema( ) ); - return window.showQuickPick(runnableItems).then(selection => { + return window.showQuickPick(runnableItems).then(async selection => { if (!selection) { return; } - const schemaDef = readSchema( + const schemaDef = await readBuilderSchema( workspacePath, selection.architectDef.builder ); @@ -121,7 +121,6 @@ export async function getTaskExecutionSchema( } if (s.name === 'project') { - s.type = 'enum'; s.enum = getProjectEntries() .map(entry => entry[0]) .sort(); diff --git a/libs/schema/src/index.ts b/libs/schema/src/index.ts index 00ec707e72..3196160ba4 100644 --- a/libs/schema/src/index.ts +++ b/libs/schema/src/index.ts @@ -1,15 +1,7 @@ -export interface Schema { - name: string; - type: string; - description: string; - defaultValue?: string; - important?: boolean; - completion?: string; - deprecated?: string; - required: boolean; - positional: boolean; - enum?: string[]; -} +import { Option } from '@angular/cli/models/interface'; + +// tslint:disable-next-line: no-empty-interface +export interface Schema extends Option {} export interface SchematicCollectionForNgNew { name: string; diff --git a/libs/server/src/lib/read-schematic-collections.ts b/libs/server/src/lib/read-schematic-collections.ts deleted file mode 100644 index 4d572546e8..0000000000 --- a/libs/server/src/lib/read-schematic-collections.ts +++ /dev/null @@ -1,190 +0,0 @@ -import { Schematic, SchematicCollection } from '@angular-console/schema'; -import * as path from 'path'; - -import { - directoryExists, - fileExistsSync, - listFiles, - listOfUnnestedNpmPackages, - normalizeSchema, - readAndCacheJsonFile -} from './utils/utils'; - -export function readAllSchematicCollections( - basedir: string, - workspaceSchematicsPath: string, - workspaceSchematicsNpmScript: string -): SchematicCollection[] { - const npmClient = fileExistsSync(path.join(basedir, 'yarn.lock')) - ? 'yarn' - : 'npm'; - - let collections = readSchematicCollectionsFromNodeModules(basedir); - if (directoryExists(path.join(basedir, workspaceSchematicsPath))) { - collections = [ - readWorkspaceSchematicsCollection( - basedir, - workspaceSchematicsPath, - npmClient, - workspaceSchematicsNpmScript - ), - ...collections - ]; - } - return collections.filter( - (collection): collection is SchematicCollection => - !!collection && collection!.schematics!.length > 0 - ); -} - -function readAngularJsonDefaults(basedir: string): any { - const defaults = readAndCacheJsonFile('angular.json', basedir).json - .schematics; - const collectionDefaults = Object.keys(defaults ? defaults : {}).reduce( - (collectionDefaultsMap: any, key) => { - const [collectionName, schematicName] = key.split(':'); - if (!collectionDefaultsMap[collectionName]) { - collectionDefaultsMap[collectionName] = {}; - } - collectionDefaultsMap[collectionName][schematicName] = defaults[key]; - return collectionDefaultsMap; - }, - {} - ); - return collectionDefaults; -} - -function readSchematicCollectionsFromNodeModules( - basedir: string -): SchematicCollection[] { - const nodeModulesDir = path.join(basedir, 'node_modules'); - const packages = listOfUnnestedNpmPackages(nodeModulesDir); - const schematicCollections = packages.filter(p => { - try { - return !!readAndCacheJsonFile( - path.join(p, 'package.json'), - nodeModulesDir - ).json.schematics; - } catch (e) { - if ( - e.message && - (e.message.indexOf('no such file') > -1 || - e.message.indexOf('not a directory') > -1) - ) { - return false; - } else { - throw e; - } - } - }); - const defaults = readAngularJsonDefaults(basedir); - - return schematicCollections - .map(c => readCollection(nodeModulesDir, c, defaults)) - .filter((c): c is SchematicCollection => Boolean(c)); -} - -function readWorkspaceSchematicsCollection( - basedir: string, - workspaceSchematicsPath: string, - npmClient: string, - workspaceSchematicsNpmScript: string -) { - const collectionDir = path.join(basedir, workspaceSchematicsPath); - const collectionName = '@nrwl/workspace'; - if (fileExistsSync(path.join(collectionDir, 'collection.json'))) { - const collection = readAndCacheJsonFile('collection.json', collectionDir); - const defaults = readAngularJsonDefaults(basedir); - - return readCollectionSchematics( - collectionName, - collection.path, - collection.json, - defaults - ); - } else { - const schematics = listFiles(collectionDir) - .filter(f => path.basename(f) === 'schema.json') - .map(f => { - const schemaJson = readAndCacheJsonFile(f, ''); - return { - name: schemaJson.json.id, - collection: collectionName, - schema: normalizeSchema(schemaJson.json), - description: '', - npmClient, - npmScript: workspaceSchematicsNpmScript - }; - }); - return { name: collectionName, schematics }; - } -} - -function readCollection( - basedir: string, - collectionName: string, - defaults?: any -): SchematicCollection | null { - try { - const packageJson = readAndCacheJsonFile( - path.join(collectionName, 'package.json'), - basedir - ); - const collection = readAndCacheJsonFile( - packageJson.json.schematics, - path.dirname(packageJson.path) - ); - return readCollectionSchematics( - collectionName, - collection.path, - collection.json, - defaults - ); - } catch (e) { - // this happens when package is misconfigured. We decided to ignore such a case. - return null; - } -} - -function readCollectionSchematics( - collectionName: string, - collectionPath: string, - collectionJson: any, - defaults?: any -) { - const schematicCollection = { - name: collectionName, - schematics: [] as Schematic[] - }; - Object.entries(collectionJson.schematics).forEach(([k, v]: [any, any]) => { - try { - if (canAdd(k, v)) { - const schematicSchema = readAndCacheJsonFile( - v.schema, - path.dirname(collectionPath) - ); - const projectDefaults = - defaults && defaults[collectionName] && defaults[collectionName][k]; - - schematicCollection.schematics.push({ - name: k, - collection: collectionName, - schema: normalizeSchema(schematicSchema.json, projectDefaults), - description: v.description || '' - }); - } - } catch (e) { - console.error( - `Invalid package.json for schematic ${collectionName}:${k}` - ); - } - }); - return schematicCollection; -} - -export function canAdd( - name: string, - s: { hidden: boolean; private: boolean; schema: string; extends: boolean } -): boolean { - return !s.hidden && !s.private && !s.extends && name !== 'ng-add'; -} diff --git a/libs/server/src/lib/utils/read-projects.ts b/libs/server/src/lib/utils/read-projects.ts index 9a258a651f..1ba8b1227a 100644 --- a/libs/server/src/lib/utils/read-projects.ts +++ b/libs/server/src/lib/utils/read-projects.ts @@ -73,26 +73,11 @@ function serializeDefaultsForConfig(config: any) { ); } -export function readBuilder( +export async function readBuilderSchema( basedir: string, builder: string -): { schema: Array } | undefined { +): Promise { const [npmPackage, builderName] = builder.split(':'); - return readBuildersFile(basedir, npmPackage)[builderName]; -} - -export function readSchema( - basedir: string, - builder: string -): Schema[] | undefined { - const builderDef = readBuilder(basedir, builder); - return builderDef ? builderDef.schema : undefined; -} - -function readBuildersFile( - basedir: string, - npmPackage: string -): { [key: string]: any } { const packageJson = readAndCacheJsonFile( path.join(npmPackage, 'package.json'), path.join(basedir, 'node_modules') @@ -104,20 +89,11 @@ function readBuildersFile( path.dirname(packageJson.path) ); - const builders = {} as any; - Object.entries(buildersJson.json.builders).forEach(([k, v]: [any, any]) => { - try { - const builderSchema = readAndCacheJsonFile( - v.schema, - path.dirname(buildersJson.path) - ); - builders[k] = { - name: k, - schema: normalizeSchema(builderSchema.json), - description: v.description || '' - }; - } catch (e) {} - }); + const builderDef = buildersJson.json.builders[builderName]; + const builderSchema = readAndCacheJsonFile( + builderDef.schema, + path.dirname(buildersJson.path) + ); - return builders; + return await normalizeSchema(builderSchema.json); } diff --git a/libs/server/src/lib/utils/read-schematic-collections.ts b/libs/server/src/lib/utils/read-schematic-collections.ts index facc397ed5..a52e1a6d60 100644 --- a/libs/server/src/lib/utils/read-schematic-collections.ts +++ b/libs/server/src/lib/utils/read-schematic-collections.ts @@ -10,19 +10,19 @@ import { readAndParseJson } from './utils'; -export function readAllSchematicCollections( +export async function readAllSchematicCollections( basedir: string, workspaceSchematicsPath: string, workspaceSchematicsNpmScript: string -): SchematicCollection[] { +): Promise { const npmClient = fileExistsSync(path.join(basedir, 'yarn.lock')) ? 'yarn' : 'npm'; - let collections = readSchematicCollectionsFromNodeModules(basedir); + let collections = await readSchematicCollectionsFromNodeModules(basedir); if (directoryExists(path.join(basedir, workspaceSchematicsPath))) { collections = [ - readWorkspaceSchematicsCollection( + await readWorkspaceSchematicsCollection( basedir, workspaceSchematicsPath, npmClient, @@ -65,9 +65,9 @@ function readAngularJsonDefaults(basedir: string): any { return collectionDefaults; } -function readSchematicCollectionsFromNodeModules( +async function readSchematicCollectionsFromNodeModules( basedir: string -): SchematicCollection[] { +): Promise { const nodeModulesDir = path.join(basedir, 'node_modules'); const packages = listOfUnnestedNpmPackages(nodeModulesDir); const schematicCollections = packages.filter(p => { @@ -90,50 +90,55 @@ function readSchematicCollectionsFromNodeModules( }); const defaults = readAngularJsonDefaults(basedir); - return schematicCollections - .map(c => readCollection(nodeModulesDir, c, defaults)) - .filter((c): c is SchematicCollection => Boolean(c)); + return (await Promise.all( + schematicCollections.map(c => readCollection(nodeModulesDir, c, defaults)) + )).filter((c): c is SchematicCollection => Boolean(c)); } -function readWorkspaceSchematicsCollection( +async function readWorkspaceSchematicsCollection( basedir: string, workspaceSchematicsPath: string, npmClient: string, workspaceSchematicsNpmScript: string -) { +): Promise<{ + name: string; + schematics: Schematic[]; +}> { const collectionDir = path.join(basedir, workspaceSchematicsPath); const collectionName = '@nrwl/workspace'; if (fileExistsSync(path.join(collectionDir, 'collection.json'))) { const collection = readAndCacheJsonFile('collection.json', collectionDir); - return readCollectionSchematics( + return await readCollectionSchematics( collectionName, collection.path, collection.json ); } else { - const schematics = listFiles(collectionDir) - .filter(f => path.basename(f) === 'schema.json') - .map(f => { - const schemaJson = readAndCacheJsonFile(f, ''); - return { - name: schemaJson.json.id, - collection: collectionName, - schema: normalizeSchema(schemaJson.json), - description: '', - npmClient, - npmScript: workspaceSchematicsNpmScript - }; - }); + const schematics = await Promise.all( + listFiles(collectionDir) + .filter(f => path.basename(f) === 'schema.json') + .map(async f => { + const schemaJson = readAndCacheJsonFile(f, ''); + return { + name: schemaJson.json.id, + collection: collectionName, + schema: await normalizeSchema(schemaJson.json), + description: '', + npmClient, + npmScript: workspaceSchematicsNpmScript + }; + }) + ); return { name: collectionName, schematics }; } } -function readCollection( +async function readCollection( basedir: string, collectionName: string, defaults?: any -): SchematicCollection | null { +): Promise { try { const packageJson = readAndCacheJsonFile( path.join(collectionName, 'package.json'), @@ -155,7 +160,7 @@ function readCollection( } } -function readCollectionSchematics( +async function readCollectionSchematics( collectionName: string, collectionPath: string, collectionJson: any, @@ -165,29 +170,35 @@ function readCollectionSchematics( name: collectionName, schematics: [] as Schematic[] }; - Object.entries(collectionJson.schematics).forEach(([k, v]: [any, any]) => { - try { - if (canAdd(k, v)) { - const schematicSchema = readAndCacheJsonFile( - v.schema, - path.dirname(collectionPath) - ); - const projectDefaults = - defaults && defaults[collectionName] && defaults[collectionName][k]; + Object.entries(collectionJson.schematics).forEach( + async ([k, v]: [any, any]) => { + try { + if (canAdd(k, v)) { + const schematicSchema = readAndCacheJsonFile( + v.schema, + path.dirname(collectionPath) + ); + const projectDefaults = + defaults && defaults[collectionName] && defaults[collectionName][k]; - schematicCollection.schematics.push({ - name: k, - collection: collectionName, - schema: normalizeSchema(schematicSchema.json, projectDefaults), - description: v.description || '' - }); + schematicCollection.schematics.push({ + name: k, + collection: collectionName, + schema: await normalizeSchema( + schematicSchema.json, + projectDefaults + ), + description: v.description || '' + }); + } + } catch (e) { + console.error(e); + console.error( + `Invalid package.json for schematic ${collectionName}:${k}` + ); } - } catch (e) { - console.error( - `Invalid package.json for schematic ${collectionName}:${k}` - ); } - }); + ); return schematicCollection; } diff --git a/libs/server/src/lib/utils/utils.spec.ts b/libs/server/src/lib/utils/utils.spec.ts index fb8f041b9e..f855677c3f 100644 --- a/libs/server/src/lib/utils/utils.spec.ts +++ b/libs/server/src/lib/utils/utils.spec.ts @@ -2,22 +2,14 @@ import { normalizeSchema, seconds } from './utils'; describe('utils', () => { describe('normalizeSchema', () => { - it('should mark fields as required if they are listed in the required array', () => { - const r = normalizeSchema({ + it('should mark fields as required if they are listed in the required array', async () => { + const r = await normalizeSchema({ properties: { one: {} }, required: ['one'] }); expect(r[0].required).toBeTruthy(); }); - it('should mark fields as required if they have source', () => { - const r = normalizeSchema({ - properties: { one: { $default: { $source: 'argv' } } }, - required: [] - }); - expect(r[0].required).toBeTruthy(); - }); - it('measures seconds', () => { const returns = 'result'; const [elapsed, result] = seconds(() => returns); @@ -26,16 +18,16 @@ describe('utils', () => { expect(result).toEqual(returns); }); - it('should not mark fields as required otherwise', () => { - const r = normalizeSchema({ + it('should not mark fields as required otherwise', async () => { + const r = await normalizeSchema({ properties: { one: {} }, required: [] }); expect(r[0].required).toBeFalsy(); }); - it('should sort positional arguments by ascending order', () => { - const r = normalizeSchema({ + 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 } }, diff --git a/libs/server/src/lib/utils/utils.ts b/libs/server/src/lib/utils/utils.ts index 8b6c916868..e306d1ed29 100644 --- a/libs/server/src/lib/utils/utils.ts +++ b/libs/server/src/lib/utils/utils.ts @@ -3,7 +3,10 @@ import { existsSync, readdirSync, readFileSync, statSync } from 'fs'; import { platform } from 'os'; import * as path from 'path'; import * as JSON5 from 'json5'; - +import { schema } from '@angular-devkit/core'; +import { standardFormats } from '@angular-devkit/schematics/src/formats'; +import { Option } from '@angular/cli/models/interface'; +import { parseJsonSchemaToOptions } from '@angular/cli/utilities/json-schema'; export interface SchematicDefaults { [name: string]: string; } @@ -11,6 +14,17 @@ export interface SchematicDefaults { export const files: { [path: string]: string[] } = {}; export let fileContents: { [path: string]: any } = {}; +const IMPORTANT_FIELD_NAMES = [ + 'name', + 'project', + 'module', + 'watch', + 'style', + 'directory', + 'port' +]; +const IMPORTANT_FIELDS_SET = new Set(IMPORTANT_FIELD_NAMES); + export function exists(cmd: string): boolean { try { if (platform() === 'win32') { @@ -168,69 +182,59 @@ export function readAndCacheJsonFile( } } -export function normalizeSchema( - p: { +const registry = new schema.CoreSchemaRegistry(standardFormats); +export async function normalizeSchema( + s: { properties: { [k: string]: any }; required: string[]; }, projectDefaults?: SchematicDefaults -): any[] { - try { - const res = [] as any[]; - Object.entries(p.properties).forEach(([k, v]: [string, any]) => { - if (v.visible === undefined || v.visible) { - const d = getDefault(v); - const r = (p.required && p.required.indexOf(k) > -1) || hasSource(v); +): Promise { + const options = await parseJsonSchemaToOptions(registry, s); + const requiredFields = new Set(s.required || []); - const workspaceDefault = projectDefaults && projectDefaults[k]; + options.forEach(option => { + const workspaceDefault = projectDefaults && projectDefaults[option.name]; - if (v.enum) { - v.type = 'enum'; - } + if (workspaceDefault !== undefined) { + option.default = workspaceDefault; + } - res.push({ - name: k, - type: String(v.type || 'string'), - description: v.description || '', - defaultValue: workspaceDefault === undefined ? d : workspaceDefault, - required: Boolean(r), - deprecated: v['x-deprecated'], - positional: Boolean(isPositional(v)), - index: getIndex(v), - enum: v.enum - }); - } - }); + if (requiredFields.has(option.name)) { + option.required = true; + } + }); - return res.sort((a, b) => { - if (a.positional && b.positional) { - return a.index - b.index; - } else if (a.positional) { - return -1; - } else if (b.positional) { - return 1; - } else if (a.required) { - if (b.required) { - return a.name.localeCompare(b.name); - } - return -1; - } else if (b.required) { - return 1; - } else if (a.important) { - if (b.important) { - return a.name.localeCompare(b.name); - } - return -1; - } else if (b.important) { - return 1; - } else { + return options.sort((a, b) => { + if (typeof a.positional === 'number' && typeof b.positional === 'number') { + return a.positional - b.positional; + } + + if (typeof a.positional === 'number') { + return -1; + } else if (typeof b.positional === 'number') { + return 1; + } else if (a.required) { + if (b.required) { return a.name.localeCompare(b.name); } - }); - } catch (e) { - console.error(`normalizeSchema error: '${e.message}'`); - throw e; - } + return -1; + } else if (b.required) { + return 1; + } else if (IMPORTANT_FIELDS_SET.has(a.name)) { + if (IMPORTANT_FIELDS_SET.has(b.name)) { + return ( + IMPORTANT_FIELD_NAMES.indexOf(a.name) - + IMPORTANT_FIELD_NAMES.indexOf(b.name) + ); + } + return -1; + } else if (IMPORTANT_FIELDS_SET.has(b.name)) { + return 1; + } else { + return a.name.localeCompare(b.name); + } + }); } export function getPrimitiveValue(value: any) { @@ -246,39 +250,6 @@ export function getPrimitiveValue(value: any) { } } -function getDefault(prop: any): any { - if (prop.default === undefined && prop.$default === undefined) { - return undefined; - } - const d = prop.default !== undefined ? prop.default : prop.$default; - return !d.$source ? d.toString() : undefined; -} - -function isPositional(prop: any): any { - if (prop.default === undefined && prop.$default === undefined) { - return false; - } - const d = prop.default !== undefined ? prop.default : prop.$default; - return d.$source === 'argv'; -} - -function getIndex(prop: any): number | undefined { - if (prop.default === undefined && prop.$default === undefined) { - return undefined; - } else { - const d = prop.default !== undefined ? prop.default : prop.$default; - return d.$source === 'argv' ? d.index : undefined; - } -} - -function hasSource(prop: any): any { - if (prop.default === undefined && prop.$default === undefined) { - return false; - } - const d = prop.default !== undefined ? prop.default : prop.$default; - return !!d.$source; -} - export function filterByName(t: T[], args: { name?: string | null }): T[] { return args.name ? t.filter((s: any) => s.name === args.name) : t; } diff --git a/libs/vscode-ui/components/src/lib/autocomplete/autocomplete.component.ts b/libs/vscode-ui/components/src/lib/autocomplete/autocomplete.component.ts index cfeb74accf..0cadd1df8f 100644 --- a/libs/vscode-ui/components/src/lib/autocomplete/autocomplete.component.ts +++ b/libs/vscode-ui/components/src/lib/autocomplete/autocomplete.component.ts @@ -150,7 +150,7 @@ export class AutocompleteComponent ngOnChanges(changes: SimpleChanges) { if (changes.field && this.field.enum) { - this._options$.next(this.field.enum); + this._options$.next(this.field.enum.map(String)); } } diff --git a/libs/vscode-ui/components/src/lib/field/field.component.html b/libs/vscode-ui/components/src/lib/field/field.component.html index 9c64da56b3..ffb2a372e3 100644 --- a/libs/vscode-ui/components/src/lib/field/field.component.html +++ b/libs/vscode-ui/components/src/lib/field/field.component.html @@ -4,30 +4,32 @@ (deprecated) - - + + + + > + - - + + + [(value)]="value" + > - + > - - - + diff --git a/libs/vscode-ui/components/src/lib/input/input.component.html b/libs/vscode-ui/components/src/lib/input/input.component.html index 0b88fed40e..2e8faaae3d 100644 --- a/libs/vscode-ui/components/src/lib/input/input.component.html +++ b/libs/vscode-ui/components/src/lib/input/input.component.html @@ -6,7 +6,7 @@ (keyup)="updateValue($event.target.value)" [value]="value" class="text-input" - type="text" + [type]="field.type === 'number' ? 'number' : 'text'" role="textbox" [required]="field.required" /> diff --git a/libs/vscode-ui/components/src/lib/select/select.component.html b/libs/vscode-ui/components/src/lib/select/select.component.html index 840a66245f..8a487961a4 100644 --- a/libs/vscode-ui/components/src/lib/select/select.component.html +++ b/libs/vscode-ui/components/src/lib/select/select.component.html @@ -11,6 +11,7 @@ [required]="field.required" [disabled]="disabled" > +