@squiz/dx-json-schema-lib 1.21.1-alpha.2 → 1.21.1-alpha.20

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. package/.npm/_logs/2023-03-16T10_16_41_384Z-debug-0.log +37 -0
  2. package/lib/JsonValidationService.d.ts +1 -1
  3. package/lib/JsonValidationService.js +23 -5
  4. package/lib/JsonValidationService.js.map +1 -1
  5. package/lib/JsonValidationService.spec.js +469 -426
  6. package/lib/JsonValidationService.spec.js.map +1 -1
  7. package/lib/index.d.ts +6 -1
  8. package/lib/index.js +6 -1
  9. package/lib/index.js.map +1 -1
  10. package/lib/jsonTypeResolution/{arbitraryTypeResolution.d.ts → TypeResolver.d.ts} +7 -12
  11. package/lib/jsonTypeResolution/{arbitraryTypeResolution.js → TypeResolver.js} +17 -17
  12. package/lib/jsonTypeResolution/TypeResolver.js.map +1 -0
  13. package/lib/jsonTypeResolution/{arbitraryTypeResolution.spec.js → TypeResolver.spec.js} +12 -39
  14. package/lib/jsonTypeResolution/TypeResolver.spec.js.map +1 -0
  15. package/lib/jsonTypeResolution/TypeResolverBuilder.d.ts +12 -0
  16. package/lib/jsonTypeResolution/TypeResolverBuilder.js +32 -0
  17. package/lib/jsonTypeResolution/TypeResolverBuilder.js.map +1 -0
  18. package/lib/manifest/v1/DxContentMetaSchema.json +117 -2
  19. package/lib/manifest/v1/MatrixAssetSchema.json +390 -0
  20. package/lib/manifest/v1/__test__/schemas/inputStringWithFormat.json +29 -0
  21. package/lib/manifest/v1/subSchemas.d.ts +2 -1
  22. package/lib/manifest/v1/subSchemas.js +3 -1
  23. package/lib/manifest/v1/subSchemas.js.map +1 -1
  24. package/lib/manifest/v1/v1.d.ts +405 -4
  25. package/lib/manifest/v1/v1.json +48 -0
  26. package/lib/primitiveTypes/FormattedText.d.ts +8 -0
  27. package/lib/primitiveTypes/FormattedText.js +21 -0
  28. package/lib/primitiveTypes/FormattedText.js.map +1 -0
  29. package/lib/primitiveTypes/SquizImage.d.ts +26 -0
  30. package/lib/primitiveTypes/SquizImage.js +105 -0
  31. package/lib/primitiveTypes/SquizImage.js.map +1 -0
  32. package/lib/primitiveTypes/index.d.ts +2 -0
  33. package/lib/primitiveTypes/index.js +19 -0
  34. package/lib/primitiveTypes/index.js.map +1 -0
  35. package/lib/resolvableTypes/MatrixAsset.d.ts +9 -0
  36. package/lib/resolvableTypes/MatrixAsset.js +21 -0
  37. package/lib/resolvableTypes/MatrixAsset.js.map +1 -0
  38. package/lib/resolvableTypes/index.d.ts +1 -0
  39. package/lib/resolvableTypes/index.js +18 -0
  40. package/lib/resolvableTypes/index.js.map +1 -0
  41. package/lib/validators/customFormatValidators.d.ts +2 -0
  42. package/lib/validators/customFormatValidators.js +14 -0
  43. package/lib/validators/customFormatValidators.js.map +1 -0
  44. package/lib/validators/utils/matrixAssetValidator.d.ts +2 -0
  45. package/lib/validators/utils/matrixAssetValidator.js +11 -0
  46. package/lib/validators/utils/matrixAssetValidator.js.map +1 -0
  47. package/lib/validators/utils/matrixAssetValidator.spec.d.ts +1 -0
  48. package/lib/validators/utils/matrixAssetValidator.spec.js +43 -0
  49. package/lib/validators/utils/matrixAssetValidator.spec.js.map +1 -0
  50. package/package.json +5 -4
  51. package/src/JsonValidationService.spec.ts +596 -533
  52. package/src/JsonValidationService.ts +28 -10
  53. package/src/index.ts +8 -1
  54. package/src/jsonTypeResolution/{arbitraryTypeResolution.spec.ts → TypeResolver.spec.ts} +23 -70
  55. package/src/jsonTypeResolution/{arbitraryTypeResolution.ts → TypeResolver.ts} +27 -23
  56. package/src/jsonTypeResolution/TypeResolverBuilder.ts +43 -0
  57. package/src/manifest/v1/DxContentMetaSchema.json +117 -2
  58. package/src/manifest/v1/MatrixAssetSchema.json +391 -0
  59. package/src/manifest/v1/__test__/schemas/inputStringWithFormat.json +29 -0
  60. package/src/manifest/v1/subSchemas.ts +2 -1
  61. package/src/manifest/v1/v1.json +48 -0
  62. package/src/manifest/v1/v1.ts +657 -6
  63. package/src/primitiveTypes/FormattedText.ts +24 -0
  64. package/src/primitiveTypes/SquizImage.ts +128 -0
  65. package/src/primitiveTypes/index.ts +2 -0
  66. package/src/resolvableTypes/MatrixAsset.ts +24 -0
  67. package/src/resolvableTypes/index.ts +1 -0
  68. package/src/validators/customFormatValidators.ts +15 -0
  69. package/src/validators/utils/matrixAssetValidator.spec.ts +49 -0
  70. package/src/validators/utils/matrixAssetValidator.ts +8 -0
  71. package/tsconfig.tsbuildinfo +1 -1
  72. package/.npm/_logs/2023-03-02T03_26_09_372Z-debug-0.log +0 -39
  73. package/lib/jsonTypeResolution/arbitraryTypeResolution.js.map +0 -1
  74. package/lib/jsonTypeResolution/arbitraryTypeResolution.spec.js.map +0 -1
  75. package/lib/jsonTypeResolution/index.d.ts +0 -76
  76. package/lib/jsonTypeResolution/index.js +0 -35
  77. package/lib/jsonTypeResolution/index.js.map +0 -1
  78. package/lib/jsonTypeResolution/primitiveTypes.d.ts +0 -10
  79. package/lib/jsonTypeResolution/primitiveTypes.js +0 -27
  80. package/lib/jsonTypeResolution/primitiveTypes.js.map +0 -1
  81. package/lib/jsonTypeResolution/resolvableTypes.d.ts +0 -12
  82. package/lib/jsonTypeResolution/resolvableTypes.js +0 -30
  83. package/lib/jsonTypeResolution/resolvableTypes.js.map +0 -1
  84. package/src/jsonTypeResolution/index.ts +0 -16
  85. package/src/jsonTypeResolution/primitiveTypes.ts +0 -32
  86. package/src/jsonTypeResolution/resolvableTypes.ts +0 -37
  87. /package/lib/jsonTypeResolution/{arbitraryTypeResolution.spec.d.ts → TypeResolver.spec.d.ts} +0 -0
