feat(@angular-devkit/core): add useXDeprecatedProvider to SchemaRegistry

Use the new provider to record usage of options which have the `x-deprecated` keyword.
This commit is contained in:
Alan Agius 2020-08-13 18:45:58 +02:00
parent f3d54ee670
commit 797bcf9944
5 changed files with 52 additions and 3 deletions

View File

@ -226,6 +226,7 @@ export declare class CoreSchemaRegistry implements SchemaRegistry {
flatten(schema: JsonObject): Observable<JsonObject>;
registerUriHandler(handler: UriHandler): void;
usePromptProvider(provider: PromptProvider): void;
useXDeprecatedProvider(onUsage: (message: string) => void): void;
}
export declare function createWorkspaceHost(host: virtualFs.Host): WorkspaceHost;
@ -904,6 +905,7 @@ export interface SchemaRegistry {
compile(schema: Object): Observable<SchemaValidator>;
flatten(schema: JsonObject | string): Observable<JsonObject>;
usePromptProvider(provider: PromptProvider): void;
useXDeprecatedProvider(onUsage: (message: string) => void): void;
}
export declare class SchemaValidationException extends BaseException {

View File

@ -117,6 +117,7 @@ export interface SchemaRegistry {
addFormat(format: SchemaFormat): void;
addSmartDefaultProvider<T>(source: string, provider: SmartDefaultProvider<T>): void;
usePromptProvider(provider: PromptProvider): void;
useXDeprecatedProvider(onUsage: (message: string) => void): void;
/**
* Add a transformation step before the validation of any Json.

View File

@ -461,9 +461,7 @@ export class CoreSchemaRegistry implements SchemaRegistry {
this._ajv.addFormat(format.name, {
async: format.formatter.async,
validate,
// AJV typings list `compare` as required, but it is optional.
// tslint:disable-next-line:no-any
} as any);
});
}
addSmartDefaultProvider<T>(source: string, provider: SmartDefaultProvider<T>) {
@ -755,4 +753,17 @@ export class CoreSchemaRegistry implements SchemaRegistry {
}),
);
}
useXDeprecatedProvider(onUsage: (message: string) => void): void {
this._ajv.addKeyword('x-deprecated', {
validate: (schema, _data, _parentSchema, _dataPath, _parentDataObject, propertyName) => {
if (schema) {
onUsage(`Option "${propertyName}" is deprecated${typeof schema == 'string' ? ': ' + schema : '.'}`);
}
return true;
},
errors: false,
});
}
}

View File

@ -481,4 +481,35 @@ describe('CoreSchemaRegistry', () => {
.toPromise().then(done, done.fail);
});
it('adds deprecated options usage', done => {
const registry = new CoreSchemaRegistry();
const deprecatedMessages: string[] = [];
registry.useXDeprecatedProvider(m => deprecatedMessages.push(m));
const data = {
foo: true,
bar: true,
bat: true,
};
registry
.compile({
properties: {
foo: { type: 'boolean', 'x-deprecated': 'Use bar instead.' },
bar: { type: 'boolean', 'x-deprecated': true },
buz: { type: 'boolean', 'x-deprecated': true },
bat: { type: 'boolean', 'x-deprecated': false },
},
})
.pipe(
mergeMap(validator => validator(data)),
map(result => {
expect(deprecatedMessages.length).toBe(2);
expect(deprecatedMessages[0]).toBe('Option "foo" is deprecated: Use bar instead.');
expect(deprecatedMessages[1]).toBe('Option "bar" is deprecated.');
expect(result.success).toBe(true, result.errors);
}),
)
.toPromise().then(done, done.fail);
});
});

View File

@ -259,6 +259,10 @@ export async function main({
parsedArgs[key] = argv2[key];
}
// Show usage of deprecated options
workflow.registry.useXDeprecatedProvider(msg => logger.warn(msg));
// Pass the rest of the arguments as the smart default "argv". Then delete it.
workflow.registry.addSmartDefaultProvider('argv', (schema: JsonObject) => {
if ('index' in schema) {