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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (27) hide show
  1. package/.npm/_logs/{2023-03-02T03_26_09_372Z-debug-0.log → 2023-03-03T02_38_06_635Z-debug-0.log} +10 -10
  2. package/lib/JsonValidationService.js +5 -0
  3. package/lib/JsonValidationService.js.map +1 -1
  4. package/lib/JsonValidationService.spec.js +44 -0
  5. package/lib/JsonValidationService.spec.js.map +1 -1
  6. package/lib/manifest/v1/DxContentMetaSchema.json +116 -1
  7. package/lib/manifest/v1/__test__/schemas/inputStringWithFormat.json +29 -0
  8. package/lib/manifest/v1/v1.d.ts +4 -2
  9. package/lib/validators/customFormatValidators.d.ts +2 -0
  10. package/lib/validators/customFormatValidators.js +14 -0
  11. package/lib/validators/customFormatValidators.js.map +1 -0
  12. package/lib/validators/utils/matrixAssetValidator.d.ts +2 -0
  13. package/lib/validators/utils/matrixAssetValidator.js +11 -0
  14. package/lib/validators/utils/matrixAssetValidator.js.map +1 -0
  15. package/lib/validators/utils/matrixAssetValidator.spec.d.ts +1 -0
  16. package/lib/validators/utils/matrixAssetValidator.spec.js +43 -0
  17. package/lib/validators/utils/matrixAssetValidator.spec.js.map +1 -0
  18. package/package.json +2 -2
  19. package/src/JsonValidationService.spec.ts +62 -0
  20. package/src/JsonValidationService.ts +5 -1
  21. package/src/manifest/v1/DxContentMetaSchema.json +116 -1
  22. package/src/manifest/v1/__test__/schemas/inputStringWithFormat.json +29 -0
  23. package/src/manifest/v1/v1.ts +206 -2
  24. package/src/validators/customFormatValidators.ts +15 -0
  25. package/src/validators/utils/matrixAssetValidator.spec.ts +49 -0
  26. package/src/validators/utils/matrixAssetValidator.ts +8 -0
  27. package/tsconfig.tsbuildinfo +1 -1
@@ -4,6 +4,7 @@ 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
9
  import { PrimitiveType, ResolvableType, TypeResolver } from './jsonTypeResolution/arbitraryTypeResolution';
9
10
 
@@ -59,6 +60,11 @@ describe('JsonValidationService', () => {
59
60
  'failed validation: Invalid manifest version',
60
61
  );
61
62
  });
63
+
64
+ it('should return true for a valid manifest with a string format MatrixAssetUri', () => {
65
+ const result = jsonValidationService.validateManifest(inputStringWithFormat, 'v1');
66
+ expect(result).toBe(true);
67
+ });
62
68
  });
63
69
 
