Skip to content

Commit

Permalink
fix: array decorator
Browse files Browse the repository at this point in the history
  • Loading branch information
jannyHou committed May 28, 2020
1 parent 28681dd commit 08ba68d
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 18 deletions.
21 changes: 21 additions & 0 deletions docs/site/Model.md
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,27 @@ class TestModel {
}
```
To define a nested array property, you must provide the `jsonSchema` field to
describe the sub-array property. For example:
```ts
@model()
class TestModel {
// alternatively use @property.array('array')
@property.array(Array, {
jsonSchema: {
type: 'array',
items: {type: 'string'},
},
})
nestedArr: Array<Array<string>>;
}
```
If the `jsonSchema` field is missing, you will get an error saying
> You must provide the "jsonSchema" field when define a nested array property'
### Validation Rules
You can also specify the validation rules in the field `jsonSchema`. For
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,34 @@ describe('build-schema', () => {
expectValidJsonSchema(jsonSchema);
});

it('properly converts nested array property when json schema provided', () => {
@model()
class TestModel {
// alternatively use @property.array('array')
@property.array(Array, {
jsonSchema: {
type: 'array',
items: {type: 'string'},
},
})
nestedArr: Array<Array<string>>;
}

const jsonSchema = modelToJsonSchema(TestModel);
expect(jsonSchema.properties).to.deepEqual({
nestedArr: {
type: 'array',
items: {
type: 'array',
items: {
type: 'string',
},
},
},
});
expectValidJsonSchema(jsonSchema);
});

it('properly converts properties with enum in json schema', () => {
enum QueryLanguage {
JSON = 'json',
Expand Down Expand Up @@ -308,22 +336,20 @@ describe('build-schema', () => {
});
});

it('properly converts properties with recursive arrays', () => {
it('throws for nested array property when json schema is missing', () => {
@model()
class RecursiveArray {
@property.array(Array)
recArr: string[][];
}

const jsonSchema = modelToJsonSchema(RecursiveArray);
expect(jsonSchema.properties).to.eql({
recArr: {
type: 'array',
items: {
type: 'array',
},
expect.throws(
() => {
modelToJsonSchema(RecursiveArray);
},
});
Error,
'You must provide the "jsonSchema" field when define a nested array property',
);
});

it('supports explicit primitive type decoration via strings', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@ describe('build-schema', () => {
});

describe('metaToJsonSchema', () => {
it('errors out if "itemType" is an array', () => {
expect(() => metaToJsonProperty({type: Array, itemType: []})).to.throw(
/itemType as an array is not supported/,
);
});

it('converts Boolean', () => {
expect(metaToJsonProperty({type: Boolean})).to.eql({
type: 'boolean',
Expand Down
10 changes: 7 additions & 3 deletions packages/repository-json-schema/src/build-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
ModelMetadataHelper,
Null,
PropertyDefinition,
PropertyType,
RelationMetadata,
resolveType,
} from '@loopback/repository';
Expand Down Expand Up @@ -242,7 +243,7 @@ export function stringTypeToWrapper(type: string | Function): Function {
* Determines whether a given string or constructor is array type or not
* @param type - Type as string or wrapper
*/
export function isArrayType(type: string | Function) {
export function isArrayType(type: string | Function | PropertyType) {
return type === Array || type === 'array';
}

Expand All @@ -256,8 +257,11 @@ export function metaToJsonProperty(meta: PropertyDefinition): JsonSchema {
let propertyType = meta.type as string | Function;

if (isArrayType(propertyType) && meta.itemType) {
if (Array.isArray(meta.itemType)) {
throw new Error('itemType as an array is not supported');
if (isArrayType(meta.itemType) && !meta.jsonSchema) {
throw new Error(
'You must provide the "jsonSchema" field when define ' +
'a nested array property',
);
}
result = {type: 'array', items: propDef};
propertyType = meta.itemType as string | Function;
Expand Down

0 comments on commit 08ba68d

Please sign in to comment.