@extrahorizon/exh-cli 1.12.0-dev-145-36d98c7 → 1.12.0-dev-147-8845ed1
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/build/config-json-schemas/Dispatchers.json +120 -0
- package/build/helpers/util.d.ts +1 -0
- package/build/helpers/util.js +11 -1
- package/build/services/dispatchers.js +11 -39
- package/build/services/tasks/taskConfig.d.ts +1 -1
- package/build/services/tasks/taskConfig.js +1 -7
- package/package.json +1 -1
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"allOf": [
|
|
4
|
+
{
|
|
5
|
+
"oneOf": [
|
|
6
|
+
{ "type": "array" },
|
|
7
|
+
{ "type": "object" }
|
|
8
|
+
]
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"if": { "type": "object" },
|
|
12
|
+
"then": { "$ref": "#/definitions/Wrapper" }
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"if": { "type": "array" },
|
|
16
|
+
"then": {
|
|
17
|
+
"type": "array",
|
|
18
|
+
"items": { "$ref": "#/definitions/Dispatcher" }
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"definitions": {
|
|
23
|
+
"Wrapper": {
|
|
24
|
+
"type": "object",
|
|
25
|
+
"required": ["dispatchers"],
|
|
26
|
+
"properties": {
|
|
27
|
+
"dispatchers": {
|
|
28
|
+
"type": "array",
|
|
29
|
+
"items": { "$ref": "#/definitions/Dispatcher" }
|
|
30
|
+
},
|
|
31
|
+
"$schema": { "type": "string" }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"Dispatcher": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"required": ["eventType", "name", "actions"],
|
|
37
|
+
"properties": {
|
|
38
|
+
"eventType": { "type": "string" },
|
|
39
|
+
"name": { "type": "string" },
|
|
40
|
+
"description": { "type": "string" },
|
|
41
|
+
"actions": {
|
|
42
|
+
"type": "array",
|
|
43
|
+
"minItems": 1,
|
|
44
|
+
"items": { "$ref": "#/definitions/Action" }
|
|
45
|
+
},
|
|
46
|
+
"tags": {
|
|
47
|
+
"type": "array",
|
|
48
|
+
"items": { "type": "string" }
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"Action": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"required": ["type"],
|
|
55
|
+
"properties": {
|
|
56
|
+
"type": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"enum": ["mail", "task"]
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
"allOf": [
|
|
62
|
+
{
|
|
63
|
+
"if": { "properties": { "type": { "const": "mail" } } },
|
|
64
|
+
"then": { "$ref": "#/definitions/MailAction" }
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"if": { "properties": { "type": { "const": "task" } } },
|
|
68
|
+
"then": { "$ref": "#/definitions/TaskAction" }
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
"MailAction": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"required": ["type", "name", "recipients", "templateId"],
|
|
75
|
+
"properties": {
|
|
76
|
+
"type": { "const": "mail" },
|
|
77
|
+
"name": { "type": "string" },
|
|
78
|
+
"description": { "type": "string" },
|
|
79
|
+
"recipients": {
|
|
80
|
+
"type": "object",
|
|
81
|
+
"required": ["to"],
|
|
82
|
+
"properties": {
|
|
83
|
+
"to": {
|
|
84
|
+
"type": "array",
|
|
85
|
+
"items": { "type": "string" }
|
|
86
|
+
},
|
|
87
|
+
"cc": {
|
|
88
|
+
"type": "array",
|
|
89
|
+
"items": { "type": "string" }
|
|
90
|
+
},
|
|
91
|
+
"bcc": {
|
|
92
|
+
"type": "array",
|
|
93
|
+
"items": { "type": "string" }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"templateId": { "type": "string" }
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
"TaskAction": {
|
|
101
|
+
"type": "object",
|
|
102
|
+
"required": ["type", "name", "functionName"],
|
|
103
|
+
"properties": {
|
|
104
|
+
"type": { "const": "task" },
|
|
105
|
+
"name": { "type": "string" },
|
|
106
|
+
"description": { "type": "string" },
|
|
107
|
+
"functionName": { "type": "string" },
|
|
108
|
+
"data": {
|
|
109
|
+
"type": "object",
|
|
110
|
+
"additionalProperties": true
|
|
111
|
+
},
|
|
112
|
+
"tags": {
|
|
113
|
+
"type": "array",
|
|
114
|
+
"items": { "type": "string" }
|
|
115
|
+
},
|
|
116
|
+
"startTimestamp": { "type": "string" }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
package/build/helpers/util.d.ts
CHANGED
|
@@ -3,4 +3,5 @@ export declare function epilogue(y: yargs.Argv): yargs.Argv;
|
|
|
3
3
|
export declare function asyncExec(cmd: string): Promise<string>;
|
|
4
4
|
export declare function loadAndAssertCredentials(): void;
|
|
5
5
|
export declare function getSwaggerDocumentationUrl(subPath: string): string;
|
|
6
|
+
export declare function ajvValidate<T>(schema: any, data: any): asserts data is T;
|
|
6
7
|
export declare function getAjvErrorStrings(errors: any[]): string[];
|
package/build/helpers/util.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getAjvErrorStrings = exports.getSwaggerDocumentationUrl = exports.loadAndAssertCredentials = exports.asyncExec = exports.epilogue = void 0;
|
|
3
|
+
exports.getAjvErrorStrings = exports.ajvValidate = exports.getSwaggerDocumentationUrl = exports.loadAndAssertCredentials = exports.asyncExec = exports.epilogue = void 0;
|
|
4
4
|
const child_process_1 = require("child_process");
|
|
5
5
|
const fs = require("fs");
|
|
6
6
|
const path = require("path");
|
|
7
|
+
const ajv_1 = require("ajv");
|
|
7
8
|
const chalk = require("chalk");
|
|
8
9
|
const constants_1 = require("../constants");
|
|
9
10
|
const error_1 = require("./error");
|
|
@@ -80,6 +81,15 @@ function getSwaggerDocumentationUrl(subPath) {
|
|
|
80
81
|
throw new Error(`Unknown CLI version format: ${packageVersion}`);
|
|
81
82
|
}
|
|
82
83
|
exports.getSwaggerDocumentationUrl = getSwaggerDocumentationUrl;
|
|
84
|
+
function ajvValidate(schema, data) {
|
|
85
|
+
const validate = new ajv_1.default().compile(schema);
|
|
86
|
+
const valid = validate(data);
|
|
87
|
+
if (!valid) {
|
|
88
|
+
const errors = getAjvErrorStrings(validate.errors);
|
|
89
|
+
throw new Error(errors[0] || 'Unknown config validation error');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.ajvValidate = ajvValidate;
|
|
83
93
|
function getAjvErrorStrings(errors) {
|
|
84
94
|
return errors.map(error => {
|
|
85
95
|
let message = '';
|
|
@@ -4,14 +4,15 @@ exports.sync = exports.cliManagedTag = void 0;
|
|
|
4
4
|
const promises_1 = require("fs/promises");
|
|
5
5
|
const javascript_sdk_1 = require("@extrahorizon/javascript-sdk");
|
|
6
6
|
const chalk_1 = require("chalk");
|
|
7
|
+
const dispatcherSchema = require("../config-json-schemas/Dispatchers.json");
|
|
8
|
+
const util_1 = require("../helpers/util");
|
|
7
9
|
const dispatcherRepository = require("../repositories/dispatchers");
|
|
8
10
|
exports.cliManagedTag = 'EXH_CLI_MANAGED';
|
|
9
11
|
async function sync(path, clean = false) {
|
|
10
12
|
console.log((0, chalk_1.yellow)(`Synchronizing Dispatchers from ${path}`));
|
|
11
|
-
const localDispatchers = await
|
|
13
|
+
const localDispatchers = await readAndValidateDispatcherConfig(path);
|
|
12
14
|
const rql = (0, javascript_sdk_1.rqlBuilder)().eq('tags', exports.cliManagedTag).build();
|
|
13
15
|
const exhDispatchers = await dispatcherRepository.findAll(rql);
|
|
14
|
-
validateDispatchers(localDispatchers);
|
|
15
16
|
console.group((0, chalk_1.blue)('Synchronizing Dispatchers:'));
|
|
16
17
|
for (const localDispatcher of localDispatchers) {
|
|
17
18
|
const exhDispatcher = exhDispatchers.find(({ name }) => name === localDispatcher.name);
|
|
@@ -86,47 +87,18 @@ async function synchronizeActions(localDispatcher, exhDispatcher) {
|
|
|
86
87
|
}
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
|
-
async function
|
|
90
|
+
async function readAndValidateDispatcherConfig(path) {
|
|
91
|
+
let config;
|
|
90
92
|
try {
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
+
const buffer = await (0, promises_1.readFile)(path);
|
|
94
|
+
config = JSON.parse(buffer.toString());
|
|
93
95
|
}
|
|
94
96
|
catch (error) {
|
|
95
97
|
throw new Error(`Failed to read Dispatchers from ${path}: ${error.message}`);
|
|
96
98
|
}
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
console.group((0, chalk_1.blue)('Validating Dispatchers:'));
|
|
101
|
-
dispatchers.forEach((dispatcher, index) => {
|
|
102
|
-
const displayName = dispatcher.name ? `[${index}]: ${dispatcher.name}` : `[${index}]: NO_NAME`;
|
|
103
|
-
const errors = [];
|
|
104
|
-
if (!dispatcher.name) {
|
|
105
|
-
errors.push('No name');
|
|
106
|
-
}
|
|
107
|
-
const hasActions = Array.isArray(dispatcher.actions) && dispatcher.actions.length > 0;
|
|
108
|
-
if (!hasActions) {
|
|
109
|
-
errors.push('The actions value need to be an array with at least one object in it');
|
|
110
|
-
}
|
|
111
|
-
else {
|
|
112
|
-
dispatcher.actions.forEach((action, actionIndex) => {
|
|
113
|
-
if (!action.name) {
|
|
114
|
-
errors.push(`Action [${actionIndex}] does not have a name`);
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
if (errors.length === 0) {
|
|
119
|
-
console.log((0, chalk_1.green)(`✓ Valid Dispatcher: ${displayName}`));
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
hasErrors = true;
|
|
123
|
-
console.group((0, chalk_1.red)(`𝖷 Invalid Dispatcher: ${displayName}`));
|
|
124
|
-
errors.forEach(error => console.log((0, chalk_1.red)(`- ${error}`)));
|
|
125
|
-
console.groupEnd();
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
console.groupEnd();
|
|
129
|
-
if (hasErrors) {
|
|
130
|
-
throw new Error('\nThe dispatchers file is invalid');
|
|
99
|
+
(0, util_1.ajvValidate)(dispatcherSchema, config);
|
|
100
|
+
if (Array.isArray(config)) {
|
|
101
|
+
return config;
|
|
131
102
|
}
|
|
103
|
+
return config.dispatchers;
|
|
132
104
|
}
|
|
@@ -24,6 +24,6 @@ export interface TaskConfig {
|
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
export declare function assertExecutionPermission(mode: string): asserts mode is permissionModes | undefined;
|
|
27
|
-
export declare function validateConfig(config:
|
|
27
|
+
export declare function validateConfig(config: any): Promise<boolean>;
|
|
28
28
|
export declare function loadSingleConfigFile(path: string): Promise<TaskConfig>;
|
|
29
29
|
export declare function getValidatedConfigIterator({ path, name, code, entryPoint, runtime, description, timeLimit, memoryLimit, executionPermission, env, defaultPriority }: any): AsyncGenerator<TaskConfig>;
|
|
@@ -4,7 +4,6 @@ exports.getValidatedConfigIterator = exports.loadSingleConfigFile = exports.vali
|
|
|
4
4
|
const assert_1 = require("assert");
|
|
5
5
|
const fs = require("fs/promises");
|
|
6
6
|
const ospath = require("path");
|
|
7
|
-
const ajv_1 = require("ajv");
|
|
8
7
|
const taskConfigSchema = require("../../config-json-schemas/TaskConfig.json");
|
|
9
8
|
const util_1 = require("../../helpers/util");
|
|
10
9
|
var permissionModes;
|
|
@@ -52,12 +51,7 @@ function replaceConfigVariables(config) {
|
|
|
52
51
|
return result;
|
|
53
52
|
}
|
|
54
53
|
async function validateConfig(config) {
|
|
55
|
-
|
|
56
|
-
const valid = validate(config);
|
|
57
|
-
if (!valid) {
|
|
58
|
-
const errors = (0, util_1.getAjvErrorStrings)(validate.errors);
|
|
59
|
-
throw new Error(errors[0] || 'Unknown config validation error');
|
|
60
|
-
}
|
|
54
|
+
(0, util_1.ajvValidate)(taskConfigSchema, config);
|
|
61
55
|
try {
|
|
62
56
|
await fs.access(config.path);
|
|
63
57
|
}
|