64
70
  describe('validateContentSchema', () => {
@@ -141,6 +147,62 @@ describe('JsonValidationService', () => {
141
147
  });
142
148
 
143
149
  describe('validateComponentInput', () => {
150
+ describe('matrix-asset-uri input', () => {
151
+ const functionInputSchema = {
152
+ type: 'object',
153
+
154
+ properties: {
155
+ 'matrix-asset': { type: 'string', format: 'matrix-asset-uri', matrixAssetTypes: ['image'] },
156
+ },
157
+
158
+ required: ['matrix-asset'],
159
+ };
160
+ it('should return true for valid a string with matrix-asset-uri format', () => {
161
+ const validMatrixAssetUri = 'matrix-asset://canary.uat.matrix.squiz.cloud/abc123';
162
+ expect(
163
+ jsonValidationService.validateComponentInput(functionInputSchema, {
164
+ 'matrix-asset': validMatrixAssetUri,
165
+ }),
166
+ ).toEqual(true);
167
+ });
168
+ it('should throw error for invalid matrix-asset-uri format', () => {
169
+ const invalidMatrixAssetUri = 'not-valid://canary.uat.matrix.squiz.cloud//abc123';
170
+ expectToThrowErrorMatchingTypeAndMessage(
171
+ () => {
172
+ jsonValidationService.validateComponentInput(functionInputSchema, {
173
+ 'matrix-asset': invalidMatrixAssetUri,
174
+ });
175
+ },
176
+ SchemaValidationError,
177
+ `failed validation: value "not-valid://canary.uat.matrix.squiz.cloud//abc123" isn't a valid matrix asset uri`,
178
+ );
179
+ });
180
+ it('should throw error for invalid matrix-asset-uri type number', () => {
181
+ const invalidMatrixAssetUri = 1234;
182
+ expectToThrowErrorMatchingTypeAndMessage(
183
+ () => {
184
+ jsonValidationService.validateComponentInput(functionInputSchema, {
185
+ 'matrix-asset': invalidMatrixAssetUri,
186
+ });
187
+ },
188
+ SchemaValidationError,
189
+ 'failed validation: Expected `1234` (number) in `#/matrix-asset` to be of type `string`',
190
+ );
191
+ });
192
+ it('should throw error for invalid matrix-asset-uri which does not contain correct number of parts', () => {
193
+ const invalidMatrixAssetUri = 'matrix://';
194
+ expectToThrowErrorMatchingTypeAndMessage(
195
+ () => {
196
+ jsonValidationService.validateComponentInput(functionInputSchema, {
197
+ 'matrix-asset': invalidMatrixAssetUri,
198
+ });
199
+ },
200
+ SchemaValidationError,
201
+ `failed validation: value "matrix://" isn't a valid matrix asset uri`,
202
+ );
203
+ });
204
+ });
205
+
144
206
  describe('FormattedText input', () => {
145
207
  it('should handle type as an array', () => {
146
208
  const functionInputSchema = {
@@ -13,14 +13,18 @@ import { Draft07, JSONError, JSONSchema, Draft, DraftConfig, isJSONError } from
13
13
 
14
14
  import { draft07Config } from 'json-schema-library';
15
15
  import { MANIFEST_MODELS } from '.';
16
+ import { customFormatValidators } from './validators/customFormatValidators';
16
17
  import { AnyPrimitiveType, AnyResolvableType, TypeResolver } from './jsonTypeResolution/arbitraryTypeResolution';
17
18
  import { JsonResolutionError } from './errors/JsonResolutionError';
18
19
 
19
20
  const defaultConfig: DraftConfig = {
20
21
  ...draft07Config,
22
+ validateFormat: {
23
+ ...draft07Config.validateFormat,
24
+ ...customFormatValidators,
25
+ },
21
26
  errors: {
22
27
  ...draft07Config.errors,
23
-
24
28
  enumError(data) {
25
29
  let values = '[]';
26
30
 
@@ -140,7 +140,34 @@
140
140
  }
141
141
  ]
142
142
  },
143
- "format": { "type": "string" },
143
+ "format": {
144
+ "type": "string",
145
+ "enum": [
146
+ "date-time",
147
+ "email",
148
+ "hostname",
149
+ "ipv4",
150
+ "ipv6",
151
+ "json-pointer",
152
+ "matrix-asset-uri",
153
+ "multi-line",
154
+ "password",
155
+ "phone",
156
+ "regex",
157
+ "relative-json-pointer",
158
+ "uri-reference",
159
+ "uri-template",
160
+ "uri",
161
+ "uuid"
162
+ ]
163
+ },
164
+ "matrixAssetTypes": {
165
+ "type": "array",
166
+ "items": {
167
+ "type": "string",
168
+ "$ref": "#/matrixAssetEnum"
169
+ }
170
+ },
144
171
  "contentMediaType": { "type": "string" },
145
172
  "contentEncoding": { "type": "string" },
146
173
  "if": { "$ref": "#" },
@@ -161,5 +188,93 @@
161
188
  },
162
189
  "required": ["required"]
163
190
  }
191
+ },
192
+ "matrixAssetEnum": {
193
+ "enum": [
194
+ "audioFile",
195
+ "bodycopyContainer",
196
+ "bodycopyDiv",
197
+ "calendarEventsSearchPage",
198
+ "contentContainerTemplate",
199
+ "contentTypeMarkdown",
200
+ "contentTypeNestContent",
201
+ "contentTypeRawHtml",
202
+ "contentTypeSnippet",
203
+ "contentTypeWysiwyg",
204
+ "cssFileFolder",
205
+ "cssFile",
206
+ "customForm",
207
+ "dataRecord",
208
+ "designAreaAssetLineage",
209
+ "designAreaBody",
210
+ "designAreaMenuNormal",
211
+ "designAreaNestContent",
212
+ "designCssCustomisation",
213
+ "designCss",
214
+ "designCustomisation",
215
+ "designScss",
216
+ "design",
217
+ "docx",
218
+ "excelDoc",
219
+ "file",
220
+ "folder",
221
+ "gitBridge",
222
+ "googleAnalyticsConnector",
223
+ "googleAnalyticsView",
224
+ "image",
225
+ "jsFileFolder",
226
+ "jsFile",
227
+ "jsonWebToken",
228
+ "layoutManager",
229
+ "layout",
230
+ "link",
231
+ "metadataFieldDate",
232
+ "metadataFieldRelatedAsset",
233
+ "metadataFieldSelect",
234
+ "metadataFieldText",
235
+ "metadataFieldWysiwyg",
236
+ "metadataSchema",
237
+ "metadataSection",
238
+ "newsItem",
239
+ "oauthAccountManager",
240
+ "pageAccountManager",
241
+ "pageAssetListing",
242
+ "pageCalendarEventsSearch",
243
+ "pageCalendar",
244
+ "pagePasswordReset",
245
+ "pageRemoteContent",
246
+ "pageRestResourceJs",
247
+ "pageRestResourceOauthSession",
248
+ "pageRestResourceOauthTwoLegged",
249
+ "pageRestResource",
250
+ "pageSiteMap",
251
+ "pageStandard",
252
+ "paintLayoutBodycopy",
253
+ "paintLayoutPage",
254
+ "pdfFile",
255
+ "pdf",
256
+ "persona",
257
+ "powerpointDoc",
258
+ "pptx",
259
+ "redirectPage",
260
+ "regex",
261
+ "regularExpression",
262
+ "rtfFile",
263
+ "samlAccountManager",
264
+ "saml2Acs",
265
+ "saml2Sls",
266
+ "searchPage",
267
+ "site",
268
+ "textFile",
269
+ "TriggerTypes?",
270
+ "userGroup",
271
+ "wordDoc",
272
+ "workflowSchema",
273
+ "workflowStepCondition",
274
+ "workflowStep",
275
+ "workflowStream",
276
+ "xlsx",
277
+ "xmlFile"
278
+ ]
164
279
  }
165
280
  }
@@ -0,0 +1,29 @@
1
+ {
2
+ "$schema": "../../v1.json",
3
+ "description": "t",
4
+ "displayName": "t",
5
+ "name": "test",
6
+ "namespace": "other",
7
+ "mainFunction": "main",
8
+ "version": "1.0.4",
9
+ "environment": [],
10
+ "functions": [
11
+ {
12
+ "entry": "main.js",
13
+ "name": "main",
14
+ "output": {
15
+ "responseType": "html"
16
+ },
17
+ "input": {
18
+ "type": "object",
19
+ "properties": {
20
+ "prop": {
21
+ "type": "string",
22
+ "format": "matrix-asset-uri"
23
+ }
24
+ },
25
+ "required": []
26
+ }
27
+ }
28
+ ]
29
+ }
@@ -65,7 +65,109 @@ export type CoreSchemaMetaSchema2 =
65
65
  type?:
66
66
  | ('array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string' | 'FormattedText')
67
67
  | ('array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string' | 'FormattedText')[];
68
- format?: string;
68
+ format?:
69
+ | 'date-time'
70
+ | 'email'
71
+ | 'hostname'
72
+ | 'ipv4'
73
+ | 'ipv6'
74
+ | 'json-pointer'
75
+ | 'matrix-asset-uri'
76
+ | 'multi-line'
77
+ | 'password'
78
+ | 'phone'
79
+ | 'regex'
80
+ | 'relative-json-pointer'
81
+ | 'uri-reference'
82
+ | 'uri-template'
83
+ | 'uri'
84
+ | 'uuid';
85
+ matrixAssetTypes?: (
86
+ | 'audioFile'
87
+ | 'bodycopyContainer'
88
+ | 'bodycopyDiv'
89
+ | 'calendarEventsSearchPage'
90
+ | 'contentContainerTemplate'
91
+ | 'contentTypeMarkdown'
92
+ | 'contentTypeNestContent'
93
+ | 'contentTypeRawHtml'
94
+ | 'contentTypeSnippet'
95
+ | 'contentTypeWysiwyg'
96
+ | 'cssFileFolder'
97
+ | 'cssFile'
98
+ | 'customForm'
99
+ | 'dataRecord'
100
+ | 'designAreaAssetLineage'
101
+ | 'designAreaBody'
102
+ | 'designAreaMenuNormal'
103
+ | 'designAreaNestContent'
104
+ | 'designCssCustomisation'
105
+ | 'designCss'
106
+ | 'designCustomisation'
107
+ | 'designScss'
108
+ | 'design'
109
+ | 'docx'
110
+ | 'excelDoc'
111
+ | 'file'
112
+ | 'folder'
113
+ | 'gitBridge'
114
+ | 'googleAnalyticsConnector'
115
+ | 'googleAnalyticsView'
116
+ | 'image'
117
+ | 'jsFileFolder'
118
+ | 'jsFile'
119
+ | 'jsonWebToken'
120
+ | 'layoutManager'
121
+ | 'layout'
122
+ | 'link'
123
+ | 'metadataFieldDate'
124
+ | 'metadataFieldRelatedAsset'
125
+ | 'metadataFieldSelect'
126
+ | 'metadataFieldText'
127
+ | 'metadataFieldWysiwyg'
128
+ | 'metadataSchema'
129
+ | 'metadataSection'
130
+ | 'newsItem'
131
+ | 'oauthAccountManager'
132
+ | 'pageAccountManager'
133
+ | 'pageAssetListing'
134
+ | 'pageCalendarEventsSearch'
135
+ | 'pageCalendar'
136
+ | 'pagePasswordReset'
137
+ | 'pageRemoteContent'
138
+ | 'pageRestResourceJs'
139
+ | 'pageRestResourceOauthSession'
140
+ | 'pageRestResourceOauthTwoLegged'
141
+ | 'pageRestResource'
142
+ | 'pageSiteMap'
143
+ | 'pageStandard'
144
+ | 'paintLayoutBodycopy'
145
+ | 'paintLayoutPage'
146
+ | 'pdfFile'
147
+ | 'pdf'
148
+ | 'persona'
149
+ | 'powerpointDoc'
150
+ | 'pptx'
151
+ | 'redirectPage'
152
+ | 'regex'
153
+ | 'regularExpression'
154
+ | 'rtfFile'
155
+ | 'samlAccountManager'
156
+ | 'saml2Acs'
157
+ | 'saml2Sls'
158
+ | 'searchPage'
159
+ | 'site'
160
+ | 'textFile'
161
+ | 'TriggerTypes?'
162
+ | 'userGroup'
163
+ | 'wordDoc'
164
+ | 'workflowSchema'
165
+ | 'workflowStepCondition'
166
+ | 'workflowStep'
167
+ | 'workflowStream'
168
+ | 'xlsx'
169
+ | 'xmlFile'
170
+ )[];
69
171
  contentMediaType?: string;
70
172
  contentEncoding?: string;
71
173
  if?: CoreSchemaMetaSchema2;
@@ -2531,7 +2633,109 @@ export interface CoreSchemaMetaSchema1 {
2531
2633
  type?:
2532
2634
  | ('array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string' | 'FormattedText')
2533
2635
  | ('array' | 'boolean' | 'integer' | 'null' | 'number' | 'object' | 'string' | 'FormattedText')[];
2534
- format?: string;
2636
+ format?:
2637
+ | 'date-time'
2638
+ | 'email'
2639
+ | 'hostname'
2640
+ | 'ipv4'
2641
+ | 'ipv6'
2642
+ | 'json-pointer'
2643
+ | 'matrix-asset-uri'
2644
+ | 'multi-line'
2645
+ | 'password'
2646
+ | 'phone'
2647
+ | 'regex'
2648
+ | 'relative-json-pointer'
2649
+ | 'uri-reference'
2650
+ | 'uri-template'
2651
+ | 'uri'
2652
+ | 'uuid';
2653
+ matrixAssetTypes?: (
2654
+ | 'audioFile'
2655
+ | 'bodycopyContainer'
2656
+ | 'bodycopyDiv'
2657
+ | 'calendarEventsSearchPage'
2658
+ | 'contentContainerTemplate'
2659
+ | 'contentTypeMarkdown'
2660
+ | 'contentTypeNestContent'
2661
+ | 'contentTypeRawHtml'
2662
+ | 'contentTypeSnippet'
2663
+ | 'contentTypeWysiwyg'
2664
+ | 'cssFileFolder'
2665
+ | 'cssFile'
2666
+ | 'customForm'
2667
+ | 'dataRecord'
2668
+ | 'designAreaAssetLineage'
2669
+ | 'designAreaBody'
2670
+ | 'designAreaMenuNormal'
2671
+ | 'designAreaNestContent'
2672
+ | 'designCssCustomisation'
2673
+ | 'designCss'
2674
+ | 'designCustomisation'
2675
+ | 'designScss'
2676
+ | 'design'
2677
+ | 'docx'
2678
+ | 'excelDoc'
2679
+ | 'file'
2680
+ | 'folder'
2681
+ | 'gitBridge'
2682
+ | 'googleAnalyticsConnector'
2683
+ | 'googleAnalyticsView'
2684
+ | 'image'
2685
+ | 'jsFileFolder'
2686
+ | 'jsFile'
2687
+ | 'jsonWebToken'
2688
+ | 'layoutManager'
2689
+ | 'layout'
2690
+ | 'link'
2691
+ | 'metadataFieldDate'
2692
+ | 'metadataFieldRelatedAsset'
2693
+ | 'metadataFieldSelect'
2694
+ | 'metadataFieldText'
2695
+ | 'metadataFieldWysiwyg'
2696
+ | 'metadataSchema'
2697
+ | 'metadataSection'
2698
+ | 'newsItem'
2699
+ | 'oauthAccountManager'
2700
+ | 'pageAccountManager'
2701
+ | 'pageAssetListing'
2702
+ | 'pageCalendarEventsSearch'
2703
+ | 'pageCalendar'
2704
+ | 'pagePasswordReset'
2705
+ | 'pageRemoteContent'
2706
+ | 'pageRestResourceJs'
2707
+ | 'pageRestResourceOauthSession'
2708
+ | 'pageRestResourceOauthTwoLegged'
2709
+ | 'pageRestResource'
2710
+ | 'pageSiteMap'
2711
+ | 'pageStandard'
2712
+ | 'paintLayoutBodycopy'
2713
+ | 'paintLayoutPage'
2714
+ | 'pdfFile'
2715
+ | 'pdf'
2716
+ | 'persona'
2717
+ | 'powerpointDoc'
2718
+ | 'pptx'
2719
+ | 'redirectPage'
2720
+ | 'regex'
2721
+ | 'regularExpression'
2722
+ | 'rtfFile'
2723
+ | 'samlAccountManager'
2724
+ | 'saml2Acs'
2725
+ | 'saml2Sls'
2726
+ | 'searchPage'
2727
+ | 'site'
2728
+ | 'textFile'
2729
+ | 'TriggerTypes?'
2730
+ | 'userGroup'
2731
+ | 'wordDoc'
2732
+ | 'workflowSchema'
2733
+ | 'workflowStepCondition'
2734
+ | 'workflowStep'
2735
+ | 'workflowStream'
2736
+ | 'xlsx'
2737
+ | 'xmlFile'
2738
+ )[];
2535
2739
  contentMediaType?: string;
2536
2740
  contentEncoding?: string;
2537
2741
  if?: CoreSchemaMetaSchema2;
@@ -0,0 +1,15 @@
1
+ import { Draft, JSONError, JSONSchema } from 'json-schema-library';
2
+ import { SchemaValidationError } from '../errors/SchemaValidationError';
3
+ import { isMatrixAssetUri } from './utils/matrixAssetValidator';
4
+
5
+ export const customFormatValidators: Record<
6
+ string,
7
+ (draft: Draft, schema: JSONSchema, value: unknown, pointer: string) => undefined | JSONError | JSONError[]
8
+ > = {
9
+ 'matrix-asset-uri': (core, schema, value): undefined => {
10
+ if (isMatrixAssetUri(value) === false) {
11
+ throw new SchemaValidationError(`value "${value}" isn't a valid matrix asset uri`);
12
+ }
13
+ return;
14
+ },
15
+ };
@@ -0,0 +1,49 @@
1
+ import { isMatrixAssetUri } from './matrixAssetValidator';
2
+
3
+ describe('matrixAssetValidator', () => {
4
+ describe('should return true for valid matrix asset uri', () => {
5
+ it('with basic uri structure', () => {
6
+ expect(isMatrixAssetUri('matrix-asset://matrix.org/123')).toBe(true);
7
+ expect(isMatrixAssetUri('matrix-asset://dx.dev.matrix/123')).toBe(true);
8
+ expect(isMatrixAssetUri('matrix-asset://instance-identifier/123')).toBe(true);
9
+ });
10
+
11
+ it('different matrix identifiers', () => {
12
+ expect(isMatrixAssetUri('matrix-asset://MATRIX-IDENTIFIER.STRANGE-NAME.org/123')).toBe(true);
13
+ expect(isMatrixAssetUri('matrix-asset://matrix-identifier.STRANGE-NAME.org/123')).toBe(true);
14
+ });
15
+
16
+ it(' with different asset ids', () => {
17
+ expect(isMatrixAssetUri('matrix-asset://matrix.org/123/')).toBe(true);
18
+ expect(isMatrixAssetUri('matrix-asset://matrix.org/ASDFG1473189')).toBe(true);
19
+ expect(isMatrixAssetUri('matrix-asset://matrix.org/1-2-3-a-3/456/')).toBe(true);
20
+ expect(isMatrixAssetUri('matrix-asset://matrix.org/123/456/789')).toBe(true);
21
+ });
22
+ });
23
+
24
+ describe('should return false for invalid matrix asset uri', () => {
25
+ it('given incorrect type number', () => {
26
+ expect(isMatrixAssetUri(123)).toBe(false);
27
+ });
28
+
29
+ it('given incorrect type object', () => {
30
+ expect(isMatrixAssetUri({ test: 'invalid' })).toBe(false);
31
+ });
32
+
33
+ it('given incorrect value undefined', () => {
34
+ expect(isMatrixAssetUri(undefined)).toBe(false);
35
+ });
36
+
37
+ it('when the scheme is incorrect', () => {
38
+ expect(isMatrixAssetUri('invalid://matrix.org')).toBe(false);
39
+ });
40
+
41
+ it('when missing the asset id', () => {
42
+ expect(isMatrixAssetUri('matrix-asset://matrix.org/')).toBe(false);
43
+ });
44
+
45
+ it('when missing the asset path', () => {
46
+ expect(isMatrixAssetUri('matrix-asset:///123')).toBe(false);
47
+ });
48
+ });
49
+ });
@@ -0,0 +1,8 @@
1
+ export type MatrixAssetUri = `matrix-asset://${string}`;
2
+
3
+ export function isMatrixAssetUri(url: unknown): url is MatrixAssetUri {
4
+ if (typeof url !== 'string') return false;
5
+
6
+ /*eslint-disable no-useless-escape*/
7
+ return /^matrix-asset:\/\/[a-zA-Z0-9.-]+\/[a-zA-Z0-9\/._-]+\/?([0-9]+(?:\:[0-9a-z\-\._/]+\$?)?)?$/.test(url);
8
+ }