Skip to content

Commit 08ba68d

Browse files
committed
fix: array decorator
1 parent 28681dd commit 08ba68d

File tree

4 files changed

+63
-18
lines changed

4 files changed

+63
-18
lines changed

docs/site/Model.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,27 @@ class TestModel {
851851
}
852852
```
853853
854+
To define a nested array property, you must provide the `jsonSchema` field to
855+
describe the sub-array property. For example:
856+
857+
```ts
858+
@model()
859+
class TestModel {
860+
// alternatively use @property.array('array')
861+
@property.array(Array, {
862+
jsonSchema: {
863+
type: 'array',
864+
items: {type: 'string'},
865+
},
866+
})
867+
nestedArr: Array<Array<string>>;
868+
}
869+
```
870+
871+
If the `jsonSchema` field is missing, you will get an error saying
872+
873+
> You must provide the "jsonSchema" field when define a nested array property'
874+
854875
### Validation Rules
855876
856877
You can also specify the validation rules in the field `jsonSchema`. For

packages/repository-json-schema/src/__tests__/integration/build-schema.integration.ts

Lines changed: 35 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,34 @@ describe('build-schema', () => {
251251
expectValidJsonSchema(jsonSchema);
252252
});
253253

254+
it('properly converts nested array property when json schema provided', () => {
255+
@model()
256+
class TestModel {
257+
// alternatively use @property.array('array')
258+
@property.array(Array, {
259+
jsonSchema: {
260+
type: 'array',
261+
items: {type: 'string'},
262+
},
263+
})
264+
nestedArr: Array<Array<string>>;
265+
}
266+
267+
const jsonSchema = modelToJsonSchema(TestModel);
268+
expect(jsonSchema.properties).to.deepEqual({
269+
nestedArr: {
270+
type: 'array',
271+
items: {
272+
type: 'array',
273+
items: {
274+
type: 'string',
275+
},
276+
},
277+
},
278+
});
279+
expectValidJsonSchema(jsonSchema);
280+
});
281+
254282
it('properly converts properties with enum in json schema', () => {
255283
enum QueryLanguage {
256284
JSON = 'json',
@@ -308,22 +336,20 @@ describe('build-schema', () => {
308336
});
309337
});
310338

311-
it('properly converts properties with recursive arrays', () => {
339+
it('throws for nested array property when json schema is missing', () => {
312340
@model()
313341
class RecursiveArray {
314342
@property.array(Array)
315343
recArr: string[][];
316344
}
317345

318-
const jsonSchema = modelToJsonSchema(RecursiveArray);
319-
expect(jsonSchema.properties).to.eql({
320-
recArr: {
321-
type: 'array',
322-
items: {
323-
type: 'array',
324-
},
346+
expect.throws(
347+
() => {
348+
modelToJsonSchema(RecursiveArray);
325349
},
326-
});
350+
Error,
351+
'You must provide the "jsonSchema" field when define a nested array property',
352+
);
327353
});
328354

329355
it('supports explicit primitive type decoration via strings', () => {

packages/repository-json-schema/src/__tests__/unit/build-schema.unit.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,6 @@ describe('build-schema', () => {
7171
});
7272

7373
describe('metaToJsonSchema', () => {
74-
it('errors out if "itemType" is an array', () => {
75-
expect(() => metaToJsonProperty({type: Array, itemType: []})).to.throw(
76-
/itemType as an array is not supported/,
77-
);
78-
});
79-
8074
it('converts Boolean', () => {
8175
expect(metaToJsonProperty({type: Boolean})).to.eql({
8276
type: 'boolean',

packages/repository-json-schema/src/build-schema.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
ModelMetadataHelper,
1111
Null,
1212
PropertyDefinition,
13+
PropertyType,
1314
RelationMetadata,
1415
resolveType,
1516
} from '@loopback/repository';
@@ -242,7 +243,7 @@ export function stringTypeToWrapper(type: string | Function): Function {
242243
* Determines whether a given string or constructor is array type or not
243244
* @param type - Type as string or wrapper
244245
*/
245-
export function isArrayType(type: string | Function) {
246+
export function isArrayType(type: string | Function | PropertyType) {
246247
return type === Array || type === 'array';
247248
}
248249

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

258259
if (isArrayType(propertyType) && meta.itemType) {
259-
if (Array.isArray(meta.itemType)) {
260-
throw new Error('itemType as an array is not supported');
260+
if (isArrayType(meta.itemType) && !meta.jsonSchema) {
261+
throw new Error(
262+
'You must provide the "jsonSchema" field when define ' +
263+
'a nested array property',
264+
);
261265
}
262266
result = {type: 'array', items: propDef};
263267
propertyType = meta.itemType as string | Function;

0 commit comments

Comments
 (0)