@@ -4,8 +4,16 @@ import { SchemaValidationError } from './errors/SchemaValidationError';
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 inputStringWithFormat from './manifest/v1/__test__/schemas/inputStringWithFormat.json';
7
8
  import { JSONSchema } from 'json-schema-library';
8
- import { PrimitiveType, ResolvableType, TypeResolver } from './jsonTypeResolution/arbitraryTypeResolution';
9
+ import {
10
+ AnyPrimitiveType,
11
+ AnyResolvableType,
12
+ PrimitiveType,
13
+ ResolvableType,
14
+ TypeResolver,
15
+ } from './jsonTypeResolution/TypeResolver';
16
+ import { FormattedTextType } from './primitiveTypes';
9
17
 
10
18
  // eslint-disable-next-line @typescript-eslint/ban-types
11
19
  function expectToThrowErrorMatchingTypeAndMessage(received: Function, errorType: Function, message: string) {
@@ -59,8 +67,182 @@ describe('JsonValidationService', () => {
59
67
  'failed validation: Invalid manifest version',
60
68
  );
61
69
  });
70
+
71
+ it('should return true for a valid manifest with a string format MatrixAssetUri', () => {
72
+ const result = jsonValidationService.validateManifest(inputStringWithFormat, 'v1');
73
+ expect(result).toBe(true);
74
+ });
62
75
  });
63
76
 
