Skip to content

Commit

Permalink
feat(jsonschema): Add AllowTypes and Any decorators for jsonSchema
Browse files Browse the repository at this point in the history
- Add AllowTypes and Any,
- Fix Converter decorators. Now, Converter throw an error when it used without type,
- AJV use JSONSchema6 instead of JSONSchema4.
- Add tag documentation on decorators
  • Loading branch information
Romakita committed Jan 4, 2018
1 parent 9793008 commit 5b7778d
Show file tree
Hide file tree
Showing 29 changed files with 172 additions and 18 deletions.
7 changes: 3 additions & 4 deletions docs/docs/jsonschema.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ class Person {

Decorators list:

<ul class="api-list" style="display: block;"><li class="api-item" data-symbol="common/jsonschema;Default;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/default" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Default" title="Default"><span class="symbol decorator"></span>Default</a></li>
<ul class="api-list" style="display: block;">
<li class="api-item" data-symbol="common/jsonschema;Any;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/any" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Any" title="Any"><span class="symbol decorator"></span>Any</a></li>
<li class="api-item" data-symbol="common/jsonschema;Default;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/default" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Default" title="Default"><span class="symbol decorator"></span>Default</a></li>
<li class="api-item" data-symbol="common/jsonschema;Email;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/email" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Email" title="Email"><span class="symbol decorator"></span>Email</a></li>
<li class="api-item" data-symbol="common/jsonschema;Enum;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/enum" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Enum" title="Enum"><span class="symbol decorator"></span>Enum</a></li>
<li class="api-item" data-symbol="common/jsonschema;ExclusiveMaximum;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/exclusivemaximum" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-ExclusiveMaximum" title="ExclusiveMaximum"><span class="symbol decorator"></span>ExclusiveMaximum</a></li>
Expand All @@ -74,9 +76,6 @@ Decorators list:
<li class="api-item" data-symbol="common/jsonschema;Minimum;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/minimum" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Minimum" title="Minimum"><span class="symbol decorator"></span>Minimum</a></li>
<li class="api-item" data-symbol="common/jsonschema;MultipleOf;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/multipleof" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-MultipleOf" title="MultipleOf"><span class="symbol decorator"></span>MultipleOf</a></li>
<li class="api-item" data-symbol="common/jsonschema;Pattern;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/pattern" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Pattern" title="Pattern"><span class="symbol decorator"></span>Pattern</a></li>
<li class="api-item" data-symbol="common/jsonschema;Property;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/property" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-Property" title="Property"><span class="symbol decorator"></span>Property</a></li>
<li class="api-item" data-symbol="common/jsonschema;PropertyName;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/propertyname" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-PropertyName" title="PropertyName"><span class="symbol decorator"></span>PropertyName</a></li>
<li class="api-item" data-symbol="common/jsonschema;PropertyType;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/propertytype" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-PropertyType" title="PropertyType"><span class="symbol decorator"></span>PropertyType</a></li>
<li class="api-item" data-symbol="common/jsonschema;UniqueItems;decorator;@;false;false;false;false" style="display: inline-block;"><a href="#/api/common/jsonschema/uniqueitems" class="symbol-container deprecated symbol-type-decorator symbol-name-commonjsonschema-UniqueItems" title="UniqueItems"><span class="symbol decorator"></span>UniqueItems</a></li>
</ul>

Expand Down
6 changes: 5 additions & 1 deletion src/converters/decorators/converter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ export function Converter(...classes: any[]): Function {

return (target: any) => {

/* istanbul ignore next */
if (classes.length === 0) {
throw new Error("Converter decorator need at least one type like String, Date, Class, etc...");
}

classes.forEach(clazz =>
Metadata.set(CONVERTER, target, clazz)
);

};
}
23 changes: 23 additions & 0 deletions src/jsonschema/decorators/allowTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import {JSONSchema6TypeName} from "json-schema";
import {PropertyMetadata} from "../class/PropertyMetadata";
import {PropertyRegistry} from "../registries/PropertyRegistry";

/**
* Set the type of the array items.
*
* ```typescript
* class Model {
* @AllowTypes("string", "integer", "boolean", "array")
* property: string[];
* }
* ```
*
* @returns {Function}
* @decorator
* @param types
*/
export function AllowTypes(...types: JSONSchema6TypeName[]) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
propertyMetadata.schema.type = types;
});
}
24 changes: 24 additions & 0 deletions src/jsonschema/decorators/any.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {JSONSchema6TypeName} from "json-schema";
import {PropertyMetadata} from "../class/PropertyMetadata";
import {PropertyRegistry} from "../registries/PropertyRegistry";

