Permalink
Browse files

feat(@ngtools/json-schema): Introduce a separate package for JSON sch…

…ema. (#3927)

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).
  • Loading branch information...
1 parent c6d1c99 commit 74f7cddf9e0a5af013ccd15350f018849846daf5 @hansl hansl committed on GitHub Jan 11, 2017
Showing with 844 additions and 262 deletions.
  1. +0 −1 package.json
  2. +32 −0 packages/@ngtools/json-schema/package.json
  3. +12 −0 packages/@ngtools/json-schema/src/error.ts
  4. +1 −0 packages/@ngtools/json-schema/src/index.ts
  5. +34 −0 packages/@ngtools/json-schema/src/mimetypes.ts
  6. +42 −0 packages/@ngtools/json-schema/src/node.ts
  7. +8 −2 packages/{angular-cli/models/json-schema → @ngtools/json-schema/src}/schema-class-factory.ts
  8. +34 −0 packages/@ngtools/json-schema/src/schema-tree.spec.ts
  9. +187 −87 packages/{angular-cli/models/json-schema → @ngtools/json-schema/src}/schema-tree.ts
  10. +26 −0 packages/@ngtools/json-schema/src/serializer.ts
  11. +30 −0 packages/@ngtools/json-schema/src/serializers/dts.spec.ts
  12. +150 −0 packages/@ngtools/json-schema/src/serializers/dts.ts
  13. +32 −0 packages/@ngtools/json-schema/src/serializers/json.spec.ts
  14. +56 −55 ...ges/{angular-cli/models/json-schema/serializer.ts → @ngtools/json-schema/src/serializers/json.ts}
  15. +84 −0 packages/@ngtools/json-schema/tests/schema1.json
  16. +8 −0 packages/@ngtools/json-schema/tests/value1-1.json
  17. +7 −0 packages/@ngtools/json-schema/tests/value1.json
  18. +27 −0 packages/@ngtools/json-schema/tsconfig.json
  19. +1 −0 packages/angular-cli/lib/config/.gitignore
  20. +0 −79 packages/angular-cli/lib/config/schema.d.ts
  21. +2 −1 packages/angular-cli/lib/config/schema.json
  22. +30 −32 {tests/models → packages/angular-cli/models/config}/config.spec.ts
  23. +1 −1 packages/angular-cli/models/config/config.ts
  24. 0 {tests/models → packages/angular-cli/models/config}/spec-schema.d.ts
  25. +3 −4 {tests/models → packages/angular-cli/models/config}/spec-schema.json
  26. +1 −0 packages/angular-cli/package.json
  27. +1 −0 packages/angular-cli/tsconfig.json
  28. +28 −0 scripts/build-schema-dts.js
  29. +7 −0 scripts/publish/build.js
