feat(build): Added a version stamp in .metadata.json files.
Also modified StaticReflector to handle multiple versions in a single .metadata.json file. Fixes #8974 Closes #8981
This commit is contained in:
parent
cf2d3cf920
commit
2d8f776e38
|
@ -23,6 +23,8 @@ import {
|
||||||
} from "@angular/core";
|
} from "@angular/core";
|
||||||
import {ReflectorReader} from "./core_private";
|
import {ReflectorReader} from "./core_private";
|
||||||
|
|
||||||
|
const SUPPORTED_SCHEMA_VERSION = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The host of the static resolver is expected to be able to provide module metadata in the form of
|
* The host of the static resolver is expected to be able to provide module metadata in the form of
|
||||||
* ModuleMetadata. Angular 2 CLI will produce this metadata for a module whenever a .d.ts files is
|
* ModuleMetadata. Angular 2 CLI will produce this metadata for a module whenever a .d.ts files is
|
||||||
|
@ -379,8 +381,14 @@ export class StaticReflector implements ReflectorReader {
|
||||||
let moduleMetadata = this.metadataCache.get(module);
|
let moduleMetadata = this.metadataCache.get(module);
|
||||||
if (!moduleMetadata) {
|
if (!moduleMetadata) {
|
||||||
moduleMetadata = this.host.getMetadataFor(module);
|
moduleMetadata = this.host.getMetadataFor(module);
|
||||||
|
if (Array.isArray(moduleMetadata)) {
|
||||||
|
moduleMetadata = (<Array<any>>moduleMetadata).find(element => element.version === SUPPORTED_SCHEMA_VERSION) || moduleMetadata[0];
|
||||||
|
}
|
||||||
if (!moduleMetadata) {
|
if (!moduleMetadata) {
|
||||||
moduleMetadata = {__symbolic: "module", module: module, metadata: {}};
|
moduleMetadata = {__symbolic: "module", version: SUPPORTED_SCHEMA_VERSION, module: module, metadata: {}};
|
||||||
|
}
|
||||||
|
if (moduleMetadata['version'] != SUPPORTED_SCHEMA_VERSION) {
|
||||||
|
throw new Error(`Metadata version mismatch for module ${module}, found version ${moduleMetadata['version']}, expected ${SUPPORTED_SCHEMA_VERSION}`);
|
||||||
}
|
}
|
||||||
this.metadataCache.set(module, moduleMetadata);
|
this.metadataCache.set(module, moduleMetadata);
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,6 +64,11 @@ describe('StaticReflector', () => {
|
||||||
.toEqual([[host.findDeclaration('angular2/src/common/directives/ng_for', 'NgFor')]]);
|
.toEqual([[host.findDeclaration('angular2/src/common/directives/ng_for', 'NgFor')]]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should throw and exception for unsupported metadata versions', () => {
|
||||||
|
let e = host.findDeclaration('src/version-error', 'e');
|
||||||
|
expect(() => reflector.annotations(e)).toThrow(new Error('Metadata version mismatch for module /tmp/src/version-error.d.ts, found version 100, expected 1'));
|
||||||
|
});
|
||||||
|
|
||||||
it('should get and empty annotation list for an unknown class', () => {
|
it('should get and empty annotation list for an unknown class', () => {
|
||||||
let UnknownClass = host.findDeclaration('src/app/app.component', 'UnknownClass');
|
let UnknownClass = host.findDeclaration('src/app/app.component', 'UnknownClass');
|
||||||
let annotations = reflector.annotations(UnknownClass);
|
let annotations = reflector.annotations(UnknownClass);
|
||||||
|
@ -300,8 +305,9 @@ class MockReflectorHost implements StaticReflectorHost {
|
||||||
|
|
||||||
getMetadataFor(moduleId: string): any {
|
getMetadataFor(moduleId: string): any {
|
||||||
let data: {[key: string]: any} = {
|
let data: {[key: string]: any} = {
|
||||||
'/tmp/angular2/src/common/forms/directives.d.ts': {
|
'/tmp/angular2/src/common/forms/directives.d.ts': [{
|
||||||
"__symbolic": "module",
|
"__symbolic": "module",
|
||||||
|
"version": 1,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"FORM_DIRECTIVES": [
|
"FORM_DIRECTIVES": [
|
||||||
{
|
{
|
||||||
|
@ -311,9 +317,10 @@ class MockReflectorHost implements StaticReflectorHost {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
}],
|
||||||
'/tmp/angular2/src/common/directives/ng_for.d.ts': {
|
'/tmp/angular2/src/common/directives/ng_for.d.ts': {
|
||||||
"__symbolic": "module",
|
"__symbolic": "module",
|
||||||
|
"version": 1,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"NgFor": {
|
"NgFor": {
|
||||||
"__symbolic": "class",
|
"__symbolic": "class",
|
||||||
|
@ -366,15 +373,16 @@ class MockReflectorHost implements StaticReflectorHost {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'/tmp/angular2/src/core/linker/view_container_ref.d.ts':
|
'/tmp/angular2/src/core/linker/view_container_ref.d.ts':
|
||||||
{"metadata": {"ViewContainerRef": {"__symbolic": "class"}}},
|
{version: 1, "metadata": {"ViewContainerRef": {"__symbolic": "class"}}},
|
||||||
'/tmp/angular2/src/core/linker/template_ref.d.ts':
|
'/tmp/angular2/src/core/linker/template_ref.d.ts':
|
||||||
{"module": "./template_ref", "metadata": {"TemplateRef": {"__symbolic": "class"}}},
|
{version: 1, "module": "./template_ref", "metadata": {"TemplateRef": {"__symbolic": "class"}}},
|
||||||
'/tmp/angular2/src/core/change_detection/differs/iterable_differs.d.ts':
|
'/tmp/angular2/src/core/change_detection/differs/iterable_differs.d.ts':
|
||||||
{"metadata": {"IterableDiffers": {"__symbolic": "class"}}},
|
{version: 1, "metadata": {"IterableDiffers": {"__symbolic": "class"}}},
|
||||||
'/tmp/angular2/src/core/change_detection/change_detector_ref.d.ts':
|
'/tmp/angular2/src/core/change_detection/change_detector_ref.d.ts':
|
||||||
{"metadata": {"ChangeDetectorRef": {"__symbolic": "class"}}},
|
{version: 1, "metadata": {"ChangeDetectorRef": {"__symbolic": "class"}}},
|
||||||
'/tmp/src/app/hero-detail.component.d.ts': {
|
'/tmp/src/app/hero-detail.component.d.ts': {
|
||||||
"__symbolic": "module",
|
"__symbolic": "module",
|
||||||
|
"version": 1,
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"HeroDetailComponent": {
|
"HeroDetailComponent": {
|
||||||
"__symbolic": "class",
|
"__symbolic": "class",
|
||||||
|
@ -422,7 +430,8 @@ class MockReflectorHost implements StaticReflectorHost {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'/src/extern.d.ts': {"__symbolic": "module", metadata: {s: "s"}}
|
'/src/extern.d.ts': {"__symbolic": "module", "version": 1, metadata: {s: "s"}},
|
||||||
|
'/tmp/src/version-error.d.ts': {"__symbolic": "module", "version": 100, metadata: {e: "s"}},
|
||||||
};
|
};
|
||||||
return data[moduleId];
|
return data[moduleId];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import * as ts from 'typescript';
|
import * as ts from 'typescript';
|
||||||
|
|
||||||
import {Evaluator, ImportMetadata, ImportSpecifierMetadata, isPrimitive} from './evaluator';
|
import {Evaluator, ImportMetadata, ImportSpecifierMetadata, isPrimitive} from './evaluator';
|
||||||
import {ClassMetadata, ConstructorMetadata, ModuleMetadata, MemberMetadata, MetadataError, MetadataMap, MetadataSymbolicExpression, MetadataSymbolicReferenceExpression, MetadataValue, MethodMetadata, isMetadataError, isMetadataSymbolicReferenceExpression,} from './schema';
|
import {ClassMetadata, ConstructorMetadata, ModuleMetadata, MemberMetadata, MetadataError, MetadataMap, MetadataSymbolicExpression, MetadataSymbolicReferenceExpression, MetadataValue, MethodMetadata, isMetadataError, isMetadataSymbolicReferenceExpression, VERSION} from './schema';
|
||||||
import {Symbols} from './symbols';
|
import {Symbols} from './symbols';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,6 +207,6 @@ export class MetadataCollector {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return metadata && {__symbolic: 'module', metadata};
|
return metadata && {__symbolic: 'module', version: VERSION, metadata};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,17 @@
|
||||||
|
// Metadata Schema
|
||||||
|
|
||||||
|
// If you make a backwards incompatible change to the schema, increment the VERSION number.
|
||||||
|
|
||||||
|
// If you make a backwards compatible change to the metadata (such as adding an option field) then
|
||||||
|
// leave VERSION the same. If possible, as many versions of the metadata that can represent the
|
||||||
|
// semantics of the file in an array. For example, when generating a version 2 file, if version 1
|
||||||
|
// can accurately represent the metadata, generate both version 1 and version 2 in an array.
|
||||||
|
|
||||||
|
export const VERSION = 1;
|
||||||
|
|
||||||
export interface ModuleMetadata {
|
export interface ModuleMetadata {
|
||||||
__symbolic: 'module';
|
__symbolic: 'module';
|
||||||
|
version: number;
|
||||||
metadata: {[name: string]: (ClassMetadata | MetadataValue)};
|
metadata: {[name: string]: (ClassMetadata | MetadataValue)};
|
||||||
}
|
}
|
||||||
export function isModuleMetadata(value: any): value is ModuleMetadata {
|
export function isModuleMetadata(value: any): value is ModuleMetadata {
|
||||||
|
|
Loading…
Reference in New Issue