@squiz/dx-json-schema-lib 1.39.1-alpha.0 → 1.39.1-alpha.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (34) hide show
  1. package/.npm/_logs/{2023-06-21T21_57_08_768Z-debug-0.log → 2023-06-22T07_21_57_071Z-debug-0.log} +16 -16
  2. package/jsonCompiler.ts +1 -0
  3. package/lib/JsonValidationService.d.ts +1 -1
  4. package/lib/JsonValidationService.js +7 -0
  5. package/lib/JsonValidationService.js.map +1 -1
  6. package/lib/manifest/v1/JobV1.d.ts +192 -0
  7. package/lib/manifest/v1/JobV1.js +9 -0
  8. package/lib/manifest/v1/JobV1.js.map +1 -0
  9. package/lib/manifest/v1/JobV1.json +88 -0
  10. package/lib/manifest/v1/JobV1.spec.d.ts +1 -0
  11. package/lib/manifest/v1/JobV1.spec.js +75 -0
  12. package/lib/manifest/v1/JobV1.spec.js.map +1 -0
  13. package/lib/manifest/v1/__test__/schemas/badFunctionInputJob.json +25 -0
  14. package/lib/manifest/v1/__test__/schemas/nonObjectFunctionInputJob.json +25 -0
  15. package/lib/manifest/v1/__test__/schemas/validJob.json +25 -0
  16. package/lib/manifest/v1/manifestModels.d.ts +1 -0
  17. package/lib/manifest/v1/manifestModels.js +2 -1
  18. package/lib/manifest/v1/manifestModels.js.map +1 -1
  19. package/lib/manifest/v1/manifestSchemas.d.ts +2 -1
  20. package/lib/manifest/v1/manifestSchemas.js +3 -1
  21. package/lib/manifest/v1/manifestSchemas.js.map +1 -1
  22. package/lib/manifest/v1/v1.json +26 -7
  23. package/package.json +2 -2
  24. package/src/JsonValidationService.ts +9 -1
  25. package/src/manifest/v1/JobV1.json +88 -0
  26. package/src/manifest/v1/JobV1.spec.ts +110 -0
  27. package/src/manifest/v1/JobV1.ts +447 -0
  28. package/src/manifest/v1/__test__/schemas/badFunctionInputJob.json +25 -0
  29. package/src/manifest/v1/__test__/schemas/nonObjectFunctionInputJob.json +25 -0
  30. package/src/manifest/v1/__test__/schemas/validJob.json +25 -0
  31. package/src/manifest/v1/manifestModels.ts +1 -0
  32. package/src/manifest/v1/manifestSchemas.ts +2 -1
  33. package/src/manifest/v1/v1.json +26 -14
  34. package/tsconfig.tsbuildinfo +1 -1
@@ -3,7 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.v1 = void 0;
6
+ exports.JobV1 = exports.v1 = void 0;
7
7
  const v1_json_1 = __importDefault(require("./v1.json"));
8
8
  exports.v1 = v1_json_1.default;
9
+ const JobV1_json_1 = __importDefault(require("./JobV1.json"));
10
+ exports.JobV1 = JobV1_json_1.default;
9
11
  //# sourceMappingURL=manifestSchemas.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifestSchemas.js","sourceRoot":"","sources":["../../../src/manifest/v1/manifestSchemas.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA2B;AAElB,aAFF,iBAAE,CAEE"}
1
+ {"version":3,"file":"manifestSchemas.js","sourceRoot":"","sources":["../../../src/manifest/v1/manifestSchemas.ts"],"names":[],"mappings":";;;;;;AAAA,wDAA2B;AAGlB,aAHF,iBAAE,CAGE;AAFX,8DAAiC;AAEpB,gBAFN,oBAAK,CAEM"}
@@ -4,15 +4,28 @@
4
4
  "title": "ComponentManifest",
5
5
  "additionalProperties": false,