/**
* Set the type of the array items.
*
* ```typescript
* class Model {
* @Any()
* // eq. @AllowTypes("any")
* property: any;
* }
* ```
*
* @returns {Function}
* @decorator
* @param types
*/
export function Any(...types: JSONSchema6TypeName[]) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
propertyMetadata.schema.type = "any";
});
}
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {string | number | boolean | {}} defaultValue
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function Default(defaultValue: string | number | boolean | {}) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/email.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import {Format} from "./format";
*
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function Email() {
return Format("email");
Expand Down
4 changes: 3 additions & 1 deletion src/jsonschema/decorators/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
*
* @param {string | number | boolean | {}} enumValue
* @returns {Function}
* @constructor
* @decorator
* @ajv
* @jsonschema
*/
export function Enum(...enumValue: Array<string | number | boolean | {}>) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/exclusiveMaximum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {Maximum} from "./maximum";
* @param {boolean} exclusiveMaximum
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function ExclusiveMaximum(maximum: number, exclusiveMaximum: boolean = true) {
return Maximum(maximum, exclusiveMaximum);
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/exclusiveMinimum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import {Minimum} from "./minimum";
* @param {boolean} exclusiveMinimum
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function ExclusiveMinimum(minimum: number, exclusiveMinimum: boolean = true) {
return Minimum(minimum, exclusiveMinimum);
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/format.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {string} format
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function Format(format: string) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/jsonProperty.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @returns {Function}
* @decorator
* @param options
* @decorator
* @converters
*/
export function JsonProperty<T>(options?: IPropertyOptions | string): Function {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/maxItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {number} maxItems
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function MaxItems(maxItems: number) {

Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/maxLength.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {number} maxLength
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function MaxLength(maxLength: number) {

Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/maxProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {number} maxProperties
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function MaxProperties(maxProperties: number) {
if (maxProperties < 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/maximum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {boolean} exclusive
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function Maximum(maximum: number, exclusive: boolean = false) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/minItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {number} minItems
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function MinItems(minItems: number) {

Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/minLength.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {number} minLength
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function MinLength(minLength: number) {

Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/minProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {number} minProperties
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function MinProperties(minProperties: number) {
if (minProperties < 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/minimum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {boolean} exclusive
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function Minimum(minimum: number, exclusive: boolean = false) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/multipleOf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {number} multipleOf
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function MultipleOf(multipleOf: number) {
if (multipleOf <= 0) {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/decorators/pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
* @param {string} pattern
* @returns {Function}
* @decorator
* @ajv
* @jsonschema
*/
export function Pattern(pattern: string | RegExp) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
5 changes: 4 additions & 1 deletion src/jsonschema/decorators/propertyName.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
/**
* Create an alias of the propertyKey that must be used by the converter.
*
* ?> This decorator is used by the Converters to deserialize correctly you model.
*
* ## Example
*
* ```typescript
Expand All @@ -15,7 +17,8 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
*
* @param {string} name
* @returns {Function}
* @decorators
* @decorator
* @converters
*/
export function PropertyName(name: string) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
29 changes: 27 additions & 2 deletions src/jsonschema/decorators/propertyType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,43 @@ import {PropertyMetadata} from "../class/PropertyMetadata";
import {PropertyRegistry} from "../registries/PropertyRegistry";

/**
* Set the type of the array items.
* Set the type of the array items. The possible value is String, Boolean, Number, Date, Object, Class, etc...
*
* ?> This decorator is used by the Converters to deserialize correctly you model.
*
* ```typescript
* class Model {
* @PropertyType(String)
* property: string[];
* }
* ```
* !> You didn't use the `type Type = string | number` as parameters Type.
*
* Didn't works:
*
* ```typescript
* type Type = "string" | "number"
* class Model {
* @PropertyType(Type)
* property: Type[];
* }
* ```
*
* Works with converter and AJV:
*
* ```typescript
* type Type = "string" | "number"
* class Model {
* @Property()
* @AllowTypes("string", "number") // for AJV
* property: Type[];
* }
* ```
*
* @param {Type<any>} type
* @returns {Function}
* @decorators
* @decorator
* @converters
*/
export function PropertyType(type: Type<any>) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
4 changes: 3 additions & 1 deletion src/jsonschema/decorators/uniqueItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ import {PropertyRegistry} from "../registries/PropertyRegistry";
*
* @param {boolean} uniqueItems
* @returns {Function}
* @constructor
* @decorator
* @ajv
* @jsonschema
*/
export function UniqueItems(uniqueItems: boolean = true) {
return PropertyRegistry.decorate((propertyMetadata: PropertyMetadata) => {
Expand Down
2 changes: 2 additions & 0 deletions src/jsonschema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ export * from "./decorators/minProperties";
export * from "./decorators/multipleOf";
export * from "./decorators/pattern";
export * from "./decorators/uniqueItems";
export * from "./decorators/allowTypes";
export * from "./decorators/any";
export * from "./services/JsonSchemesService";
21 changes: 21 additions & 0 deletions test/units/jsonschema/decorators/allowTypes.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {AllowTypes} from "../../../../src/jsonschema/decorators/allowTypes";
import {PropertyRegistry} from "../../../../src/jsonschema/registries/PropertyRegistry";
import {Sinon} from "../../../tools";

describe("AllowTypes", () => {
before(() => {
this.decorateStub = Sinon.stub(PropertyRegistry, "decorate");
this.propertyMetadata = {
schema: {}
};
AllowTypes("string", "number");
this.decorateStub.getCall(0).args[0](this.propertyMetadata);
});
after(() => {
this.decorateStub.restore();
});

it("should store data", () => {
this.propertyMetadata.schema.type.should.deep.eq(["string", "number"]);
});
});
21 changes: 21 additions & 0 deletions test/units/jsonschema/decorators/any.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import {Any} from "../../../../src/jsonschema/decorators/any";
import {PropertyRegistry} from "../../../../src/jsonschema/registries/PropertyRegistry";
import {Sinon} from "../../../tools";

describe("AllowTypes", () => {
before(() => {
this.decorateStub = Sinon.stub(PropertyRegistry, "decorate");
this.propertyMetadata = {
schema: {}
};
Any();
this.decorateStub.getCall(0).args[0](this.propertyMetadata);
});
after(() => {
this.decorateStub.restore();
});

it("should store data", () => {
this.propertyMetadata.schema.type.should.deep.eq("any");
});
});
6 changes: 2 additions & 4 deletions test/units/jsonschema/decorators/exclusiveMaximum.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ describe("ExclusiveMaximum", () => {
});

it("should store data", () => {
this.propertyMetadata.schema.exclusiveMaximum.should.eq(true);
this.propertyMetadata.schema.maximum.should.eq(10);
this.propertyMetadata.schema.exclusiveMaximum.should.eq(10);
});
});

Expand All @@ -36,8 +35,7 @@ describe("ExclusiveMaximum", () => {
});

it("should store data", () => {
this.propertyMetadata.schema.exclusiveMaximum.should.eq(true);
this.propertyMetadata.schema.maximum.should.eq(10);
this.propertyMetadata.schema.exclusiveMaximum.should.eq(10);
});
});
});

0 comments on commit 5b7778d

Please sign in to comment.