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

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.
Files changed (27) hide show
  1. package/.npm/_logs/{2023-03-02T03_26_09_372Z-debug-0.log → 2023-03-06T05_16_32_570Z-debug-0.log} +14 -14
  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
+ }