@squiz/dx-json-schema-lib 1.12.0-alpha.8 → 1.12.1-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.npm/_logs/2023-02-27T04_50_27_819Z-debug-0.log +39 -0
- package/jest.config.ts +0 -6
- package/lib/JsonValidationService.d.ts +35 -0
- package/lib/JsonValidationService.js +127 -1
- package/lib/JsonValidationService.js.map +1 -1
- package/lib/JsonValidationService.spec.js +288 -0
- package/lib/JsonValidationService.spec.js.map +1 -1
- package/lib/errors/JsonResolutionError.d.ts +5 -0
- package/lib/errors/JsonResolutionError.js +12 -0
- package/lib/errors/JsonResolutionError.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/jsonTypeResolution/arbitraryTypeResolution.d.ts +61 -0
- package/lib/jsonTypeResolution/arbitraryTypeResolution.js +61 -0
- package/lib/jsonTypeResolution/arbitraryTypeResolution.js.map +1 -0
- package/lib/jsonTypeResolution/arbitraryTypeResolution.spec.d.ts +1 -0
- package/lib/jsonTypeResolution/arbitraryTypeResolution.spec.js +100 -0
- package/lib/jsonTypeResolution/arbitraryTypeResolution.spec.js.map +1 -0
- package/lib/jsonTypeResolution/index.d.ts +76 -0
- package/lib/jsonTypeResolution/index.js +35 -0
- package/lib/jsonTypeResolution/index.js.map +1 -0
- package/lib/jsonTypeResolution/primitiveTypes.d.ts +10 -0
- package/lib/jsonTypeResolution/primitiveTypes.js +27 -0
- package/lib/jsonTypeResolution/primitiveTypes.js.map +1 -0
- package/lib/jsonTypeResolution/resolvableTypes.d.ts +12 -0
- package/lib/jsonTypeResolution/resolvableTypes.js +30 -0
- package/lib/jsonTypeResolution/resolvableTypes.js.map +1 -0
- package/lib/manifest/v1/v1.json +4 -3
- package/lib/manifest/v1/v1.spec.js +58 -0
- package/lib/manifest/v1/v1.spec.js.map +1 -1
- package/package.json +5 -4
- package/src/JsonValidationService.spec.ts +417 -1
- package/src/JsonValidationService.ts +154 -1
- package/src/errors/JsonResolutionError.ts +5 -0
- package/src/index.ts +3 -0
- package/src/jsonTypeResolution/arbitraryTypeResolution.spec.ts +134 -0
- package/src/jsonTypeResolution/arbitraryTypeResolution.ts +100 -0
- package/src/jsonTypeResolution/index.ts +16 -0
- package/src/jsonTypeResolution/primitiveTypes.ts +32 -0
- package/src/jsonTypeResolution/resolvableTypes.ts +37 -0
- package/src/manifest/v1/v1.json +4 -3
- package/src/manifest/v1/v1.spec.ts +96 -0
- package/tsconfig.tsbuildinfo +1 -1
@@ -4,6 +4,7 @@ const promises_1 = require("fs/promises");
|
|
4
4
|
const path_1 = require("path");
|
5
5
|
const SchemaValidationError_1 = require("../../errors/SchemaValidationError");
|
6
6
|
const JsonValidationService_1 = require("../../JsonValidationService");
|
7
|
+
const NAME_PATTERN = '^[a-z][a-z0-9_\\-]+$';
|
7
8
|
async function fetchTestManifest(filename) {
|
8
9
|
const contents = await (0, promises_1.readFile)((0, path_1.resolve)(__dirname, '__test__', 'schemas', filename), {
|
9
10
|
encoding: 'utf-8',
|
@@ -50,5 +51,62 @@ describe('manifest/v1', () => {
|
|
50
51
|
validationService.validateManifest(manifest, 'v1');
|
51
52
|
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: Expected value at `#/functions/0/input/type` to be `object`, but value given is `string`');
|
52
53
|
});
|
54
|
+
describe.each(['_my-name', '-my-name', 'MyName', 'myName', '0my-name'])('fails name-pattern validation for %s', (propertyValue) => {
|
55
|
+
it.each(['namespace', 'name'])(`fails validation for manifests with %s of %s`, async (propertyName) => {
|
56
|
+
const manifest = await fetchTestManifest('validComponent.json');
|
57
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
58
|
+
validationService.validateManifest({
|
59
|
+
...manifest,
|
60
|
+
[propertyName]: propertyValue,
|
61
|
+
}, 'v1');
|
62
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: Value in \`#/${propertyName}\` should match \`${NAME_PATTERN}\`, but received \`${propertyValue}\``);
|
63
|
+
});
|
64
|
+
it('fails validation for manifests with function names of %s', async () => {
|
65
|
+
const manifest = await fetchTestManifest('validComponent.json');
|
66
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
67
|
+
validationService.validateManifest({
|
68
|
+
...manifest,
|
69
|
+
functions: [
|
70
|
+
{
|
71
|
+
name: propertyValue,
|
72
|
+
entry: 'main.js',
|
73
|
+
input: {},
|
74
|
+
output: {
|
75
|
+
responseType: 'html',
|
76
|
+
},
|
77
|
+
},
|
78
|
+
],
|
79
|
+
}, 'v1');
|
80
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: Value in \`#/functions/0/name\` should match \`${NAME_PATTERN}\`, but received \`${propertyValue}\``);
|
81
|
+
});
|
82
|
+
});
|
83
|
+
it('should allow uppercase letters in property names withe previews', async () => {
|
84
|
+
const manifest = await fetchTestManifest('validComponent.json');
|
85
|
+
expect(validationService.validateManifest({
|
86
|
+
...manifest,
|
87
|
+
previews: {
|
88
|
+
ValidPreview: {
|
89
|
+
functionData: {
|
90
|
+
main: {},
|
91
|
+
},
|
92
|
+
},
|
93
|
+
},
|
94
|
+
}, 'v1')).toEqual(true);
|
95
|
+
});
|
96
|
+
it('errors for non-alphanumeric characters in preview keys', async () => {
|
97
|
+
const manifest = await fetchTestManifest('validComponent.json');
|
98
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
99
|
+
validationService.validateManifest({
|
100
|
+
...manifest,
|
101
|
+
previews: {
|
102
|
+
'Bad-@@@Preview': {
|
103
|
+
functionData: {
|
104
|
+
main: {},
|
105
|
+
},
|
106
|
+
},
|
107
|
+
},
|
108
|
+
}, 'v1');
|
109
|
+
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: Invalid property name `Bad-@@@Preview` at `#/previews`');
|
110
|
+
});
|
53
111
|
});
|
54
112
|
//# sourceMappingURL=v1.spec.js.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"v1.spec.js","sourceRoot":"","sources":["../../../src/manifest/v1/v1.spec.ts"],"names":[],"mappings":";;AAAA,0CAAuC;AACvC,+BAA+B;AAC/B,8EAA2E;AAC3E,uEAAoE;AAEpE,KAAK,UAAU,iBAAiB,CAAC,QAAgB;IAC/C,MAAM,QAAQ,GAAG,MAAM,IAAA,mBAAQ,EAAC,IAAA,cAAO,EAAC,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,CAAC,EAAE;QACnF,QAAQ,EAAE,OAAO;KAClB,CAAC,CAAC;IACH,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;AAC9B,CAAC;AACD,wDAAwD;AACxD,SAAS,wCAAwC,CAAC,QAAkB,EAAE,SAAmB,EAAE,OAAe;IACxG,IAAI,KAAK,GAAiB,IAAI,CAAC;IAE/B,IAAI;QACF,QAAQ,EAAE,CAAC;KACZ;IAAC,OAAO,CAAM,EAAE;QACf,KAAK,GAAG,CAAC,CAAC;KACX;IAED,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAC5B,MAAM,CAAC,KAAK,aAAL,KAAK,uBAAL,KAAK,CAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,CAAC,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;AAC1C,CAAC;AAED,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAI,iBAAwC,CAAC;IAE7C,SAAS,CAAC,GAAG,EAAE;QACb,iBAAiB,GAAG,IAAI,6CAAqB,EAAE,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8BAA8B,EAAE,KAAK,IAAI,EAAE;QAC5C,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,qBAAqB,CAAC,CAAC;QAChE,MAAM,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC;IAC1E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,gCAAgC,CAAC,CAAC;QAE3E,wCAAwC,CACtC,GAAG,EAAE;YACH,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC,EACD,6CAAqB,EACrB,sHAAsH,CACvH,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2DAA2D,EAAE,KAAK,IAAI,EAAE;QACzE,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,6BAA6B,CAAC,CAAC;QAExE,wCAAwC,CACtC,GAAG,EAAE;YACH,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC,EACD,6CAAqB,EACrB,+HAA+H,CAChI,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,sCAAsC,CAAC,CAAC;QACjF,wCAAwC,CACtC,GAAG,EAAE;YACH,iBAAiB,CAAC,gBAAgB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACrD,CAAC,EACD,6CAAqB,EACrB,6GAA6G,CAC9G,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
1
|
+
{"version":3,"file":"v1.spec.js","sourceRoot":"","sources":["../../../src/manifest/v1/v1.spec.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@squiz/dx-json-schema-lib",
|
3
|
-
"version": "1.12.
|
3
|
+
"version": "1.12.1-alpha.0",
|
4
4
|
"description": "",
|
5
5
|
"main": "lib/index.js",
|
6
6
|
"scripts": {
|
@@ -20,14 +20,15 @@
|
|
20
20
|
"jest": "29.4.1",
|
21
21
|
"json-schema-to-typescript": "11.0.3",
|
22
22
|
"rimraf": "4.1.2",
|
23
|
-
"ts-jest": "
|
23
|
+
"ts-jest": "29.0.5",
|
24
24
|
"ts-loader": "9.3.1",
|
25
25
|
"ts-node": "10.9.1",
|
26
26
|
"typescript": "4.9.4"
|
27
27
|
},
|
28
28
|
"dependencies": {
|
29
29
|
"@sagold/json-query": "6.0.0",
|
30
|
-
"json-schema-library": "7.4.5"
|
30
|
+
"json-schema-library": "7.4.5",
|
31
|
+
"ts-brand": "0.0.2"
|
31
32
|
},
|
32
|
-
"gitHead": "
|
33
|
+
"gitHead": "4a0c81e76ca50706d137dee82869e3ea7844376e"
|
33
34
|
}
|
@@ -1,9 +1,11 @@
|
|
1
|
-
import { JsonValidationService } from './JsonValidationService';
|
1
|
+
import { ComponentInputMetaSchema, JSONSchemaService, JsonValidationService } from './JsonValidationService';
|
2
2
|
import { SchemaValidationError } from './errors/SchemaValidationError';
|
3
3
|
|
4
4
|
import validManifest from './manifest/v1/__test__/schemas/validComponent.json';
|
5
5
|
import validManifestJson from './manifest/v1/__test__/schemas/validComponentJson.json';
|
6
6
|
import { FormattedText } from './formatted-text/v1/formattedText';
|
7
|
+
import { JSONSchema } from 'json-schema-library';
|
8
|
+
import { PrimitiveType, ResolvableType, TypeResolver } from './jsonTypeResolution/arbitraryTypeResolution';
|
7
9
|
|
8
10
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
9
11
|
function expectToThrowErrorMatchingTypeAndMessage(received: Function, errorType: Function, message: string) {
|
@@ -448,6 +450,60 @@ describe('JsonValidationService', () => {
|
|
448
450
|
'failed validation: Expected `[object Object]` (object) in `#/my-input` to be of type `array`',
|
449
451
|
);
|
450
452
|
});
|
453
|
+
|
454
|
+
it('should validate a FormattedText value when the schema is a $ref to a $ref', async () => {
|
455
|
+
const formattedText: FormattedText = [
|
456
|
+
{
|
457
|
+
tag: 'p',
|
458
|
+
type: 'tag',
|
459
|
+
children: [{ type: 'text', value: 'hello' }],
|
460
|
+
},
|
461
|
+
];
|
462
|
+
|
463
|
+
const schema = {
|
464
|
+
type: 'object',
|
465
|
+
properties: {
|
466
|
+
'my-input': { $ref: '#/definitions/FormattedText' },
|
467
|
+
},
|
468
|
+
definitions: {
|
469
|
+
FormattedText: { $ref: '#/definitions/FormattedText2' },
|
470
|
+
FormattedText2: { type: 'FormattedText' },
|
471
|
+
},
|
472
|
+
required: ['my-input'],
|
473
|
+
};
|
474
|
+
const value = {
|
475
|
+
'my-input': formattedText,
|
476
|
+
};
|
477
|
+
|
478
|
+
expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
|
479
|
+
});
|
480
|
+
|
481
|
+
it('should validate a FormattedText value when the schema is in an if/then/else', async () => {
|
482
|
+
const formattedText: FormattedText = [
|
483
|
+
{
|
484
|
+
tag: 'p',
|
485
|
+
type: 'tag',
|
486
|
+
children: [{ type: 'text', value: 'hello' }],
|
487
|
+
},
|
488
|
+
];
|
489
|
+
|
490
|
+
const schema = {
|
491
|
+
type: 'object',
|
492
|
+
properties: {
|
493
|
+
'my-input': {
|
494
|
+
if: { type: 'string' },
|
495
|
+
then: { type: 'string' },
|
496
|
+
else: { type: 'FormattedText' },
|
497
|
+
},
|
498
|
+
},
|
499
|
+
required: ['my-input'],
|
500
|
+
};
|
501
|
+
const value = {
|
502
|
+
'my-input': formattedText,
|
503
|
+
};
|
504
|
+
|
505
|
+
expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
|
506
|
+
});
|
451
507
|
});
|
452
508
|
|
453
509
|
describe('standard inputs', () => {
|
@@ -518,4 +574,364 @@ describe('JsonValidationService', () => {
|
|
518
574
|
});
|
519
575
|
});
|
520
576
|
});
|
577
|
+
|
578
|
+
describe('validateRenderInput', () => {
|
579
|
+
it('should validate a property with type FormattedText as string', () => {
|
580
|
+
const schema = {
|
581
|
+
type: 'object',
|
582
|
+
properties: {
|
583
|
+
'my-input': { type: 'FormattedText' },
|
584
|
+
},
|
585
|
+
required: ['my-input'],
|
586
|
+
};
|
587
|
+
const value = {
|
588
|
+
'my-input': 'hello',
|
589
|
+
};
|
590
|
+
|
591
|
+
expect(jsonValidationService.validateRenderInput(schema, value)).toEqual(true);
|
592
|
+
});
|
593
|
+
|
594
|
+
it('should error when a property with type FormattedText is provided a valid FormattedText value', () => {
|
595
|
+
const schema = {
|
596
|
+
type: 'object',
|
597
|
+
properties: {
|
598
|
+
'my-input': { type: 'FormattedText' },
|
599
|
+
},
|
600
|
+
required: ['my-input'],
|
601
|
+
};
|
602
|
+
const value = {
|
603
|
+
'my-input': [{ type: 'text', value: 'hello' }],
|
604
|
+
};
|
605
|
+
|
606
|
+
expectToThrowErrorMatchingTypeAndMessage(
|
607
|
+
() => {
|
608
|
+
jsonValidationService.validateRenderInput(schema, value);
|
609
|
+
},
|
610
|
+
SchemaValidationError,
|
611
|
+
'failed validation: Expected `[object Object]` (array) in `#/my-input` to be of type `string`',
|
612
|
+
);
|
613
|
+
});
|
614
|
+
|
615
|
+
it('should validate a property with type FormattedText within an if/then/else as string', () => {
|
616
|
+
const schema = {
|
617
|
+
type: 'object',
|
618
|
+
properties: {
|
619
|
+
'my-input': {
|
620
|
+
type: 'object',
|
621
|
+
properties: {
|
622
|
+
prop: { type: 'string' },
|
623
|
+
},
|
624
|
+
required: ['prop'],
|
625
|
+
if: { properties: { prop: { const: 'a' } } },
|
626
|
+
then: {
|
627
|
+
properties: {
|
628
|
+
text: { type: 'FormattedText' },
|
629
|
+
},
|
630
|
+
required: ['text'],
|
631
|
+
},
|
632
|
+
else: {
|
633
|
+
properties: {
|
634
|
+
text: { type: 'array', items: { type: 'FormattedText' } },
|
635
|
+
},
|
636
|
+
required: ['text'],
|
637
|
+
},
|
638
|
+
},
|
639
|
+
},
|
640
|
+
required: ['my-input'],
|
641
|
+
};
|
642
|
+
const value = {
|
643
|
+
'my-input': {
|
644
|
+
prop: 'a',
|
645
|
+
text: 'hello',
|
646
|
+
},
|
647
|
+
};
|
648
|
+
|
649
|
+
expect(jsonValidationService.validateRenderInput(schema, value)).toEqual(true);
|
650
|
+
|
651
|
+
const otherValue = {
|
652
|
+
'my-input': {
|
653
|
+
prop: 'b',
|
654
|
+
text: ['my', 'formatted', 'text'],
|
655
|
+
},
|
656
|
+
};
|
657
|
+
expect(jsonValidationService.validateRenderInput(schema, otherValue)).toEqual(true);
|
658
|
+
});
|
659
|
+
});
|
660
|
+
});
|
661
|
+
|
662
|
+
const defaultSchema: JSONSchema = {
|
663
|
+
type: 'object',
|
664
|
+
properties: {
|
665
|
+
myProperty: {
|
666
|
+
type: 'string',
|
667
|
+
},
|
668
|
+
},
|
669
|
+
required: ['myProperty'],
|
670
|
+
};
|
671
|
+
function primitiveTypeFixture<T extends string>(title: T, schema: JSONSchema = defaultSchema) {
|
672
|
+
return PrimitiveType({
|
673
|
+
...schema,
|
674
|
+
title,
|
675
|
+
});
|
676
|
+
}
|
677
|
+
|
678
|
+
function resolvableTypeFixture<T extends string>(title: T, schema: JSONSchema = defaultSchema) {
|
679
|
+
return ResolvableType({
|
680
|
+
...schema,
|
681
|
+
title,
|
682
|
+
});
|
683
|
+
}
|
684
|
+
|
685
|
+
describe('JsonSchemaService', () => {
|
686
|
+
describe('validateInput', () => {
|
687
|
+
it.each([String('123'), Number(123), [123]])(
|
688
|
+
'should validate any primitive type with its resolvable type %s',
|
689
|
+
(propertyValue) => {
|
690
|
+
const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
|
691
|
+
const jsonSchemaService = new JSONSchemaService(
|
692
|
+
new TypeResolver(
|
693
|
+
{
|
694
|
+
MyPrimitive: primitiveSchema,
|
695
|
+
},
|
696
|
+
{
|
697
|
+
MyResolvableNumber: resolvableTypeFixture('MyResolvableNumber', { type: 'number' }),
|
698
|
+
MyResolvableArray: resolvableTypeFixture('MyResolvableArray', { type: 'array' }),
|
699
|
+
},
|
700
|
+
{
|
701
|
+
MyPrimitive: {
|
702
|
+
MyResolvableNumber: (value: number) => value.toString(),
|
703
|
+
MyResolvableArray: (value: any[]) => value.join(''),
|
704
|
+
},
|
705
|
+
},
|
706
|
+
),
|
707
|
+
ComponentInputMetaSchema,
|
708
|
+
);
|
709
|
+
|
710
|
+
expect(
|
711
|
+
jsonSchemaService.validateInput(
|
712
|
+
{ myProperty: propertyValue },
|
713
|
+
{ type: 'object', properties: { myProperty: { type: 'MyPrimitive' } } },
|
714
|
+
),
|
715
|
+
).toEqual(true);
|
716
|
+
},
|
717
|
+
);
|
718
|
+
|
719
|
+
it('should error when a primitive type is provided a value that cannot be resolved by its resolvable types', () => {
|
720
|
+
const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
|
721
|
+
const jsonSchemaService = new JSONSchemaService(
|
722
|
+
new TypeResolver(
|
723
|
+
{
|
724
|
+
MyPrimitive: primitiveSchema,
|
725
|
+
},
|
726
|
+
{
|
727
|
+
MyResolvableNumber: resolvableTypeFixture('MyResolvableNumber', { type: 'number' }),
|
728
|
+
MyResolvableArray: resolvableTypeFixture('MyResolvableArray', { type: 'array' }),
|
729
|
+
},
|
730
|
+
{
|
731
|
+
MyPrimitive: {
|
732
|
+
MyResolvableNumber: (value: number) => value.toString(),
|
733
|
+
MyResolvableArray: (value: any[]) => value.join(''),
|
734
|
+
},
|
735
|
+
},
|
736
|
+
),
|
737
|
+
ComponentInputMetaSchema,
|
738
|
+
);
|
739
|
+
|
740
|
+
expect(() => {
|
741
|
+
jsonSchemaService.validateInput(
|
742
|
+
{ myProperty: true },
|
743
|
+
{ type: 'object', properties: { myProperty: { type: 'MyPrimitive' } } },
|
744
|
+
);
|
745
|
+
}).toThrowError();
|
746
|
+
});
|
747
|
+
|
748
|
+
it.each([String('123'), Number(123), [123]])(
|
749
|
+
'should validate a primitive type when defined as a ref with resolvable value %s',
|
750
|
+
(propertyValue) => {
|
751
|
+
const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
|
752
|
+
const jsonSchemaService = new JSONSchemaService(
|
753
|
+
new TypeResolver(
|
754
|
+
{
|
755
|
+
MyPrimitive: primitiveSchema,
|
756
|
+
},
|
757
|
+
{
|
758
|
+
MyResolvableNumber: resolvableTypeFixture('MyResolvableNumber', { type: 'number' }),
|
759
|
+
MyResolvableArray: resolvableTypeFixture('MyResolvableArray', { type: 'array' }),
|
760
|
+
},
|
761
|
+
{
|
762
|
+
MyPrimitive: {
|
763
|
+
MyResolvableNumber: (value: number) => value.toString(),
|
764
|
+
MyResolvableArray: (value: any[]) => value.join(''),
|
765
|
+
},
|
766
|
+
},
|
767
|
+
),
|
768
|
+
ComponentInputMetaSchema,
|
769
|
+
);
|
770
|
+
|
771
|
+
expect(
|
772
|
+
jsonSchemaService.validateInput(
|
773
|
+
{ myProperty: propertyValue },
|
774
|
+
{
|
775
|
+
type: 'object',
|
776
|
+
properties: { myProperty: { $ref: '#/definitions/Ref' } },
|
777
|
+
definitions: { Ref: { type: 'MyPrimitive' } },
|
778
|
+
},
|
779
|
+
),
|
780
|
+
).toEqual(true);
|
781
|
+
},
|
782
|
+
);
|
783
|
+
|
784
|
+
it('should not validate on a primitive type against a resolvable type when a resolver is not defined', () => {
|
785
|
+
const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
|
786
|
+
const jsonSchemaService = new JSONSchemaService(
|
787
|
+
new TypeResolver(
|
788
|
+
{
|
789
|
+
MyPrimitive: primitiveSchema,
|
790
|
+
},
|
791
|
+
{
|
792
|
+
MyResolvableNumber: resolvableTypeFixture('MyResolvableNumber', { type: 'number' }),
|
793
|
+
MyResolvableArray: resolvableTypeFixture('MyResolvableArray', { type: 'array' }),
|
794
|
+
},
|
795
|
+
{
|
796
|
+
MyPrimitive: {
|
797
|
+
MyResolvableNumber: (value: number) => value.toString(),
|
798
|
+
},
|
799
|
+
},
|
800
|
+
),
|
801
|
+
ComponentInputMetaSchema,
|
802
|
+
);
|
803
|
+
|
804
|
+
expect(() => {
|
805
|
+
jsonSchemaService.validateInput(
|
806
|
+
{ myProperty: [123] },
|
807
|
+
{ type: 'object', properties: { myProperty: { type: 'MyPrimitive' } } },
|
808
|
+
);
|
809
|
+
}).toThrowError();
|
810
|
+
});
|
811
|
+
|
812
|
+
it('should validate a primitive type against similar but different resolvable types', () => {
|
813
|
+
const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
|
814
|
+
const jsonSchemaService = new JSONSchemaService(
|
815
|
+
new TypeResolver(
|
816
|
+
{
|
817
|
+
MyPrimitive: primitiveSchema,
|
818
|
+
},
|
819
|
+
{
|
820
|
+
MyResolvableSrcNumber: resolvableTypeFixture('MyResolvableSrcNumber', {
|
821
|
+
type: 'object',
|
822
|
+
properties: {
|
823
|
+
src: { type: 'number' },
|
824
|
+
},
|
825
|
+
}),
|
826
|
+
MyResolvableSrcString: resolvableTypeFixture('MyResolvableSrcString', {
|
827
|
+
type: 'object',
|
828
|
+
properties: {
|
829
|
+
src: { type: 'string' },
|
830
|
+
},
|
831
|
+
}),
|
832
|
+
},
|
833
|
+
{
|
834
|
+
MyPrimitive: {
|
835
|
+
MyResolvableSrcNumber: (value: { src: number }) => value.src.toString(),
|
836
|
+
MyResolvableSrcString: (value: { src: string }) => value.src,
|
837
|
+
},
|
838
|
+
},
|
839
|
+
),
|
840
|
+
ComponentInputMetaSchema,
|
841
|
+
);
|
842
|
+
|
843
|
+
expect(
|
844
|
+
jsonSchemaService.validateInput(
|
845
|
+
{
|
846
|
+
myProperty: {
|
847
|
+
src: 123,
|
848
|
+
},
|
849
|
+
},
|
850
|
+
{ type: 'object', properties: { myProperty: { type: 'MyPrimitive' } } },
|
851
|
+
),
|
852
|
+
).toEqual(true);
|
853
|
+
expect(
|
854
|
+
jsonSchemaService.validateInput(
|
855
|
+
{
|
856
|
+
myProperty: {
|
857
|
+
src: '123',
|
858
|
+
},
|
859
|
+
},
|
860
|
+
{ type: 'object', properties: { myProperty: { type: 'MyPrimitive' } } },
|
861
|
+
),
|
862
|
+
).toEqual(true);
|
863
|
+
});
|
864
|
+
});
|
865
|
+
|
866
|
+
describe('resolveInput', () => {
|
867
|
+
it.each([String('123'), Number(123), [123]])(
|
868
|
+
'should resolve a primitive type from its resolvable type %s',
|
869
|
+
async (resolvableValue) => {
|
870
|
+
const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
|
871
|
+
const jsonSchemaService = new JSONSchemaService(
|
872
|
+
new TypeResolver(
|
873
|
+
{
|
874
|
+
MyPrimitive: primitiveSchema,
|
875
|
+
},
|
876
|
+
{
|
877
|
+
MyResolvableNumber: resolvableTypeFixture('MyResolvableNumber', { type: 'number' }),
|
878
|
+
MyResolvableArray: resolvableTypeFixture('MyResolvableArray', { type: 'array' }),
|
879
|
+
},
|
880
|
+
{
|
881
|
+
MyPrimitive: {
|
882
|
+
MyResolvableNumber: (value: number) => value.toString(),
|
883
|
+
MyResolvableArray: (value: any[]) => value.join(''),
|
884
|
+
},
|
885
|
+
},
|
886
|
+
),
|
887
|
+
ComponentInputMetaSchema,
|
888
|
+
);
|
889
|
+
|
890
|
+
await expect(
|
891
|
+
jsonSchemaService.resolveInput(
|
892
|
+
{ myProperty: resolvableValue },
|
893
|
+
{ type: 'object', properties: { myProperty: { type: 'MyPrimitive' } } },
|
894
|
+
),
|
895
|
+
).resolves.toEqual({ myProperty: '123' });
|
896
|
+
},
|
897
|
+
);
|
898
|
+
|
899
|
+
it.each([
|
900
|
+
[{ src: 'MyString' }, 'MyString'],
|
901
|
+
[{ src: 1132 }, '1132'],
|
902
|
+
])('should resolve a resolvable type %s against the correct resolver to %s', async (resolvableValue, output) => {
|
903
|
+
const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
|
904
|
+
const jsonSchemaService = new JSONSchemaService(
|
905
|
+
new TypeResolver(
|
906
|
+
{
|
907
|
+
MyPrimitive: primitiveSchema,
|
908
|
+
},
|
909
|
+
{
|
910
|
+
MyResolvableSrcString: resolvableTypeFixture('MyResolvableSrcString', {
|
911
|
+
type: 'object',
|
912
|
+
properties: { src: { type: 'string' } },
|
913
|
+
}),
|
914
|
+
MyResolvableSrcNumber: resolvableTypeFixture('MyResolvableSrcNumber', {
|
915
|
+
type: 'object',
|
916
|
+
properties: { src: { type: 'number' } },
|
917
|
+
}),
|
918
|
+
},
|
919
|
+
{
|
920
|
+
MyPrimitive: {
|
921
|
+
MyResolvableSrcNumber: (value: { src: number }) => value.src.toString(),
|
922
|
+
MyResolvableSrcString: (value: { src: string }) => value.src,
|
923
|
+
},
|
924
|
+
},
|
925
|
+
),
|
926
|
+
ComponentInputMetaSchema,
|
927
|
+
);
|
928
|
+
|
929
|
+
await expect(
|
930
|
+
jsonSchemaService.resolveInput(
|
931
|
+
{ myProperty: resolvableValue },
|
932
|
+
{ type: 'object', properties: { myProperty: { type: 'MyPrimitive' } } },
|
933
|
+
),
|
934
|
+
).resolves.toEqual({ myProperty: output });
|
935
|
+
});
|
936
|
+
});
|
521
937
|
});
|