6
6
  "properties": {
7
- "$schema": { "type": "string", "description": "the manifest schema version" },
7
+ "$schema": {
8
+ "type": "string",
9
+ "description": "the manifest schema version"
10
+ },
8
11
  "namespace": {
9
12
  "type": "string",
10
13
  "description": "Namespace of the component",
11
14
  "$ref": "#/definitions/name-pattern"
12
15
  },
13
- "name": { "type": "string", "description": "Name of the component", "$ref": "#/definitions/name-pattern" },
14
- "displayName": { "type": "string", "description": "Display name of the component" },
15
- "description": { "type": "string", "description": "Description of the component" },
16
+ "name": {
17
+ "type": "string",
18
+ "description": "Name of the component",
19
+ "$ref": "#/definitions/name-pattern"
20
+ },
21
+ "displayName": {
22
+ "type": "string",
23
+ "description": "Display name of the component"
24
+ },
25
+ "description": {
26
+ "type": "string",
27
+ "description": "Description of the component"
28
+ },
16
29
  "mainFunction": {
17
30
  "type": "string",
18
31
  "description": "Name of the main function to be executed at the root of the access url"
@@ -84,7 +97,9 @@
84
97
  "additionalProperties": false,
85
98
  "description": "The HtmlResponse type is for returning html content. The response out of the function must be a string. This response object also includes references to resources (staticFiles) the component needs to execute correctly. It is up to the integrating system to respect this.",
86
99
  "properties": {
87
- "responseType": { "const": "html" },
100
+ "responseType": {
101
+ "const": "html"
102
+ },
88
103
  "staticFiles": {
89
104
  "type": "array",
90
105
  "description": "A list of static resources that are required for the component to execute correctly",
@@ -251,8 +266,12 @@
251
266
  "type": "object",
252
267
  "additionalProperties": false,
253
268
  "properties": {
254
- "responseType": { "const": "json" },
255
- "definition": { "$ref": "http://json-schema.org/draft-07/schema#" },
269
+ "responseType": {
270
+ "const": "json"
271
+ },
272
+ "definition": {
273
+ "$ref": "http://json-schema.org/draft-07/schema#"
274
+ },
256
275
  "headers": {
257
276
  "title": "ResponseHeaders",
258
277
  "type": "object",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@squiz/dx-json-schema-lib",
3
- "version": "1.39.1-alpha.0",
3
+ "version": "1.39.1-alpha.2",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {
@@ -31,5 +31,5 @@
31
31
  "@squiz/json-schema-library": "7.4.7",
32
32
  "ts-brand": "0.0.2"
33
33
  },
34
- "gitHead": "7921b8f8edba43403eb4fe73f3473de7dfd52a17"
34
+ "gitHead": "00da2917377e7d2aa9e0ae7b2d51f9e8f5b671c0"
35
35
  }
@@ -11,6 +11,7 @@ import FormattedText from './formatted-text/v1/formattedText.json';
11
11
  import PageContentsSchema from './pageContents/v1/pageContents.json';
12
12
 
13
13
  import v1 from './manifest/v1/v1.json';
14
+ import JobV1 from './manifest/v1/JobV1.json';
14
15
  import { SchemaValidationError, ValidationData, ValidationDataMap } from './errors/SchemaValidationError';
15
16
  import { Draft07, JSONError, JSONSchema, Draft, DraftConfig } from '@squiz/json-schema-library';
16
17
 
@@ -152,6 +153,9 @@ v1Schema.addRemoteSchema('/MatrixAssetSchema.json', MatrixAssetSchema);
152
153
  v1Schema.addRemoteSchema('http://json-schema.org/draft-07/schema', Draft07Schema);
153
154
  v1Schema.addRemoteSchema('http://json-schema.org/draft-07/schema#', Draft07Schema);
154
155
 
156
+ const jobV1Schema = new Draft07(JobV1, defaultConfig);
157
+ jobV1Schema.addRemoteSchema('/DxComponentInputSchema.json', ComponentInputSchema.getSchema());
158
+
155
159
  export const ComponentInputMetaSchema: MetaSchemaInput = {
156
160
  root: DxComponentInputSchema,
157
161
  remotes: {
@@ -282,12 +286,16 @@ export class JSONSchemaService<P extends AnyPrimitiveType, R extends AnyResolvab
282
286
  }
283
287
 
284
288
  export class JsonValidationService {
285
- validateManifest(manifest: unknown, version: 'v1') {
289
+ validateManifest(manifest: unknown, version: 'v1' | 'JobV1') {
286
290
  switch (version) {
287
291
  case 'v1': {
288
292
  const validationResult = v1Schema.validate(manifest);
289
293
  return processValidationResult(validationResult);
290
294
  }
295
+ case 'JobV1': {
296
+ const validationResult = jobV1Schema.validate(manifest);
297
+ return processValidationResult(validationResult);
298
+ }
291
299
 
292
300
  default:
293
301
  throw new SchemaValidationError('Invalid manifest version');
@@ -0,0 +1,88 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "type": "object",
4
+ "title": "JobManifest",
5
+ "additionalProperties": false,
6
+ "properties": {
7
+ "$schema": {
8
+ "type": "string",
9
+ "description": "the manifest schema version"
10
+ },
11
+ "name": {
12
+ "type": "string",
13
+ "description": "Name of the job",
14
+ "$ref": "#/definitions/name-pattern"
15
+ },
16
+ "displayName": {
17
+ "type": "string",
18
+ "description": "Display name of the job"
19
+ },
20
+ "description": {
21
+ "type": "string",
22
+ "description": "Description of the job"
23
+ },
24
+ "mainFunction": {
25
+ "type": "string",
26
+ "description": "Name of the main function to be executed at the root of the access url"
27
+ },
28
+ "version": {
29
+ "type": "string",
30
+ "description": "Semver version number",
31
+ "minLength": 5,
32
+ "maxLength": 14,
33
+ "pattern": "^(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)\\.(?:0|[1-9]\\d*)$"
34
+ },
35
+ "timeout": {
36
+ "type": "number",
37
+ "description": "Timeout in seconds before a job is stopped (min 5s, max 8h)",
38
+ "minimum": 5,
39
+ "maximum": 28800
40
+ },
41
+ "concurrency": {
42
+ "type": "number",
43
+ "description": "The number of these jobs that can be run at once",
44
+ "minimum": 1
45
+ },
46
+ "functions": {
47
+ "type": "array",
48
+ "minItems": 0,
49
+ "items": {
50
+ "title": "JobFunction",
51
+ "description": "Job function definition, this object provides the runtime with input validation and what to execute",
52
+ "type": "object",
53
+ "properties": {
54
+ "name": {
55
+ "type": "string",
56
+ "$ref": "#/definitions/name-pattern",
57
+ "description": "Function name"
58
+ },
59
+ "entry": {
60
+ "type": "string",
61
+ "description": "File path to the javascript file to execute. The file path must be relative to the manifest file and cannot be in a folder above the manifest file."
62
+ },
63
+ "input": {
64
+ "$ref": "DxComponentInputSchema.json"
65
+ }
66
+ },
67
+ "required": ["name", "entry", "input"]
68
+ }
69
+ }
70
+ },
71
+ "required": [
72
+ "name",
73
+ "displayName",
74
+ "description",
75
+ "version",
76
+ "functions",
77
+ "$schema",
78
+ "mainFunction",
79
+ "concurrency",
80
+ "timeout"
81
+ ],
82
+ "definitions": {
83
+ "name-pattern": {
84
+ "type": "string",
85
+ "pattern": "^[a-z][a-z0-9_\\-]+$"
86
+ }
87
+ }
88
+ }
@@ -0,0 +1,110 @@
1
+ import { readFile } from 'fs/promises';
2
+ import { resolve } from 'path';
3
+ import { SchemaValidationError } from '../../errors/SchemaValidationError';
4
+ import { JsonValidationService } from '../../JsonValidationService';
5
+
6
+ const NAME_PATTERN = '^[a-z][a-z0-9_\\-]+$';
7
+
8
+ async function fetchTestManifest(filename: string) {
9
+ const contents = await readFile(resolve(__dirname, '__test__', 'schemas', filename), {
10
+ encoding: 'utf-8',
11
+ });
12
+ return JSON.parse(contents);
13
+ }
14
+ // eslint-disable-next-line @typescript-eslint/ban-types
15
+ function expectToThrowErrorMatchingTypeAndMessage(received: Function, errorType: Function, message: string) {
16
+ let error: null | Error = null;
17
+
18
+ try {
19
+ received();
20
+ } catch (e: any) {
21
+ error = e;
22
+ }
23
+
24
+ expect(error).toBeDefined();
25
+ expect(error?.message).toEqual(message);
26
+ expect(error).toBeInstanceOf(errorType);
27
+ }
28
+
29
+ describe('manifest/JobV1', () => {
30
+ let validationService: JsonValidationService;
31
+
32
+ beforeAll(() => {
33
+ validationService = new JsonValidationService();
34
+ });
35
+
36
+ it('succeeds on a valid manifest', async () => {
37
+ const manifest = await fetchTestManifest('validJob.json');
38
+ expect(validationService.validateManifest(manifest, 'JobV1')).toBeTruthy();
39
+ });
40
+
41
+ it('errors on invalid property types in function input', async () => {
42
+ const manifest = await fetchTestManifest('badFunctionInputJob.json');
43
+
44
+ expectToThrowErrorMatchingTypeAndMessage(
45
+ () => {
46
+ validationService.validateManifest(manifest, 'JobV1');
47
+ },
48
+ SchemaValidationError,
49
+ 'failed validation: Value `wrongType` at `#/functions/0/input/properties/something/type` does not match any schema',
50
+ );
51
+ });
52
+
53
+ it('errors on non-object top level input', async () => {
54
+ const manifest = await fetchTestManifest('nonObjectFunctionInputJob.json');
55
+ expectToThrowErrorMatchingTypeAndMessage(
56
+ () => {
57
+ validationService.validateManifest(manifest, 'JobV1');
58
+ },
59
+ SchemaValidationError,
60
+ 'failed validation: Expected value at `#/functions/0/input/type` to be `object`, but value given is `string`',
61
+ );
62
+ });
63
+
64
+ describe.each(['_my-name', '-my-name', 'MyName', 'myName', '0my-name'])(
65
+ 'fails name-pattern validation for %s',
66
+ (propertyValue) => {
67
+ it.each(['name'])(`fails validation for manifests with %s of ${propertyValue}`, async (propertyName) => {
68
+ const manifest = await fetchTestManifest('validJob.json');
69
+
70
+ expectToThrowErrorMatchingTypeAndMessage(
71
+ () => {
72
+ validationService.validateManifest(
73
+ {
74
+ ...manifest,
75
+ [propertyName]: propertyValue,
76
+ },
77
+ 'JobV1',
78
+ );
79
+ },
80
+ SchemaValidationError,
81
+ `failed validation: Value in \`#/${propertyName}\` should match \`${NAME_PATTERN}\`, but received \`${propertyValue}\``,
82
+ );
83
+ });
84
+
85
+ it('fails validation for manifests with function names of %s', async () => {
86
+ const manifest = await fetchTestManifest('validJob.json');
87
+
88
+ expectToThrowErrorMatchingTypeAndMessage(
89
+ () => {
90
+ validationService.validateManifest(
91
+ {
92
+ ...manifest,
93
+ functions: [
94
+ {
95
+ name: propertyValue,
96
+ entry: 'main.js',
97
+ input: {},
98
+ },
99
+ ],
100
+ },
101
+ 'JobV1',
102
+ );
103
+ },
104
+ SchemaValidationError,
105
+ `failed validation: Value in \`#/functions/0/name\` should match \`${NAME_PATTERN}\`, but received \`${propertyValue}\``,
106
+ );
107
+ });
108
+ },
109
+ );
110
+ });