Skip to content

Commit 6e5d9bc

Browse files
committed
feat(json-schema): Introduce a separate package for JSON schema.
This is the same code we used before, but: 1. its in a separate package, 2. it also support new serialization to .d.ts, 3. OneOf is now supported entirely (instead of the previous hack). Also, removed the schema.d.ts file and generate it before building the package. It is not git ignored and changing it will not work (it will be overwritten).
1 parent 338e69b commit 6e5d9bc

29 files changed

+844
-262
lines changed

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
"test:deps": "node scripts/publish/validate_dependencies.js",
2222
"test:inspect": "node --inspect --debug-brk tests/runner",
2323
"test:packages": "node scripts/run-packages-spec.js",
24-
"build-config-interface": "dtsgen packages/angular-cli/lib/config/schema.json --out packages/angular-cli/lib/config/schema.d.ts",
2524
"eslint": "eslint .",
2625
"tslint": "tslint \"**/*.ts\" -c tslint.json -e \"**/blueprints/*/files/**/*.ts\" -e \"node_modules/**\" -e \"tmp/**\" -e \"dist/**\"",
2726
"lint": "npm-run-all -c eslint tslint"
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
"name": "@ngtools/json-schema",
3+
"version": "1.2.1",
4+
"description": "Schema validating and reading for configurations, similar to Angular CLI config.",
5+
"main": "./src/index.js",
6+
"typings": "src/index.d.ts",
7+
"license": "MIT",
8+
"keywords": [
9+
"angular",
10+
"json",
11+
"json-schema",
12+
"schema",
13+
"config"
14+
],
15+
"repository": {
16+
"type": "git",
17+
"url": "https://github.com/angular/angular-cli.git"
18+
},
19+
"author": "angular",
20+
"bugs": {
21+
"url": "https://github.com/angular/angular-cli/issues"
22+
},
23+
"homepage": "https://github.com/angular/angular-cli/tree/master/packages/@ngtools/json-schema",
24+
"engines": {
25+
"node": ">= 4.1.0",
26+
"npm": ">= 3.0.0"
27+
},
28+
"dependencies": {
29+
},
30+
"peerDependencies": {
31+
}
32+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
export class JsonSchemaErrorBase extends Error {
3+
constructor(message?: string) {
4+
super();
5+
6+
if (message) {
7+
this.message = message;
8+
} else {
9+
this.message = (<any>this.constructor).name;
10+
}
11+
}
12+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {SchemaClass, SchemaClassFactory} from './schema-class-factory';
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {JsonSchemaErrorBase} from './error';
2+
import {Serializer, WriterFn} from './serializer';
3+
import {JsonSerializer} from './serializers/json';
4+
import {DTsSerializer} from './serializers/dts';
5+
6+
7+
export class UnknownMimetype extends JsonSchemaErrorBase {}
8+
9+
10+
export function createSerializerFromMimetype(mimetype: string,
11+
writer: WriterFn,
12+
...opts: any[]): Serializer {
13+
let Klass: { new (writer: WriterFn, ...args: any[]): Serializer } = null;
14+
switch (mimetype) {
15+
case 'application/json': Klass = JsonSerializer; break;
16+
case 'text/json': Klass = JsonSerializer; break;
17+
case 'text/x.typescript': Klass = DTsSerializer; break;
18+
case 'text/x.dts': Klass = DTsSerializer; break;
19+
20+
default: throw new UnknownMimetype();
21+
}
22+
23+
return new Klass(writer, ...opts);
24+
25+
}
26+
27+
28+
declare module './serializer' {
29+
namespace Serializer {
30+
export let fromMimetype: typeof createSerializerFromMimetype;
31+
}
32+
}
33+
34+
Serializer.fromMimetype = createSerializerFromMimetype;
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import {Serializer} from './serializer';
2+
3+
4+
// A TypeScript Type. This can be used to do `new tsType(value)`.
5+
// `null` implies any type; be careful.
6+
export type TypeScriptType = typeof Number
7+
| typeof Boolean
8+
| typeof String
9+
| typeof Object
10+
| typeof Array
11+
| null;
12+
13+
14+
// The most generic interface for a schema node. This is used by the serializers.
15+
export interface SchemaNode {
16+
readonly name: string;
17+
readonly type: string;
18+
readonly tsType: TypeScriptType;
19+
readonly defined: boolean;
20+
readonly dirty: boolean;
21+
readonly frozen: boolean;
22+
readonly readOnly: boolean;
23+
readonly defaultValue: any | null;
24+
readonly required: boolean;
25+
readonly parent: SchemaNode | null;
26+
27+
// Schema related properties.
28+
readonly description: string | null;
29+
30+
// Object-only properties. `null` for everything else.
31+
readonly children: { [key: string]: SchemaNode } | null;
32+
33+
// Array-only properties. `null` for everything else.
34+
readonly items: SchemaNode[] | null;
35+
readonly itemPrototype: SchemaNode | null;
36+
37+
// Mutable properties.
38+
value: any;
39+
40+
// Serialization.
41+
serialize(serializer: Serializer): void;
42+
}

packages/angular-cli/models/json-schema/schema-class-factory.ts renamed to packages/@ngtools/json-schema/src/schema-class-factory.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
import {NgToolkitError} from '../error';
21
import {Serializer} from './serializer';
32
import {RootSchemaTreeNode, SchemaTreeNode} from './schema-tree';
3+
import {JsonSchemaErrorBase} from './error';
44

5-
export class InvalidJsonPath extends NgToolkitError {}
5+
import './mimetypes';
6+
7+
8+
export class InvalidJsonPath extends JsonSchemaErrorBase {}
69

710

811
// The schema tree node property of the SchemaClass.
@@ -66,6 +69,9 @@ export interface SchemaClass<JsonType> extends Object {
6669
$$defined(path: string): boolean;
6770
$$delete(path: string): void;
6871

72+
// Direct access to the schema.
73+
$$schema(): RootSchemaTreeNode;
74+
6975
$$serialize(mimetype?: string): string;
7076
}
7177

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import {readFileSync} from 'fs';
2+
import {join} from 'path';
3+
4+
import {RootSchemaTreeNode} from './schema-tree';
5+
6+
7+
describe('SchemaTreeNode', () => {
8+
9+
});
10+
11+
12+
describe('OneOfSchemaTreeNode', () => {
13+
const schemaJsonFilePath = join(__dirname, '../tests/schema1.json');
14+
const schemaJson = JSON.parse(readFileSync(schemaJsonFilePath, 'utf-8'));
15+
const valueJsonFilePath = join(__dirname, '../tests/value1-1.json');
16+
const valueJson = JSON.parse(readFileSync(valueJsonFilePath, 'utf-8'));
17+
18+
19+
it('works', () => {
20+
const proto: any = Object.create(null);
21+
new RootSchemaTreeNode(proto, {
22+
value: valueJson,
23+
schema: schemaJson
24+
});
25+
26+
expect(proto.oneOfKey2 instanceof Array).toBe(true);
27+
expect(proto.oneOfKey2.length).toBe(2);
28+
29+
// Set it to a string, which is valid.
30+
proto.oneOfKey2 = 'hello';
31+
expect(proto.oneOfKey2 instanceof Array).toBe(false);
32+
});
33+
});
34+

0 commit comments

Comments
 (0)