77
+ describe('validateRenderInput', () => {
78
+ describe('matrix-asset-uri input', () => {
79
+ const functionInputSchema = {
80
+ type: 'object',
81
+
82
+ properties: {
83
+ 'matrix-asset': { type: 'string', format: 'matrix-asset-uri', matrixAssetTypes: ['image'] },
84
+ },
85
+
86
+ required: ['matrix-asset'],
87
+ };
88
+ it('should return true for valid a string with matrix-asset-uri format', () => {
89
+ const validMatrixAssetUri = 'matrix-asset://canary.uat.matrix.squiz.cloud/abc123';
90
+ expect(
91
+ jsonValidationService.validateRenderInput(functionInputSchema, {
92
+ 'matrix-asset': validMatrixAssetUri,
93
+ }),
94
+ ).toEqual(true);
95
+ });
96
+ it('should throw error for invalid matrix-asset-uri format', () => {
97
+ const invalidMatrixAssetUri = 'not-valid://canary.uat.matrix.squiz.cloud//abc123';
98
+ expectToThrowErrorMatchingTypeAndMessage(
99
+ () => {
100
+ jsonValidationService.validateRenderInput(functionInputSchema, {
101
+ 'matrix-asset': invalidMatrixAssetUri,
102
+ });
103
+ },
104
+ SchemaValidationError,
105
+ `failed validation: value "not-valid://canary.uat.matrix.squiz.cloud//abc123" isn't a valid matrix asset uri`,
106
+ );
107
+ });
108
+ it('should throw error for invalid matrix-asset-uri type number', () => {
109
+ const invalidMatrixAssetUri = 1234;
110
+ expectToThrowErrorMatchingTypeAndMessage(
111
+ () => {
112
+ jsonValidationService.validateRenderInput(functionInputSchema, {
113
+ 'matrix-asset': invalidMatrixAssetUri,
114
+ });
115
+ },
116
+ SchemaValidationError,
117
+ 'failed validation: Expected `1234` (number) in `#/matrix-asset` to be of type `string`',
118
+ );
119
+ });
120
+ it('should throw error for invalid matrix-asset-uri which does not contain correct number of parts', () => {
121
+ const invalidMatrixAssetUri = 'matrix://';
122
+ expectToThrowErrorMatchingTypeAndMessage(
123
+ () => {
124
+ jsonValidationService.validateRenderInput(functionInputSchema, {
125
+ 'matrix-asset': invalidMatrixAssetUri,
126
+ });
127
+ },
128
+ SchemaValidationError,
129
+ `failed validation: value "matrix://" isn't a valid matrix asset uri`,
130
+ );
131
+ });
132
+ });
133
+
134
+ it('should validate a property with type FormattedText as string', () => {
135
+ const schema = {
136
+ type: 'object',
137
+ properties: {
138
+ 'my-input': { type: 'FormattedText' },
139
+ },
140
+ required: ['my-input'],
141
+ };
142
+ const value = {
143
+ 'my-input': 'hello',
144
+ };
145
+
146
+ expect(jsonValidationService.validateRenderInput(schema, value)).toEqual(true);
147
+ });
148
+
149
+ it('should error when a property with type FormattedText is provided a valid FormattedText value', () => {
150
+ const schema = {
151
+ type: 'object',
152
+ properties: {
153
+ 'my-input': { type: 'FormattedText' },
154
+ },
155
+ required: ['my-input'],
156
+ };
157
+ const value = {
158
+ 'my-input': [{ type: 'text', value: 'hello' }],
159
+ };
160
+
161
+ expectToThrowErrorMatchingTypeAndMessage(
162
+ () => {
163
+ jsonValidationService.validateRenderInput(schema, value);
164
+ },
165
+ SchemaValidationError,
166
+ 'failed validation: Expected `[object Object]` (array) in `#/my-input` to be of type `string`',
167
+ );
168
+ });
169
+
170
+ it('should validate a property with type FormattedText within an if/then/else as string', () => {
171
+ const schema = {
172
+ type: 'object',
173
+ properties: {
174
+ 'my-input': {
175
+ type: 'object',
176
+ properties: {
177
+ prop: { type: 'string' },
178
+ },
179
+ required: ['prop'],
180
+ if: { properties: { prop: { const: 'a' } } },
181
+ then: {
182
+ properties: {
183
+ text: { type: 'FormattedText' },
184
+ },
185
+ required: ['text'],
186
+ },
187
+ else: {
188
+ properties: {
189
+ text: { type: 'array', items: { type: 'FormattedText' } },
190
+ },
191
+ required: ['text'],
192
+ },
193
+ },
194
+ },
195
+ required: ['my-input'],
196
+ };
197
+ const value = {
198
+ 'my-input': {
199
+ prop: 'a',
200
+ text: 'hello',
201
+ },
202
+ };
203
+
204
+ expect(jsonValidationService.validateRenderInput(schema, value)).toEqual(true);
205
+
206
+ const otherValue = {
207
+ 'my-input': {
208
+ prop: 'b',
209
+ text: ['my', 'formatted', 'text'],
210
+ },
211
+ };
212
+ expect(jsonValidationService.validateRenderInput(schema, otherValue)).toEqual(true);
213
+ });
214
+ });
215
+ });
216
+
217
+ const defaultSchema: JSONSchema = {
218
+ type: 'object',
219
+ properties: {
220
+ myProperty: {
221
+ type: 'string',
222
+ },
223
+ },
224
+ required: ['myProperty'],
225
+ };
226
+ function primitiveTypeFixture<T extends string>(title: T, schema: JSONSchema = defaultSchema) {
227
+ return PrimitiveType({
228
+ ...schema,
229
+ title,
230
+ });
231
+ }
232
+
233
+ function resolvableTypeFixture<T extends string>(title: T, schema: JSONSchema = defaultSchema) {
234
+ return ResolvableType({
235
+ ...schema,
236
+ title,
237
+ });
238
+ }
239
+
240
+ describe('JsonSchemaService', () => {
241
+ let jsonSchemaService: JSONSchemaService<AnyPrimitiveType, AnyResolvableType>;
242
+ beforeAll(() => {
243
+ const typeResolver = new TypeResolver([FormattedTextType]);
244
+ jsonSchemaService = new JSONSchemaService(typeResolver, ComponentInputMetaSchema);
245
+ });
64
246
  describe('validateContentSchema', () => {
65
247
  it('should return true for a valid content schema', () => {
66
248
  const contentSchema = {
@@ -72,7 +254,7 @@ describe('JsonValidationService', () => {
72
254
 
73
255
  required: ['my-input'],
74
256
  };
75
- const result = jsonValidationService.validateContentSchema(contentSchema);
257
+ const result = jsonSchemaService.validateInput(contentSchema);
76
258
  expect(result).toBe(true);
77
259
  });
78
260
 
@@ -94,7 +276,7 @@ describe('JsonValidationService', () => {
94
276
  };
95
277
  expectToThrowErrorMatchingTypeAndMessage(
96
278
  () => {
97
- jsonValidationService.validateContentSchema(contentSchema);
279
+ jsonSchemaService.validateInput(contentSchema);
98
280
  },
99
281
  SchemaValidationError,
100
282
  'failed validation: The required property `required` is missing at `#/properties/my-input`',
@@ -115,7 +297,7 @@ describe('JsonValidationService', () => {
115
297
  };
116
298
  expectToThrowErrorMatchingTypeAndMessage(
117
299
  () => {
118
- jsonValidationService.validateContentSchema(contentSchema);
300
+ jsonSchemaService.validateInput(contentSchema);
119
301
  },
120
302
  SchemaValidationError,
121
303
  `failed validation: Expected value at \`#/type\` to be \`object\`, but value given is \`array\``,
@@ -132,7 +314,7 @@ describe('JsonValidationService', () => {
132
314
  };
133
315
  expectToThrowErrorMatchingTypeAndMessage(
134
316
  () => {
135
- jsonValidationService.validateContentSchema(contentSchema);
317
+ jsonSchemaService.validateInput(contentSchema);
136
318
  },
137
319
  SchemaValidationError,
138
320
  'failed validation: The required property `required` is missing at `#`',
@@ -140,570 +322,467 @@ describe('JsonValidationService', () => {
140
322
  });
141
323
  });
142
324
 
143
- describe('validateComponentInput', () => {
144
- describe('FormattedText input', () => {
145
- it('should handle type as an array', () => {
146
- const functionInputSchema = {
147
- type: 'object',
148
-
149
- properties: {
150
- 'my-input': { type: ['number', 'string'] },
151
- },
152
-
153
- required: ['my-input'],
154
- };
325
+ describe('FormattedText input', () => {
326
+ it('should handle type as an array', () => {
327
+ const functionInputSchema = {
328
+ type: 'object',
155
329
 
156
- expect(
157
- jsonValidationService.validateComponentInput(functionInputSchema, {
158
- 'my-input': 'formattedText',
159
- }),
160
- ).toEqual(true);
330
+ properties: {
331
+ 'my-input': { type: ['number', 'string'] },
332
+ },
161
333
 
162
- expect(
163
- jsonValidationService.validateComponentInput(functionInputSchema, {
164
- 'my-input': 123,
165
- }),
166
- ).toEqual(true);
167
- });
334
+ required: ['my-input'],
335
+ };
168
336
 
169
- it('should handle type is an array of both string and FormattedText', () => {
170
- const formattedText: FormattedText = [
337
+ expect(
338
+ jsonSchemaService.validateInput(
171
339
  {
172
- tag: 'p',
173
- type: 'tag',
174
- children: [
175
- { type: 'text', value: 'This is some ' },
176
- { type: 'text', value: 'Link to asset 12345' },
177
- { type: 'text', value: ' with an image ' },
178
- { type: 'text', value: '.' },
179
- ],
180
- },
181
- ];
182
- const functionInputSchema = {
183
- type: 'object',
184
-
185
- properties: {
186
- 'my-input': { type: ['FormattedText', 'string'] },
187
- },
188
-
189
- required: ['my-input'],
190
- };
191
-
192
- expect(
193
- jsonValidationService.validateComponentInput(functionInputSchema, {
194
- 'my-input': formattedText,
195
- }),
196
- ).toEqual(true);
197
-
198
- expect(
199
- jsonValidationService.validateComponentInput(functionInputSchema, {
200
- 'my-input': 'hello',
201
- }),
202
- ).toEqual(true);
203
- });
204
-
205
- it('should return true if input is formatted text', () => {
206
- const functionInputSchema = {
207
- type: 'object',
208
-
209
- properties: {
210
- 'my-input': { type: 'FormattedText' },
340
+ 'my-input': 'formattedText',
211
341
  },
342
+ functionInputSchema,
343
+ ),
344
+ ).toEqual(true);
212
345
 
213
- required: ['my-input'],
214
- };
215
-
216
- const formattedText: FormattedText = [
346
+ expect(
347
+ jsonSchemaService.validateInput(
217
348
  {
218
- tag: 'p',
219
- type: 'tag',
220
- children: [
221
- { type: 'text', value: 'This is some ' },
222
- { type: 'text', value: 'Link to asset 12345' },
223
- { type: 'text', value: ' with an image ' },
224
- { type: 'text', value: '.' },
225
- ],
226
- },
227
- ];
228
- const inputValue = {
229
- 'my-input': formattedText,
230
- };
231
-
232
- expect(jsonValidationService.validateComponentInput(functionInputSchema, inputValue)).toEqual(true);
233
- });
234
-
235
- it('should throw an error if the FormattedText input is not formatted text', () => {
236
- const functionInputSchema = {
237
- type: 'object',
238
-
239
- properties: {
240
- 'my-input': { type: 'FormattedText' },
241
- },
242
-
243
- required: ['my-input'],
244
- };
245
- const inputValue = {
246
- 'my-input': 123,
247
- };
248
- expectToThrowErrorMatchingTypeAndMessage(
249
- () => {
250
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
251
- },
252
- SchemaValidationError,
253
- `failed validation: Expected \`123\` (number) in \`#/my-input\` to be of type \`array\``,
254
- );
255
- });
256
-
257
- it('should throw an error if the FormattedText input is invalid formatted text', () => {
258
- const functionInputSchema = {
259
- type: 'object',
260
-
261
- properties: {
262
- 'my-input': { type: 'FormattedText' },
263
- },
264
-
265
- required: ['my-input'],
266
- };
267
- const inputValue = {
268
- 'my-input': {
269
- something: 'aa',
270
- },
271
- };
272
- expectToThrowErrorMatchingTypeAndMessage(
273
- () => {
274
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
349
+ 'my-input': 123,
275
350
  },
276
- SchemaValidationError,
277
- `failed validation: Expected \`[object Object]\` (object) in \`#/my-input\` to be of type \`array\``,
278
- );
279
- });
280
-
281
- it('should throw an error if the FormattedText input is invalid formatted text (deeply nested)', () => {
282
- const functionInputSchema = {
283
- type: 'object',
351
+ functionInputSchema,
352
+ ),
353
+ ).toEqual(true);
354
+ });
284
355
 
285
- properties: {
286
- 'my-input': { type: 'FormattedText' },
287
- },
356
+ it.failing('should handle type is an array of both string and FormattedText', () => {
357
+ const formattedText: FormattedText = [
358
+ {
359
+ tag: 'p',
360
+ type: 'tag',
361
+ children: [
362
+ { type: 'text', value: 'This is some ' },
363
+ { type: 'text', value: 'Link to asset 12345' },
364
+ { type: 'text', value: ' with an image ' },
365
+ { type: 'text', value: '.' },
366
+ ],
367
+ },
368
+ ];
369
+ const functionInputSchema = {
370
+ type: 'object',
288
371
 
289
- required: ['my-input'],
290
- };
291
- const formattedText: FormattedText = [
292
- {
293
- tag: 'p',
294
- type: 'tag',
295
- children: [
296
- { type: 'text', value: 'This is some ' },
297
- { type: 'text', value: 'Link to asset 12345' },
298
- { type: 'text', value: ' with an image ' },
299
- { type: 'text', value: 123 as any }, // see here
300
- { type: 'text', value: '.' },
301
- ],
302
- },
303
- ];
372
+ properties: {
373
+ 'my-input': { type: ['FormattedText', 'string'] },
374
+ },
304
375
 
305
- const inputValue = {
306
- 'my-input': formattedText,
307
- };
308
- expectToThrowErrorMatchingTypeAndMessage(
309
- () => {
310
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
311
- },
312
- SchemaValidationError,
313
- 'failed validation: Object at `#/my-input/0` does not match any schema',
314
- );
315
- });
376
+ required: ['my-input'],
377
+ };
316
378
 
317
- it('should validate an array of formatted texts', () => {
318
- const formattedText: FormattedText = [
379
+ expect(
380
+ jsonSchemaService.validateInput(
319
381
  {
320
- tag: 'p',
321
- type: 'tag',
322
- children: [{ type: 'text', value: 'hello' }],
323
- },
324
- ];
325
-
326
- const schema = {
327
- type: 'object',
328
- properties: {
329
- arr: {
330
- type: 'array',
331
- items: { type: 'FormattedText' },
332
- },
382
+ 'my-input': formattedText,
333
383
  },
334
- };
335
- const value = {
336
- arr: [formattedText],
337
- };
338
-
339
- expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
340
- });
384
+ functionInputSchema,
385
+ ),
386
+ ).toEqual(true);
341
387
 
342
- it('should throw an error if the FormattedText input is invalid formatted text (deeply, deeply nested)', () => {
343
- const formattedText: FormattedText = [
388
+ expect(
389
+ jsonSchemaService.validateInput(
344
390
  {
345
- tag: 'p',
346
- type: 'tag',
347
- children: [{ type: 'text', value: 'hello' }],
348
- },
349
- ];
350
-
351
- const inputValue: any = {
352
- 'my-input': formattedText,
353
- deep: {
354
- arr: [
355
- {
356
- prop: formattedText,
357
- formattedTextArray: [formattedText, formattedText, { bad: 'data' }],
358
- },
359
- ],
360
- },
361
- };
362
-
363
- const functionInputSchema = {
364
- type: 'object',
365
-
366
- properties: {
367
- 'my-input': { type: 'FormattedText' },
368
- deep: {
369
- type: 'object',
370
- properties: {
371
- arr: {
372
- type: 'array',
373
- items: {
374
- type: 'object',
375
- required: ['prop', 'formattedTextArray'],
376
- properties: {
377
- prop: 'FormattedText',
378
- formattedTextArray: {
379
- type: 'array',
380
- items: {
381
- type: 'FormattedText',
382
- },
383
- },
384
- },
385
- },
386
- },
387
- },
388
- required: ['arr'],
389
- },
390
- },
391
-
392
- required: ['my-input', 'deep'],
393
- };
394
-
395
- expectToThrowErrorMatchingTypeAndMessage(
396
- () => {
397
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
391
+ 'my-input': 'hello',
398
392
  },
399
- SchemaValidationError,
400
- 'failed validation: Expected `[object Object]` (object) in `#/deep/arr/0/formattedTextArray/2` to be of type `array`',
401
- );
402
- });
393
+ functionInputSchema,
394
+ ),
395
+ ).toEqual(true);
396
+ });
403
397
 
404
- it('should validate a FormattedText value when the schema is a $ref', async () => {
405
- const formattedText: FormattedText = [
406
- {
407
- tag: 'p',
408
- type: 'tag',
409
- children: [{ type: 'text', value: 'hello' }],
410
- },
411
- ];
398
+ it('should return true if input is formatted text', () => {
399
+ const functionInputSchema = {
400
+ type: 'object',
412
401
 
413
- const schema = {
414
- type: 'object',
415
- properties: {
416
- 'my-input': { $ref: '#/definitions/FormattedText' },
417
- },
418
- definitions: {
419
- FormattedText: { type: 'FormattedText' },
420
- },
421
- required: ['my-input'],
422
- };
423
- const value = {
424
- 'my-input': formattedText,
425
- };
402
+ properties: {
403
+ 'my-input': { type: 'FormattedText' },
404
+ },
426
405
 
427
- expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
428
- });
406
+ required: ['my-input'],
407
+ };
429
408
 
430
- it('should error when a FormattedText value is invalid when the schema is a $ref', async () => {
431
- const schema = {
432
- type: 'object',
433
- properties: {
434
- 'my-input': { $ref: '#/definitions/FormattedText' },
435
- },
436
- definitions: {
437
- FormattedText: { type: 'FormattedText' },
438
- },
439
- required: ['my-input'],
440
- };
441
- const value = {
442
- 'my-input': { bad: 'data' },
443
- };
409
+ const formattedText: FormattedText = [
410
+ {
411
+ tag: 'p',
412
+ type: 'tag',
413
+ children: [
414
+ { type: 'text', value: 'This is some ' },
415
+ { type: 'text', value: 'Link to asset 12345' },
416
+ { type: 'text', value: ' with an image ' },
417
+ { type: 'text', value: '.' },
418
+ ],
419
+ },
420
+ ];
421
+ const inputValue = {
422
+ 'my-input': formattedText,
423
+ };
444
424
 
445
- expectToThrowErrorMatchingTypeAndMessage(
446
- () => {
447
- jsonValidationService.validateComponentInput(schema, value);
448
- },
449
- SchemaValidationError,
450
- 'failed validation: Expected `[object Object]` (object) in `#/my-input` to be of type `array`',
451
- );
452
- });
425
+ expect(() => jsonSchemaService.validateInput(inputValue, functionInputSchema)).not.toThrow();
426
+ });
453
427
 
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
- ];
428
+ it('should throw an error if the FormattedText input is not formatted text', () => {
429
+ const functionInputSchema = {
430
+ type: 'object',
462
431
 
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
- };
432
+ properties: {
433
+ 'my-input': { type: 'FormattedText' },
434
+ },
477
435
 
478
- expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
479
- });
436
+ required: ['my-input'],
437
+ };
438
+ const inputValue = {
439
+ 'my-input': 123,
440
+ };
441
+ expectToThrowErrorMatchingTypeAndMessage(
442
+ () => {
443
+ jsonSchemaService.validateInput(inputValue, functionInputSchema);
444
+ },
445
+ SchemaValidationError,
446
+ 'failed validation: Value `123` in `#/my-input` does not match any given oneof schema',
447
+ );
448
+ });
480
449
 
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
- ];
450
+ it('should throw an error if the FormattedText input is invalid formatted text', () => {
451
+ const functionInputSchema = {
452
+ type: 'object',
489
453
 
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
- };
454
+ properties: {
455
+ 'my-input': { type: 'FormattedText' },
456
+ },
504
457
 
505
- expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
506
- });
458
+ required: ['my-input'],
459
+ };
460
+ const inputValue = {
461
+ 'my-input': {
462
+ something: 'aa',
463
+ },
464
+ };
465
+ expectToThrowErrorMatchingTypeAndMessage(
466
+ () => {
467
+ jsonSchemaService.validateInput(inputValue, functionInputSchema);
468
+ },
469
+ SchemaValidationError,
470
+ 'failed validation: Value `{"something":"aa"}` in `#/my-input` does not match any given oneof schema',
471
+ );
507
472
  });
508
473
 
509
- describe('standard inputs', () => {
474
+ it('should throw an error if the FormattedText input is invalid formatted text (deeply nested)', () => {
510
475
  const functionInputSchema = {
511
476
  type: 'object',
512
477
 
513
478
  properties: {
514
- 'my-input': { type: 'number' },
479
+ 'my-input': { type: 'FormattedText' },
515
480
  },
516
481
 
517
482
  required: ['my-input'],
518
483
  };
484
+ const formattedText: FormattedText = [
485
+ {
486
+ tag: 'p',
487
+ type: 'tag',
488
+ children: [
489
+ { type: 'text', value: 'This is some ' },
490
+ { type: 'text', value: 'Link to asset 12345' },
491
+ { type: 'text', value: ' with an image ' },
492
+ { type: 'text', value: 123 as any }, // see here
493
+ { type: 'text', value: '.' },
494
+ ],
495
+ },
496
+ ];
519
497
 
520
- it('should return true for valid input values', () => {
521
- const inputValue = {
522
- 'my-input': 123,
523
- };
524
- const result = jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
525
- expect(result).toBe(true);
526
- });
498
+ const inputValue = {
499
+ 'my-input': formattedText,
500
+ };
501
+ expectToThrowErrorMatchingTypeAndMessage(
502
+ () => {
503
+ jsonSchemaService.validateInput(inputValue, functionInputSchema);
504
+ },
505
+ SchemaValidationError,
506
+ 'failed validation: Value `[{"tag":"p","type":"tag","children":[{"type":"text","value":"This is some "},{"type":"text","value":"Link to asset 12345"},{"type":"text","value":" with an image "},{"type":"text","value":123},{"type":"text","value":"."}]}]` in `#/my-input` does not match any given oneof schema',
507
+ );
508
+ });
527
509
 
528
- it('should throw a SchemaValidationError for invalid input type', () => {
529
- const inputValue = {
530
- 'my-input': '123',
531
- };
532
- expectToThrowErrorMatchingTypeAndMessage(
533
- () => {
534
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
535
- },
536
- SchemaValidationError,
537
- `failed validation: Expected \`123\` (string) in \`#/my-input\` to be of type \`number\``,
538
- );
539
- });
510
+ it('should validate an array of formatted texts', () => {
511
+ const formattedText: FormattedText = [
512
+ {
513
+ tag: 'p',
514
+ type: 'tag',
515
+ children: [{ type: 'text', value: 'hello' }],
516
+ },
517
+ ];
540
518
 
541
- it('should throw a SchemaValidationError for invalid input missing properties', () => {
542
- const inputValue = {};
543
- expectToThrowErrorMatchingTypeAndMessage(
544
- () => {
545
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
519
+ const schema = {
520
+ type: 'object',
521
+ properties: {
522
+ arr: {
523
+ type: 'array',
524
+ items: { type: 'FormattedText' },
546
525
  },
547
- SchemaValidationError,
548
- `failed validation: The required property \`my-input\` is missing at \`#\``,
549
- );
550
- });
526
+ },
527
+ };
528
+ const value = {
529
+ arr: [formattedText],
530
+ };
551
531
 
552
- it('should throw a SchemaValidationError with a truncated enum value list if there are more than 5 enum options', () => {
553
- expectToThrowErrorMatchingTypeAndMessage(
554
- () => {
555
- jsonValidationService.validateComponentInput(
556
- { type: 'object', properties: { enum: { type: 'string', enum: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] } } },
557
- { enum: 'z' },
558
- );
532
+ expect(jsonSchemaService.validateInput(value, schema)).toEqual(true);
533
+ });
534
+
535
+ it('should throw an error if the FormattedText input is invalid formatted text (deeply, deeply nested)', () => {
536
+ const formattedText: FormattedText = [
537
+ {
538
+ tag: 'p',
539
+ type: 'tag',
540
+ children: [{ type: 'text', value: 'hello' }],
541
+ },
542
+ ];
543
+
544
+ const inputValue: any = {
545
+ 'my-input': formattedText,
546
+ deep: {
547
+ arr: [
548
+ {
549
+ prop: formattedText,
550
+ formattedTextArray: [formattedText, formattedText, { bad: 'data' }],
551
+ },
552
+ ],
553
+ },
554
+ };
555
+
556
+ const functionInputSchema = {
557
+ type: 'object',
558
+
559
+ properties: {
560
+ 'my-input': { type: 'FormattedText' },
561
+ deep: {
562
+ type: 'object',
563
+ properties: {
564
+ arr: {
565
+ type: 'array',
566
+ items: {
567
+ type: 'object',
568
+ required: ['prop', 'formattedTextArray'],
569
+ properties: {
570
+ prop: 'FormattedText',
571
+ formattedTextArray: {
572
+ type: 'array',
573
+ items: {
574
+ type: 'FormattedText',
575
+ },
576
+ },
577
+ },
578
+ },
579
+ },
580
+ },
581
+ required: ['arr'],
559
582
  },
560
- SchemaValidationError,
561
- 'failed validation: Expected given value `z` in #/enum` to be one of `[a, b, c, d, e, ... 2 more]`',
562
- );
563
- });
583
+ },
564
584
 
565
- // TODO DEVX-658
566
- it.skip('should throw a SchemaValidationError for invalid input additional properties', () => {
567
- const inputValue = {
568
- 'my-input': 123,
569
- 'my-input-2': 123,
570
- };
571
- expect(() => {
572
- jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
573
- }).toThrowErrorMatchingInlineSnapshot();
574
- });
585
+ required: ['my-input', 'deep'],
586
+ };
587
+
588
+ expectToThrowErrorMatchingTypeAndMessage(
589
+ () => {
590
+ jsonSchemaService.validateInput(inputValue, functionInputSchema);
591
+ },
592
+ SchemaValidationError,
593
+ 'failed validation: Value `{"bad":"data"}` in `#/deep/arr/0/formattedTextArray/2` does not match any given oneof schema',
594
+ );
575
595
  });
576
- });
577
596
 
578
- describe('validateRenderInput', () => {
579
- it('should validate a property with type FormattedText as string', () => {
597
+ it('should validate a FormattedText value when the schema is a $ref', async () => {
598
+ const formattedText: FormattedText = [
599
+ {
600
+ tag: 'p',
601
+ type: 'tag',
602
+ children: [{ type: 'text', value: 'hello' }],
603
+ },
604
+ ];
605
+
580
606
  const schema = {
581
607
  type: 'object',
582
608
  properties: {
583
- 'my-input': { type: 'FormattedText' },
609
+ 'my-input': { $ref: '#/definitions/FormattedText' },
610
+ },
611
+ definitions: {
612
+ FormattedText: { type: 'FormattedText' },
584
613
  },
585
614
  required: ['my-input'],
586
615
  };
587
616
  const value = {
588
- 'my-input': 'hello',
617
+ 'my-input': formattedText,
589
618
  };
590
619
 
591
- expect(jsonValidationService.validateRenderInput(schema, value)).toEqual(true);
620
+ expect(jsonSchemaService.validateInput(value, schema)).toEqual(true);
592
621
  });
593
622
 
594
- it('should error when a property with type FormattedText is provided a valid FormattedText value', () => {
623
+ it('should error when a FormattedText value is invalid when the schema is a $ref', async () => {
595
624
  const schema = {
596
625
  type: 'object',
597
626
  properties: {
598
- 'my-input': { type: 'FormattedText' },
627
+ 'my-input': { $ref: '#/definitions/FormattedText' },
628
+ },
629
+ definitions: {
630
+ FormattedText: { type: 'FormattedText' },
599
631
  },
600
632
  required: ['my-input'],
601
633
  };
602
634
  const value = {
603
- 'my-input': [{ type: 'text', value: 'hello' }],
635
+ 'my-input': { bad: 'data' },
604
636
  };
605
637
 
606
638
  expectToThrowErrorMatchingTypeAndMessage(
607
639
  () => {
608
- jsonValidationService.validateRenderInput(schema, value);
640
+ jsonSchemaService.validateInput(value, schema);
609
641
  },
610
642
  SchemaValidationError,
611
- 'failed validation: Expected `[object Object]` (array) in `#/my-input` to be of type `string`',
643
+ 'failed validation: Value `{"bad":"data"}` in `#/my-input` does not match any given oneof schema',
612
644
  );
613
645
  });
614
646
 
615
- it('should validate a property with type FormattedText within an if/then/else as string', () => {
647
+ it('should validate a FormattedText value when the schema is a $ref to a $ref', async () => {
648
+ const formattedText: FormattedText = [
649
+ {
650
+ tag: 'p',
651
+ type: 'tag',
652
+ children: [{ type: 'text', value: 'hello' }],
653
+ },
654
+ ];
655
+
616
656
  const schema = {
617
657
  type: 'object',
618
658
  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
- },
659
+ 'my-input': { $ref: '#/definitions/FormattedText' },
660
+ },
661
+ definitions: {
662
+ FormattedText: { $ref: '#/definitions/FormattedText2' },
663
+ FormattedText2: { type: 'FormattedText' },
639
664
  },
640
665
  required: ['my-input'],
641
666
  };
642
667
  const value = {
643
- 'my-input': {
644
- prop: 'a',
645
- text: 'hello',
646
- },
668
+ 'my-input': formattedText,
647
669
  };
648
670
 
649
- expect(jsonValidationService.validateRenderInput(schema, value)).toEqual(true);
671
+ expect(jsonSchemaService.validateInput(value, schema)).toEqual(true);
672
+ });
650
673
 
651
- const otherValue = {
652
- 'my-input': {
653
- prop: 'b',
654
- text: ['my', 'formatted', 'text'],
674
+ it('should validate a FormattedText value when the schema is in an if/then/else', async () => {
675
+ const formattedText: FormattedText = [
676
+ {
677
+ tag: 'p',
678
+ type: 'tag',
679
+ children: [{ type: 'text', value: 'hello' }],
680
+ },
681
+ ];
682
+
683
+ const schema = {
684
+ type: 'object',
685
+ properties: {
686
+ 'my-input': {
687
+ if: { type: 'string' },
688
+ then: { type: 'string' },
689
+ else: { type: 'FormattedText' },
690
+ },
655
691
  },
692
+ required: ['my-input'],
656
693
  };
657
- expect(jsonValidationService.validateRenderInput(schema, otherValue)).toEqual(true);
694
+ const value = {
695
+ 'my-input': formattedText,
696
+ };
697
+
698
+ expect(jsonSchemaService.validateInput(value, schema)).toEqual(true);
658
699
  });
659
700
  });
660
- });
661
701
 
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
- }
702
+ describe('standard inputs', () => {
703
+ const functionInputSchema = {
704
+ type: 'object',
677
705
 
678
- function resolvableTypeFixture<T extends string>(title: T, schema: JSONSchema = defaultSchema) {
679
- return ResolvableType({
680
- ...schema,
681
- title,
706
+ properties: {
707
+ 'my-input': { type: 'number' },
708
+ },
709
+
710
+ required: ['my-input'],
711
+ };
712
+
713
+ it('should return true for valid input values', () => {
714
+ const inputValue = {
715
+ 'my-input': 123,
716
+ };
717
+ const result = jsonSchemaService.validateInput(inputValue, functionInputSchema);
718
+ expect(result).toBe(true);
719
+ });
720
+
721
+ it('should throw a SchemaValidationError for invalid input type', () => {
722
+ const inputValue = {
723
+ 'my-input': '123',
724
+ };
725
+ expectToThrowErrorMatchingTypeAndMessage(
726
+ () => {
727
+ jsonSchemaService.validateInput(inputValue, functionInputSchema);
728
+ },
729
+ SchemaValidationError,
730
+ `failed validation: Expected \`123\` (string) in \`#/my-input\` to be of type \`number\``,
731
+ );
732
+ });
733
+
734
+ it('should throw a SchemaValidationError for invalid input missing properties', () => {
735
+ const inputValue = {};
736
+ expectToThrowErrorMatchingTypeAndMessage(
737
+ () => {
738
+ jsonSchemaService.validateInput(inputValue, functionInputSchema);
739
+ },
740
+ SchemaValidationError,
741
+ `failed validation: The required property \`my-input\` is missing at \`#\``,
742
+ );
743
+ });
744
+
745
+ it('should throw a SchemaValidationError with a truncated enum value list if there are more than 5 enum options', () => {
746
+ expectToThrowErrorMatchingTypeAndMessage(
747
+ () => {
748
+ jsonSchemaService.validateInput(
749
+ { enum: 'z' },
750
+ { type: 'object', properties: { enum: { type: 'string', enum: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] } } },
751
+ );
752
+ },
753
+ SchemaValidationError,
754
+ 'failed validation: Expected given value `z` in #/enum` to be one of `[a, b, c, d, e, ... 2 more]`',
755
+ );
756
+ });
757
+
758
+ // TODO DEVX-658
759
+ it.skip('should throw a SchemaValidationError for invalid input additional properties', () => {
760
+ const inputValue = {
761
+ 'my-input': 123,
762
+ 'my-input-2': 123,
763
+ };
764
+ expect(() => {
765
+ jsonSchemaService.validateInput(inputValue, functionInputSchema);
766
+ }).toThrowErrorMatchingInlineSnapshot();
767
+ });
682
768
  });
683
- }
684
769
 
685
- describe('JsonSchemaService', () => {
686
770
  describe('validateInput', () => {
687
771
  it.each([String('123'), Number(123), [123]])(
688
772
  'should validate any primitive type with its resolvable type %s',
689
773
  (propertyValue) => {
690
774
  const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
775
+ const MyResolvableNumber = resolvableTypeFixture('MyResolvableNumber', { type: 'number' });
776
+ const MyResolvableArray = resolvableTypeFixture('MyResolvableArray', { type: 'array' });
691
777
  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
- },
778
+ new TypeResolver([primitiveSchema], [MyResolvableNumber, MyResolvableArray], {
779
+ MyPrimitive: {
780
+ // @ts-expect-error - fixture is unknown but we know the actual shape
781
+ MyResolvableNumber: (value: number) => value.toString(),
782
+ // @ts-expect-error - fixture is unknown but we know the actual shape
783
+ MyResolvableArray: (value: any[]) => value.join(''),
705
784
  },
706
- ),
785
+ }),
707
786
  ComponentInputMetaSchema,
708
787
  );
709
788
 
@@ -718,22 +797,17 @@ describe('JsonSchemaService', () => {
718
797
 
719
798
  it('should error when a primitive type is provided a value that cannot be resolved by its resolvable types', () => {
720
799
  const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
800
+ const MyResolvableNumber = resolvableTypeFixture('MyResolvableNumber', { type: 'number' });
801
+ const MyResolvableArray = resolvableTypeFixture('MyResolvableArray', { type: 'array' });
721
802
  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
- ),
803
+ new TypeResolver([primitiveSchema], [MyResolvableNumber, MyResolvableArray], {
804
+ MyPrimitive: {
805
+ // @ts-expect-error - fixture is unknown but we know the actual shape
806
+ MyResolvableNumber: (value: number) => value.toString(),
807
+ // @ts-expect-error - fixture is unknown but we know the actual shape
808
+ MyResolvableArray: (value: any[]) => value.join(''),
809
+ },
810
+ }),
737
811
  ComponentInputMetaSchema,
738
812
  );
739
813
 
@@ -749,22 +823,17 @@ describe('JsonSchemaService', () => {
749
823
  'should validate a primitive type when defined as a ref with resolvable value %s',
750
824
  (propertyValue) => {
751
825
  const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
826
+ const MyResolvableNumber = resolvableTypeFixture('MyResolvableNumber', { type: 'number' });
827
+ const MyResolvableArray = resolvableTypeFixture('MyResolvableArray', { type: 'array' });
752
828
  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
- },
829
+ new TypeResolver([primitiveSchema], [MyResolvableNumber, MyResolvableArray], {
830
+ MyPrimitive: {
831
+ // @ts-expect-error - fixture is unknown but we know the actual shape
832
+ MyResolvableNumber: (value: number) => value.toString(),
833
+ // @ts-expect-error - fixture is unknown but we know the actual shape
834
+ MyResolvableArray: (value: any[]) => value.join(''),
766
835
  },
767
- ),
836
+ }),
768
837
  ComponentInputMetaSchema,
769
838
  );
770
839
 
@@ -783,21 +852,15 @@ describe('JsonSchemaService', () => {
783
852
 
784
853
  it('should not validate on a primitive type against a resolvable type when a resolver is not defined', () => {
785
854
  const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
855
+ const MyResolvableNumber = resolvableTypeFixture('MyResolvableNumber', { type: 'number' });
856
+ const MyResolvableArray = resolvableTypeFixture('MyResolvableArray', { type: 'array' });
786
857
  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
- },
858
+ new TypeResolver([primitiveSchema], [MyResolvableNumber, MyResolvableArray], {
859
+ MyPrimitive: {
860
+ // @ts-expect-error - fixture is unknown but we know the actual shape
861
+ MyResolvableNumber: (value: number) => value.toString(),
799
862
  },
800
- ),
863
+ }),
801
864
  ComponentInputMetaSchema,
802
865
  );
803
866
 
@@ -813,26 +876,26 @@ describe('JsonSchemaService', () => {
813
876
  const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
814
877
  const jsonSchemaService = new JSONSchemaService(
815
878
  new TypeResolver(
816
- {
817
- MyPrimitive: primitiveSchema,
818
- },
819
- {
820
- MyResolvableSrcNumber: resolvableTypeFixture('MyResolvableSrcNumber', {
879
+ [primitiveSchema],
880
+ [
881
+ resolvableTypeFixture('MyResolvableSrcNumber', {
821
882
  type: 'object',
822
883
  properties: {
823
884
  src: { type: 'number' },
824
885
  },
825
886
  }),
826
- MyResolvableSrcString: resolvableTypeFixture('MyResolvableSrcString', {
887
+ resolvableTypeFixture('MyResolvableSrcString', {
827
888
  type: 'object',
828
889
  properties: {
829
890
  src: { type: 'string' },
830
891
  },
831
892
  }),
832
- },
893
+ ],
833
894
  {
834
895
  MyPrimitive: {
896
+ // @ts-expect-error - fixture is unknown but we know the actual shape
835
897
  MyResolvableSrcNumber: (value: { src: number }) => value.src.toString(),
898
+ // @ts-expect-error - fixture is unknown but we know the actual shape
836
899
  MyResolvableSrcString: (value: { src: string }) => value.src,
837
900
  },
838
901
  },
@@ -870,16 +933,16 @@ describe('JsonSchemaService', () => {
870
933
  const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
871
934
  const jsonSchemaService = new JSONSchemaService(
872
935
  new TypeResolver(
873
- {
874
- MyPrimitive: primitiveSchema,
875
- },
876
- {
877
- MyResolvableNumber: resolvableTypeFixture('MyResolvableNumber', { type: 'number' }),
878
- MyResolvableArray: resolvableTypeFixture('MyResolvableArray', { type: 'array' }),
879
- },
936
+ [primitiveSchema],
937
+ [
938
+ resolvableTypeFixture('MyResolvableNumber', { type: 'number' }),
939
+ resolvableTypeFixture('MyResolvableArray', { type: 'array' }),
940
+ ],
880
941
  {
881
942
  MyPrimitive: {
943
+ // @ts-expect-error - fixture is unknown but we know the actual shape
882
944
  MyResolvableNumber: (value: number) => value.toString(),
945
+ // @ts-expect-error - fixture is unknown but we know the actual shape
883
946
  MyResolvableArray: (value: any[]) => value.join(''),
884
947
  },
885
948
  },
@@ -903,22 +966,22 @@ describe('JsonSchemaService', () => {
903
966
  const primitiveSchema = primitiveTypeFixture('MyPrimitive', { type: 'string' });
904
967
  const jsonSchemaService = new JSONSchemaService(
905
968
  new TypeResolver(
906
- {
907
- MyPrimitive: primitiveSchema,
908
- },
909
- {
910
- MyResolvableSrcString: resolvableTypeFixture('MyResolvableSrcString', {
969
+ [primitiveSchema],
970
+ [
971
+ resolvableTypeFixture('MyResolvableSrcString', {
911
972
  type: 'object',
912
973
  properties: { src: { type: 'string' } },
913
974
  }),
914
- MyResolvableSrcNumber: resolvableTypeFixture('MyResolvableSrcNumber', {
975
+ resolvableTypeFixture('MyResolvableSrcNumber', {
915
976
  type: 'object',
916
977
  properties: { src: { type: 'number' } },
917
978
  }),
918
- },
979
+ ],
919
980
  {
920
981
  MyPrimitive: {
982
+ // @ts-expect-error - fixture is unknown but we know the actual shape
921
983
  MyResolvableSrcNumber: (value: { src: number }) => value.src.toString(),
984
+ // @ts-expect-error - fixture is unknown but we know the actual shape
922
985
  MyResolvableSrcString: (value: { src: string }) => value.src,
923
986
  },
924
987
  },