View
@@ -21,7 +21,6 @@
"test:deps": "node scripts/publish/validate_dependencies.js",
"test:inspect": "node --inspect --debug-brk tests/runner",
"test:packages": "node scripts/run-packages-spec.js",
- "build-config-interface": "dtsgen packages/angular-cli/lib/config/schema.json --out packages/angular-cli/lib/config/schema.d.ts",
"eslint": "eslint .",
"tslint": "tslint \"**/*.ts\" -c tslint.json -e \"**/blueprints/*/files/**/*.ts\" -e \"node_modules/**\" -e \"tmp/**\" -e \"dist/**\"",
"lint": "npm-run-all -c eslint tslint"
@@ -0,0 +1,32 @@
+{
+ "name": "@ngtools/json-schema",
+ "version": "1.2.1",
+ "description": "Schema validating and reading for configurations, similar to Angular CLI config.",
+ "main": "./src/index.js",
+ "typings": "src/index.d.ts",
+ "license": "MIT",
+ "keywords": [
+ "angular",
+ "json",
+ "json-schema",
+ "schema",
+ "config"
+ ],
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/angular/angular-cli.git"
+ },
+ "author": "angular",
+ "bugs": {
+ "url": "https://github.com/angular/angular-cli/issues"
+ },
+ "homepage": "https://github.com/angular/angular-cli/tree/master/packages/@ngtools/json-schema",
+ "engines": {
+ "node": ">= 4.1.0",
+ "npm": ">= 3.0.0"
+ },
+ "dependencies": {
+ },
+ "peerDependencies": {
+ }
+}
@@ -0,0 +1,12 @@
+
+export class JsonSchemaErrorBase extends Error {
+ constructor(message?: string) {
+ super();
+
+ if (message) {
+ this.message = message;
+ } else {
+ this.message = (<any>this.constructor).name;
+ }
+ }
+}
@@ -0,0 +1 @@
+export {SchemaClass, SchemaClassFactory} from './schema-class-factory';
@@ -0,0 +1,34 @@
+import {JsonSchemaErrorBase} from './error';
+import {Serializer, WriterFn} from './serializer';
+import {JsonSerializer} from './serializers/json';
+import {DTsSerializer} from './serializers/dts';
+
+
+export class UnknownMimetype extends JsonSchemaErrorBase {}
+
+
+export function createSerializerFromMimetype(mimetype: string,
+ writer: WriterFn,
+ ...opts: any[]): Serializer {
+ let Klass: { new (writer: WriterFn, ...args: any[]): Serializer } = null;
+ switch (mimetype) {
+ case 'application/json': Klass = JsonSerializer; break;
+ case 'text/json': Klass = JsonSerializer; break;
+ case 'text/x.typescript': Klass = DTsSerializer; break;
+ case 'text/x.dts': Klass = DTsSerializer; break;
+
+ default: throw new UnknownMimetype();
+ }
+
+ return new Klass(writer, ...opts);
+
+}
+
+
+declare module './serializer' {
+ namespace Serializer {
+ export let fromMimetype: typeof createSerializerFromMimetype;
+ }
+}
+
+Serializer.fromMimetype = createSerializerFromMimetype;
@@ -0,0 +1,42 @@
+import {Serializer} from './serializer';
+
+
+// A TypeScript Type. This can be used to do `new tsType(value)`.
+// `null` implies any type; be careful.
+export type TypeScriptType = typeof Number
+ | typeof Boolean
+ | typeof String
+ | typeof Object
+ | typeof Array
+ | null;
+
+
+// The most generic interface for a schema node. This is used by the serializers.
+export interface SchemaNode {
+ readonly name: string;
+ readonly type: string;
+ readonly tsType: TypeScriptType;
+ readonly defined: boolean;
+ readonly dirty: boolean;
+ readonly frozen: boolean;
+ readonly readOnly: boolean;
+ readonly defaultValue: any | null;
+ readonly required: boolean;
+ readonly parent: SchemaNode | null;
+
+ // Schema related properties.
+ readonly description: string | null;
+
+ // Object-only properties. `null` for everything else.
+ readonly children: { [key: string]: SchemaNode } | null;
+
+ // Array-only properties. `null` for everything else.
+ readonly items: SchemaNode[] | null;
+ readonly itemPrototype: SchemaNode | null;
+
+ // Mutable properties.
+ value: any;
+
+ // Serialization.
+ serialize(serializer: Serializer): void;
+}
@@ -1,8 +1,11 @@
-import {NgToolkitError} from '../error';
import {Serializer} from './serializer';
import {RootSchemaTreeNode, SchemaTreeNode} from './schema-tree';
+import {JsonSchemaErrorBase} from './error';
-export class InvalidJsonPath extends NgToolkitError {}
+import './mimetypes';
+
+
+export class InvalidJsonPath extends JsonSchemaErrorBase {}
// The schema tree node property of the SchemaClass.
@@ -66,6 +69,9 @@ export interface SchemaClass<JsonType> extends Object {
$$defined(path: string): boolean;
$$delete(path: string): void;
+ // Direct access to the schema.
+ $$schema(): RootSchemaTreeNode;
+
$$serialize(mimetype?: string): string;
}
@@ -0,0 +1,34 @@
+import {readFileSync} from 'fs';
+import {join} from 'path';
+
+import {RootSchemaTreeNode} from './schema-tree';
+
+
+describe('SchemaTreeNode', () => {
+
+});
+
+
+describe('OneOfSchemaTreeNode', () => {
+ const schemaJsonFilePath = join(__dirname, '../tests/schema1.json');
+ const schemaJson = JSON.parse(readFileSync(schemaJsonFilePath, 'utf-8'));
+ const valueJsonFilePath = join(__dirname, '../tests/value1-1.json');
+ const valueJson = JSON.parse(readFileSync(valueJsonFilePath, 'utf-8'));
+
+
+ it('works', () => {
+ const proto: any = Object.create(null);
+ new RootSchemaTreeNode(proto, {
+ value: valueJson,
+ schema: schemaJson
+ });
+
+ expect(proto.oneOfKey2 instanceof Array).toBe(true);
+ expect(proto.oneOfKey2.length).toBe(2);
+
+ // Set it to a string, which is valid.
+ proto.oneOfKey2 = 'hello';
+ expect(proto.oneOfKey2 instanceof Array).toBe(false);
+ });
+});
+
Oops, something went wrong.

0 comments on commit 74f7cdd

Please sign in to comment.