@squiz/dx-json-schema-lib 1.2.13-alpha.1 → 1.2.13-alpha.3
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/CHANGELOG.md +8 -0
- package/jest.config.ts +7 -0
- package/lib/JsonValidationService.d.ts +4 -6
- package/lib/JsonValidationService.js +90 -28
- package/lib/JsonValidationService.js.map +1 -1
- package/lib/JsonValidationService.spec.js +276 -65
- package/lib/JsonValidationService.spec.js.map +1 -1
- package/lib/errors/SchemaValidationError.d.ts +1 -1
- package/lib/errors/SchemaValidationError.js +8 -1
- package/lib/errors/SchemaValidationError.js.map +1 -1
- package/lib/formatted-text/v1/formattedText.d.ts +18 -16
- package/lib/formatted-text/v1/formattedText.json +59 -88
- package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.d.ts +8 -0
- package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.js +21 -0
- package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.js.map +1 -0
- package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.d.ts +1 -0
- package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.js +52 -0
- package/lib/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.js.map +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -1
- package/lib/manifest/v1/Draft-07.json +155 -0
- package/lib/manifest/v1/DxComponentInputSchema.json +11 -8
- package/lib/manifest/v1/DxComponentInputSchema.spec.js +23 -9
- package/lib/manifest/v1/DxComponentInputSchema.spec.js.map +1 -1
- package/lib/manifest/v1/__test__/schemas/badFunctionInputComponent.json +2 -1
- package/lib/manifest/v1/__test__/schemas/badNestedFunctionInput.json +2 -1
- package/lib/manifest/v1/__test__/schemas/nonObjectFunctionInputComponent.json +2 -1
- package/lib/manifest/v1/__test__/schemas/validComponentJson.json +48 -0
- package/lib/manifest/v1/v1.d.ts +5 -7
- package/lib/manifest/v1/v1.spec.js +22 -3
- package/lib/manifest/v1/v1.spec.js.map +1 -1
- package/package.json +4 -3
- package/src/JsonValidationService.spec.ts +379 -70
- package/src/JsonValidationService.ts +112 -34
- package/src/errors/SchemaValidationError.ts +10 -2
- package/src/formatted-text/v1/formattedText.json +65 -89
- package/src/formatted-text/v1/formattedText.ts +19 -17
- package/src/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.spec.ts +58 -0
- package/src/formatted-text/v1/higherOrderFormattedTextToBaseFormattedText.ts +36 -0
- package/src/index.ts +1 -0
- package/src/manifest/v1/Draft-07.json +155 -0
- package/src/manifest/v1/DxComponentInputSchema.json +11 -8
- package/src/manifest/v1/DxComponentInputSchema.spec.ts +63 -35
- package/src/manifest/v1/__test__/schemas/badFunctionInputComponent.json +2 -1
- package/src/manifest/v1/__test__/schemas/badNestedFunctionInput.json +2 -1
- package/src/manifest/v1/__test__/schemas/nonObjectFunctionInputComponent.json +2 -1
- package/src/manifest/v1/__test__/schemas/validComponentJson.json +48 -0
- package/src/manifest/v1/v1.spec.ts +37 -3
- package/src/manifest/v1/v1.ts +5 -7
- package/tsconfig.json +3 -1
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
@@ -3,6 +3,14 @@
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
5
5
|
|
6
|
+
## [1.2.13-alpha.3](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.2.2...v1.2.13-alpha.3) (2023-01-16)
|
7
|
+
|
8
|
+
**Note:** Version bump only for package @squiz/dx-json-schema-lib
|
9
|
+
|
10
|
+
## [1.2.13-alpha.2](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.2.2...v1.2.13-alpha.2) (2023-01-13)
|
11
|
+
|
12
|
+
**Note:** Version bump only for package @squiz/dx-json-schema-lib
|
13
|
+
|
6
14
|
## [1.2.13-alpha.1](https://gitlab.squiz.net/developer-experience/cmp/compare/v1.2.2...v1.2.13-alpha.1) (2023-01-13)
|
7
15
|
|
8
16
|
**Note:** Version bump only for package @squiz/dx-json-schema-lib
|
package/jest.config.ts
CHANGED
@@ -7,6 +7,7 @@ configFunc();
|
|
7
7
|
const config: Config = {
|
8
8
|
preset: 'ts-jest',
|
9
9
|
testEnvironment: 'node',
|
10
|
+
|
10
11
|
testPathIgnorePatterns: [
|
11
12
|
'<rootDir>/lib/',
|
12
13
|
'<rootDir>/cdk.out/',
|
@@ -15,6 +16,12 @@ const config: Config = {
|
|
15
16
|
'.*\\.integration\\.spec\\.ts$',
|
16
17
|
],
|
17
18
|
maxWorkers: '80%',
|
19
|
+
|
20
|
+
globals: {
|
21
|
+
'ts-jest': {
|
22
|
+
diagnostics: false,
|
23
|
+
},
|
24
|
+
},
|
18
25
|
};
|
19
26
|
|
20
27
|
export default config;
|
@@ -1,9 +1,7 @@
|
|
1
|
-
import
|
1
|
+
import { JSONSchema } from 'json-schema-library';
|
2
2
|
export declare class JsonValidationService {
|
3
|
-
ajv: Ajv;
|
4
|
-
constructor();
|
5
3
|
validateManifest(manifest: unknown, version: 'v1'): true;
|
6
|
-
validateContentSchema(contentSchema:
|
7
|
-
validateComponentInput(functionInputSchema:
|
8
|
-
private
|
4
|
+
validateContentSchema(contentSchema: JSONSchema): true;
|
5
|
+
validateComponentInput(functionInputSchema: JSONSchema, inputValue: unknown): true;
|
6
|
+
private processValidationResult;
|
9
7
|
}
|
@@ -4,50 +4,112 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
4
|
};
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
6
|
exports.JsonValidationService = void 0;
|
7
|
-
const ajv_1 = __importDefault(require("ajv"));
|
8
|
-
const ajv_formats_1 = __importDefault(require("ajv-formats"));
|
9
|
-
const better_ajv_errors_1 = __importDefault(require("better-ajv-errors"));
|
10
7
|
const DxComponentInputSchema_json_1 = __importDefault(require("./manifest/v1/DxComponentInputSchema.json"));
|
11
8
|
const DxComponentIcons_json_1 = __importDefault(require("./manifest/v1/DxComponentIcons.json"));
|
12
9
|
const DxContentMetaSchema_json_1 = __importDefault(require("./manifest/v1/DxContentMetaSchema.json"));
|
10
|
+
const Draft_07_json_1 = __importDefault(require("./manifest/v1/Draft-07.json"));
|
11
|
+
const formattedText_json_1 = __importDefault(require("./formatted-text/v1/formattedText.json"));
|
13
12
|
const v1_json_1 = __importDefault(require("./manifest/v1/v1.json"));
|
14
13
|
const SchemaValidationError_1 = require("./errors/SchemaValidationError");
|
14
|
+
const json_schema_library_1 = require("json-schema-library");
|
15
|
+
const json_schema_library_2 = require("json-schema-library");
|
16
|
+
const defaultConfig = {
|
17
|
+
...json_schema_library_2.draft07Config,
|
18
|
+
errors: {
|
19
|
+
...json_schema_library_2.draft07Config.errors,
|
20
|
+
enumError(data) {
|
21
|
+
let values = '[]';
|
22
|
+
if (data.values && Array.isArray(data.values)) {
|
23
|
+
if (data.values.length < 5) {
|
24
|
+
values = `[${data.values.join(', ')}]`;
|
25
|
+
}
|
26
|
+
else {
|
27
|
+
const firstFiveValues = data.values.slice(0, 5);
|
28
|
+
values = `[${firstFiveValues.join(', ')}, ... ${data.values.length - 5} more]`;
|
29
|
+
}
|
30
|
+
}
|
31
|
+
return {
|
32
|
+
type: 'error',
|
33
|
+
name: 'EnumError',
|
34
|
+
code: 'enum-error',
|
35
|
+
message: `Expected given value \`${data.value}\` in ${data.pointer}\` to be one of \`${values}\``,
|
36
|
+
data,
|
37
|
+
};
|
38
|
+
},
|
39
|
+
anyOfError(data) {
|
40
|
+
let value = `Value \`${data.value}\` at`;
|
41
|
+
if (typeof data.value == 'object') {
|
42
|
+
value = 'Object at';
|
43
|
+
}
|
44
|
+
if (Array.isArray(data.value)) {
|
45
|
+
value = 'Array at';
|
46
|
+
}
|
47
|
+
return {
|
48
|
+
type: 'error',
|
49
|
+
name: 'AnyOfError',
|
50
|
+
code: 'any-of-error',
|
51
|
+
message: `${value} \`${data.pointer}\` does not match any schema`,
|
52
|
+
data,
|
53
|
+
};
|
54
|
+
},
|
55
|
+
},
|
56
|
+
};
|
57
|
+
const FTSchema = new json_schema_library_1.Draft07(formattedText_json_1.default);
|
58
|
+
const ComponentInputSchema = new json_schema_library_1.Draft({
|
59
|
+
...defaultConfig,
|
60
|
+
resolveRef(schema, rootSchema) {
|
61
|
+
const resolvedSchema = json_schema_library_2.draft07Config.resolveRef(schema, rootSchema);
|
62
|
+
if (!resolvedSchema) {
|
63
|
+
return resolvedSchema;
|
64
|
+
}
|
65
|
+
if (resolvedSchema.type === 'FormattedText') {
|
66
|
+
return FTSchema.rootSchema;
|
67
|
+
}
|
68
|
+
else if (Array.isArray(resolvedSchema.type) && resolvedSchema.type.includes('FormattedText')) {
|
69
|
+
return {
|
70
|
+
...schema,
|
71
|
+
...FTSchema.rootSchema,
|
72
|
+
type: resolvedSchema.type.filter((t) => t !== 'FormattedText').concat(formattedText_json_1.default.type),
|
73
|
+
};
|
74
|
+
}
|
75
|
+
else {
|
76
|
+
return resolvedSchema;
|
77
|
+
}
|
78
|
+
},
|
79
|
+
}, DxComponentInputSchema_json_1.default);
|
80
|
+
ComponentInputSchema.addRemoteSchema('DxComponentInputSchema.json/DxContentMetaSchema.json', DxContentMetaSchema_json_1.default);
|
81
|
+
const v1Schema = new json_schema_library_1.Draft07(v1_json_1.default, defaultConfig);
|
82
|
+
v1Schema.addRemoteSchema('DxComponentInputSchema.json/DxContentMetaSchema.json', DxContentMetaSchema_json_1.default);
|
83
|
+
v1Schema.addRemoteSchema('/DxComponentInputSchema.json', ComponentInputSchema.getSchema());
|
84
|
+
v1Schema.addRemoteSchema('/DxComponentIcons.json', DxComponentIcons_json_1.default);
|
85
|
+
v1Schema.addRemoteSchema('http://json-schema.org/draft-07/schema', Draft_07_json_1.default);
|
86
|
+
v1Schema.addRemoteSchema('http://json-schema.org/draft-07/schema#', Draft_07_json_1.default);
|
87
|
+
const ContentSchemaSchema = new json_schema_library_1.Draft07(DxComponentInputSchema_json_1.default, defaultConfig);
|
88
|
+
ContentSchemaSchema.addRemoteSchema('DxComponentInputSchema.json/DxContentMetaSchema.json', DxContentMetaSchema_json_1.default);
|
15
89
|
class JsonValidationService {
|
16
|
-
constructor() {
|
17
|
-
this.ajv = new ajv_1.default({
|
18
|
-
strict: true,
|
19
|
-
schemas: { DxContentMetaSchema: DxContentMetaSchema_json_1.default, v1: v1_json_1.default, DxComponentIcons: DxComponentIcons_json_1.default, DxComponentInputSchema: DxComponentInputSchema_json_1.default },
|
20
|
-
allowUnionTypes: true,
|
21
|
-
allErrors: true,
|
22
|
-
formats: {
|
23
|
-
'multi-line': true,
|
24
|
-
},
|
25
|
-
});
|
26
|
-
(0, ajv_formats_1.default)(this.ajv);
|
27
|
-
}
|
28
90
|
validateManifest(manifest, version) {
|
29
91
|
switch (version) {
|
30
|
-
case 'v1':
|
31
|
-
|
92
|
+
case 'v1': {
|
93
|
+
const validationResult = v1Schema.validate(manifest);
|
94
|
+
return this.processValidationResult(validationResult);
|
95
|
+
}
|
32
96
|
default:
|
33
|
-
throw new
|
97
|
+
throw new SchemaValidationError_1.SchemaValidationError('Invalid manifest version');
|
34
98
|
}
|
35
99
|
}
|
36
100
|
validateContentSchema(contentSchema) {
|
37
|
-
|
38
|
-
return this.doValidate(DxComponentInputSchema_json_1.default, contentSchema);
|
101
|
+
return this.processValidationResult(ContentSchemaSchema.validate(contentSchema));
|
39
102
|
}
|
40
103
|
validateComponentInput(functionInputSchema, inputValue) {
|
41
|
-
|
104
|
+
const inputSchema = ComponentInputSchema.compileSchema(functionInputSchema);
|
105
|
+
const errors = ComponentInputSchema.validate(inputValue, inputSchema);
|
106
|
+
return this.processValidationResult(errors);
|
42
107
|
}
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
47
|
-
const betterErrors = (0, better_ajv_errors_1.default)(schema, value, this.ajv.errors, { format: 'js' });
|
48
|
-
throw new SchemaValidationError_1.SchemaValidationError(betterErrors);
|
108
|
+
processValidationResult(errors) {
|
109
|
+
if (errors.length > 0) {
|
110
|
+
throw new SchemaValidationError_1.SchemaValidationError(errors.map((a) => a.message).join(',\n'));
|
49
111
|
}
|
50
|
-
return
|
112
|
+
return true;
|
51
113
|
}
|
52
114
|
}
|
53
115
|
exports.JsonValidationService = JsonValidationService;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"JsonValidationService.js","sourceRoot":"","sources":["../src/JsonValidationService.ts"],"names":[],"mappings":";;;;;;AAAA,
|
1
|
+
{"version":3,"file":"JsonValidationService.js","sourceRoot":"","sources":["../src/JsonValidationService.ts"],"names":[],"mappings":"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"}
|
@@ -6,12 +6,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const JsonValidationService_1 = require("./JsonValidationService");
|
7
7
|
const SchemaValidationError_1 = require("./errors/SchemaValidationError");
|
8
8
|
const validComponent_json_1 = __importDefault(require("./manifest/v1/__test__/schemas/validComponent.json"));
|
9
|
+
const validComponentJson_json_1 = __importDefault(require("./manifest/v1/__test__/schemas/validComponentJson.json"));
|
10
|
+
// eslint-disable-next-line @typescript-eslint/ban-types
|
11
|
+
function expectToThrowErrorMatchingTypeAndMessage(received, errorType, message) {
|
12
|
+
let error = null;
|
13
|
+
try {
|
14
|
+
received();
|
15
|
+
}
|
16
|
+
catch (e) {
|
17
|
+
error = e;
|
18
|
+
}
|
19
|
+
expect(error).toBeDefined();
|
20
|
+
expect(error === null || error === void 0 ? void 0 : error.message).toEqual(message);
|
21
|
+
expect(error).toBeInstanceOf(errorType);
|
22
|
+
}
|
9
23
|
describe('JsonValidationService', () => {
|
10
|
-
|
11
|
-
beforeEach(() => {
|
12
|
-
jsonValidationService = new JsonValidationService_1.JsonValidationService();
|
13
|
-
});
|
24
|
+
const jsonValidationService = new JsonValidationService_1.JsonValidationService();
|
14
25
|
describe('validateManifest', () => {
|
26
|
+
it('should return true for a valid JSON endpoint manifest', () => {
|
27
|
+
const result = jsonValidationService.validateManifest(validComponentJson_json_1.default, 'v1');
|
28
|
+
expect(result).toBe(true);
|
29
|
+
});
|
15
30
|
it('should return true for a valid manifest', () => {
|
16
31
|
const result = jsonValidationService.validateManifest(validComponent_json_1.default, 'v1');
|
17
32
|
expect(result).toBe(true);
|
@@ -19,17 +34,14 @@ describe('JsonValidationService', () => {
|
|
19
34
|
it('should throw a SchemaValidationError for an invalid manifest', () => {
|
20
35
|
const invalidManifest = { ...validComponent_json_1.default };
|
21
36
|
delete invalidManifest.name;
|
22
|
-
|
23
|
-
jsonValidationService.validateManifest(invalidManifest, 'v1');
|
24
|
-
}).toThrow(SchemaValidationError_1.SchemaValidationError);
|
25
|
-
expect(() => {
|
37
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
26
38
|
jsonValidationService.validateManifest(invalidManifest, 'v1');
|
27
|
-
}
|
39
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: The required property \`name\` is missing at \`#\``);
|
28
40
|
});
|
29
41
|
it('should throw an error for an invalid manifest version', () => {
|
30
|
-
|
42
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
31
43
|
jsonValidationService.validateManifest(validComponent_json_1.default, 'invalid-version');
|
32
|
-
}
|
44
|
+
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: Invalid manifest version');
|
33
45
|
});
|
34
46
|
});
|
35
47
|
describe('validateContentSchema', () => {
|
@@ -44,8 +56,7 @@ describe('JsonValidationService', () => {
|
|
44
56
|
const result = jsonValidationService.validateContentSchema(contentSchema);
|
45
57
|
expect(result).toBe(true);
|
46
58
|
});
|
47
|
-
|
48
|
-
it.skip('should return false for an invalid content schema, where the required property is missed from a child object', () => {
|
59
|
+
it('should return false for an invalid content schema, where the required property is missed from a child object', () => {
|
49
60
|
const contentSchema = {
|
50
61
|
type: 'object',
|
51
62
|
properties: {
|
@@ -58,9 +69,9 @@ describe('JsonValidationService', () => {
|
|
58
69
|
},
|
59
70
|
required: ['my-input'],
|
60
71
|
};
|
61
|
-
|
72
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
62
73
|
jsonValidationService.validateContentSchema(contentSchema);
|
63
|
-
}
|
74
|
+
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: The required property `required` is missing at `#/properties/my-input`');
|
64
75
|
});
|
65
76
|
it('should throw a SchemaValidationError for an invalid content schema, top level type must be object', () => {
|
66
77
|
const contentSchema = {
|
@@ -73,70 +84,270 @@ describe('JsonValidationService', () => {
|
|
73
84
|
required: ['my-input'],
|
74
85
|
},
|
75
86
|
};
|
76
|
-
|
87
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
77
88
|
jsonValidationService.validateContentSchema(contentSchema);
|
78
|
-
}
|
89
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected value at \`#/type\` to be \`object\`, but value given is \`array\``);
|
79
90
|
});
|
80
|
-
|
81
|
-
it.skip('should throw a SchemaValidationError for an invalid content schema missing the required property', () => {
|
91
|
+
it('should throw a SchemaValidationError for an invalid content schema missing the required property', () => {
|
82
92
|
const contentSchema = {
|
83
93
|
type: 'object',
|
84
94
|
properties: {
|
85
95
|
'my-input': { type: 'number' },
|
86
96
|
},
|
87
97
|
};
|
88
|
-
|
98
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
89
99
|
jsonValidationService.validateContentSchema(contentSchema);
|
90
|
-
}
|
100
|
+
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: The required property `required` is missing at `#`');
|
91
101
|
});
|
92
102
|
});
|
93
103
|
describe('validateComponentInput', () => {
|
94
|
-
|
95
|
-
type
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
104
|
+
describe('FormattedText input', () => {
|
105
|
+
it('should handle type as an array', () => {
|
106
|
+
const functionInputSchema = {
|
107
|
+
type: 'object',
|
108
|
+
properties: {
|
109
|
+
'my-input': { type: ['number', 'string'] },
|
110
|
+
},
|
111
|
+
required: ['my-input'],
|
112
|
+
};
|
113
|
+
expect(jsonValidationService.validateComponentInput(functionInputSchema, {
|
114
|
+
'my-input': 'formattedText',
|
115
|
+
})).toEqual(true);
|
116
|
+
expect(jsonValidationService.validateComponentInput(functionInputSchema, {
|
117
|
+
'my-input': 123,
|
118
|
+
})).toEqual(true);
|
119
|
+
});
|
120
|
+
it('should handle type is an array of both string and FormattedText', () => {
|
121
|
+
const formattedText = [
|
122
|
+
{
|
123
|
+
tag: 'p',
|
124
|
+
type: 'tag',
|
125
|
+
children: [
|
126
|
+
{ type: 'text', value: 'This is some ' },
|
127
|
+
{ type: 'text', value: 'Link to asset 12345' },
|
128
|
+
{ type: 'text', value: ' with an image ' },
|
129
|
+
{ type: 'text', value: '.' },
|
130
|
+
],
|
131
|
+
},
|
132
|
+
];
|
133
|
+
const functionInputSchema = {
|
134
|
+
type: 'object',
|
135
|
+
properties: {
|
136
|
+
'my-input': { type: ['FormattedText', 'string'] },
|
137
|
+
},
|
138
|
+
required: ['my-input'],
|
139
|
+
};
|
140
|
+
expect(jsonValidationService.validateComponentInput(functionInputSchema, {
|
141
|
+
'my-input': formattedText,
|
142
|
+
})).toEqual(true);
|
143
|
+
expect(jsonValidationService.validateComponentInput(functionInputSchema, {
|
144
|
+
'my-input': 'hello',
|
145
|
+
})).toEqual(true);
|
146
|
+
});
|
147
|
+
it('should return true if input is formatted text', () => {
|
148
|
+
const functionInputSchema = {
|
149
|
+
type: 'object',
|
150
|
+
properties: {
|
151
|
+
'my-input': { type: 'FormattedText' },
|
152
|
+
},
|
153
|
+
required: ['my-input'],
|
154
|
+
};
|
155
|
+
const formattedText = [
|
156
|
+
{
|
157
|
+
tag: 'p',
|
158
|
+
type: 'tag',
|
159
|
+
children: [
|
160
|
+
{ type: 'text', value: 'This is some ' },
|
161
|
+
{ type: 'text', value: 'Link to asset 12345' },
|
162
|
+
{ type: 'text', value: ' with an image ' },
|
163
|
+
{ type: 'text', value: '.' },
|
164
|
+
],
|
165
|
+
},
|
166
|
+
];
|
167
|
+
const inputValue = {
|
168
|
+
'my-input': formattedText,
|
169
|
+
};
|
170
|
+
expect(jsonValidationService.validateComponentInput(functionInputSchema, inputValue)).toEqual(true);
|
171
|
+
});
|
172
|
+
it('should throw an error if the FormattedText input is not formatted text', () => {
|
173
|
+
const functionInputSchema = {
|
174
|
+
type: 'object',
|
175
|
+
properties: {
|
176
|
+
'my-input': { type: 'FormattedText' },
|
177
|
+
},
|
178
|
+
required: ['my-input'],
|
179
|
+
};
|
180
|
+
const inputValue = {
|
181
|
+
'my-input': 123,
|
182
|
+
};
|
183
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
184
|
+
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
185
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected \`123\` (number) in \`#/my-input\` to be of type \`array\``);
|
186
|
+
});
|
187
|
+
it('should throw an error if the FormattedText input is invalid formatted text', () => {
|
188
|
+
const functionInputSchema = {
|
189
|
+
type: 'object',
|
190
|
+
properties: {
|
191
|
+
'my-input': { type: 'FormattedText' },
|
192
|
+
},
|
193
|
+
required: ['my-input'],
|
194
|
+
};
|
195
|
+
const inputValue = {
|
196
|
+
'my-input': {
|
197
|
+
something: 'aa',
|
198
|
+
},
|
199
|
+
};
|
200
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
201
|
+
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
202
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected \`[object Object]\` (object) in \`#/my-input\` to be of type \`array\``);
|
203
|
+
});
|
204
|
+
it('should throw an error if the FormattedText input is invalid formatted text (deeply nested)', () => {
|
205
|
+
const functionInputSchema = {
|
206
|
+
type: 'object',
|
207
|
+
properties: {
|
208
|
+
'my-input': { type: 'FormattedText' },
|
209
|
+
},
|
210
|
+
required: ['my-input'],
|
211
|
+
};
|
212
|
+
const formattedText = [
|
213
|
+
{
|
214
|
+
tag: 'p',
|
215
|
+
type: 'tag',
|
216
|
+
children: [
|
217
|
+
{ type: 'text', value: 'This is some ' },
|
218
|
+
{ type: 'text', value: 'Link to asset 12345' },
|
219
|
+
{ type: 'text', value: ' with an image ' },
|
220
|
+
{ type: 'text', value: 123 },
|
221
|
+
{ type: 'text', value: '.' },
|
222
|
+
],
|
223
|
+
},
|
224
|
+
];
|
225
|
+
const inputValue = {
|
226
|
+
'my-input': formattedText,
|
227
|
+
};
|
228
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
229
|
+
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
230
|
+
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: Object at `#/my-input/0` does not match any schema');
|
231
|
+
});
|
232
|
+
it('should validate an array of formatted texts', () => {
|
233
|
+
const formattedText = [
|
234
|
+
{
|
235
|
+
tag: 'p',
|
236
|
+
type: 'tag',
|
237
|
+
children: [{ type: 'text', value: 'hello' }],
|
238
|
+
},
|
239
|
+
];
|
240
|
+
const schema = {
|
241
|
+
type: 'object',
|
242
|
+
properties: {
|
243
|
+
arr: {
|
244
|
+
type: 'array',
|
245
|
+
items: { type: 'FormattedText' },
|
246
|
+
},
|
247
|
+
},
|
248
|
+
};
|
249
|
+
const value = {
|
250
|
+
arr: [formattedText],
|
251
|
+
};
|
252
|
+
expect(jsonValidationService.validateComponentInput(schema, value)).toEqual(true);
|
253
|
+
});
|
254
|
+
it('should throw an error if the FormattedText input is invalid formatted text (deeply, deeply nested)', () => {
|
255
|
+
const formattedText = [
|
256
|
+
{
|
257
|
+
tag: 'p',
|
258
|
+
type: 'tag',
|
259
|
+
children: [{ type: 'text', value: 'hello' }],
|
260
|
+
},
|
261
|
+
];
|
262
|
+
const inputValue = {
|
263
|
+
'my-input': formattedText,
|
264
|
+
deep: {
|
265
|
+
arr: [
|
266
|
+
{
|
267
|
+
prop: formattedText,
|
268
|
+
formattedTextArray: [formattedText, formattedText, { bad: 'data' }],
|
269
|
+
},
|
270
|
+
],
|
271
|
+
},
|
272
|
+
};
|
273
|
+
const functionInputSchema = {
|
274
|
+
type: 'object',
|
275
|
+
properties: {
|
276
|
+
'my-input': { type: 'FormattedText' },
|
277
|
+
deep: {
|
278
|
+
type: 'object',
|
279
|
+
properties: {
|
280
|
+
arr: {
|
281
|
+
type: 'array',
|
282
|
+
items: {
|
283
|
+
type: 'object',
|
284
|
+
required: ['prop', 'formattedTextArray'],
|
285
|
+
properties: {
|
286
|
+
prop: 'FormattedText',
|
287
|
+
formattedTextArray: {
|
288
|
+
type: 'array',
|
289
|
+
items: {
|
290
|
+
type: 'FormattedText',
|
291
|
+
},
|
292
|
+
},
|
293
|
+
},
|
294
|
+
},
|
295
|
+
},
|
296
|
+
},
|
297
|
+
required: ['arr'],
|
298
|
+
},
|
299
|
+
},
|
300
|
+
required: ['my-input', 'deep'],
|
301
|
+
};
|
302
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
303
|
+
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
304
|
+
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: Expected `[object Object]` (object) in `#/deep/arr/0/formattedTextArray/2` to be of type `array`');
|
305
|
+
});
|
127
306
|
});
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
307
|
+
describe('standard inputs', () => {
|
308
|
+
const functionInputSchema = {
|
309
|
+
type: 'object',
|
310
|
+
properties: {
|
311
|
+
'my-input': { type: 'number' },
|
312
|
+
},
|
313
|
+
required: ['my-input'],
|
133
314
|
};
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
139
|
-
|
315
|
+
it('should return true for valid input values', () => {
|
316
|
+
const inputValue = {
|
317
|
+
'my-input': 123,
|
318
|
+
};
|
319
|
+
const result = jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
320
|
+
expect(result).toBe(true);
|
321
|
+
});
|
322
|
+
it('should throw a SchemaValidationError for invalid input type', () => {
|
323
|
+
const inputValue = {
|
324
|
+
'my-input': '123',
|
325
|
+
};
|
326
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
327
|
+
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
328
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: Expected \`123\` (string) in \`#/my-input\` to be of type \`number\``);
|
329
|
+
});
|
330
|
+
it('should throw a SchemaValidationError for invalid input missing properties', () => {
|
331
|
+
const inputValue = {};
|
332
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
333
|
+
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
334
|
+
}, SchemaValidationError_1.SchemaValidationError, `failed validation: The required property \`my-input\` is missing at \`#\``);
|
335
|
+
});
|
336
|
+
it('should throw a SchemaValidationError with a truncated enum value list if there are more than 5 enum options', () => {
|
337
|
+
expectToThrowErrorMatchingTypeAndMessage(() => {
|
338
|
+
jsonValidationService.validateComponentInput({ type: 'object', properties: { enum: { type: 'string', enum: ['a', 'b', 'c', 'd', 'e', 'f', 'g'] } } }, { enum: 'z' });
|
339
|
+
}, SchemaValidationError_1.SchemaValidationError, 'failed validation: Expected given value `z` in #/enum` to be one of `[a, b, c, d, e, ... 2 more]`');
|
340
|
+
});
|
341
|
+
// TODO DEVX-658
|
342
|
+
it.skip('should throw a SchemaValidationError for invalid input additional properties', () => {
|
343
|
+
const inputValue = {
|
344
|
+
'my-input': 123,
|
345
|
+
'my-input-2': 123,
|
346
|
+
};
|
347
|
+
expect(() => {
|
348
|
+
jsonValidationService.validateComponentInput(functionInputSchema, inputValue);
|
349
|
+
}).toThrowErrorMatchingInlineSnapshot();
|
350
|
+
});
|
140
351
|
});
|
141
352
|
});
|
142
353
|
});
|