suanpan_node_sdk 2.2.4 → 2.2.5
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/dist/api/index.d.ts +10 -10
- package/dist/api/index.js +56 -52
- package/dist/api/index.js.map +1 -1
- package/dist/core/common/constant.d.ts +6 -6
- package/dist/core/common/constant.js +50 -50
- package/dist/core/common/exec.d.ts +1 -1
- package/dist/core/common/exec.js +53 -53
- package/dist/core/common/log.d.ts +3 -3
- package/dist/core/common/log.js +15 -15
- package/dist/core/event/index.d.ts +6 -6
- package/dist/core/event/index.js +10 -10
- package/dist/core/logkit/index.d.ts +33 -33
- package/dist/core/logkit/index.js +125 -125
- package/dist/core/logkit/index.js.map +1 -1
- package/dist/core/message/channel.d.ts +7 -7
- package/dist/core/message/channel.js +2 -2
- package/dist/core/message/channelFactory.d.ts +4 -4
- package/dist/core/message/channelFactory.js +10 -10
- package/dist/core/message/index.d.ts +6 -6
- package/dist/core/message/index.js +22 -18
- package/dist/core/message/index.js.map +1 -1
- package/dist/core/message/message.d.ts +19 -19
- package/dist/core/message/message.js +59 -59
- package/dist/core/message/message.js.map +1 -1
- package/dist/core/message/messageBuilder.d.ts +12 -12
- package/dist/core/message/messageBuilder.js +50 -50
- package/dist/core/message/messageBuilder.js.map +1 -1
- package/dist/core/message/messageChain.d.ts +9 -9
- package/dist/core/message/messageChain.js +29 -29
- package/dist/core/message/messageListener.d.ts +4 -4
- package/dist/core/message/messageListener.js +11 -11
- package/dist/core/message/mq/index.d.ts +9 -9
- package/dist/core/message/mq/index.js +50 -50
- package/dist/core/message/mq/redis.d.ts +12 -12
- package/dist/core/message/mq/redis.js +101 -97
- package/dist/core/message/mq/redis.js.map +1 -1
- package/dist/core/parameter/commandArgs.d.ts +2 -2
- package/dist/core/parameter/commandArgs.js +22 -22
- package/dist/core/parameter/commandArgs.js.map +1 -1
- package/dist/core/parameter/environment.d.ts +86 -86
- package/dist/core/parameter/environment.js +103 -103
- package/dist/core/parameter/index.d.ts +7 -7
- package/dist/core/parameter/index.js +33 -33
- package/dist/core/script/script-babel/babel.d.ts +1 -1
- package/dist/core/script/script-babel/babel.js +23 -23
- package/dist/core/script/script-babel/plugin.d.ts +7 -7
- package/dist/core/script/script-babel/plugin.js +16 -16
- package/dist/core/script/script-constant.d.ts +36 -36
- package/dist/core/script/script-constant.js +70 -70
- package/dist/core/script/script-context.d.ts +1 -1
- package/dist/core/script/script-context.js +295 -295
- package/dist/core/script/script-front.d.ts +1 -1
- package/dist/core/script/script-front.js +201 -201
- package/dist/core/script/script-insert.d.ts +18 -18
- package/dist/core/script/script-insert.js +43 -43
- package/dist/core/script/script-manager.d.ts +74 -74
- package/dist/core/script/script-manager.js +261 -261
- package/dist/core/script/script-storage.d.ts +22 -22
- package/dist/core/script/script-storage.js +241 -241
- package/dist/core/script/script-support.d.ts +11 -11
- package/dist/core/script/script-support.js +140 -140
- package/dist/core/script/script-template.d.ts +1 -1
- package/dist/core/script/script-template.js +6 -6
- package/dist/core/service/port.d.ts +5 -5
- package/dist/core/service/port.js +53 -53
- package/dist/core/service/port.js.map +1 -1
- package/dist/core/storage/index.d.ts +5 -5
- package/dist/core/storage/index.js +21 -17
- package/dist/core/storage/index.js.map +1 -1
- package/dist/core/storage/minioStorage.d.ts +31 -28
- package/dist/core/storage/minioStorage.js +224 -209
- package/dist/core/storage/minioStorage.js.map +1 -1
- package/dist/core/storage/objectStorage.d.ts +23 -19
- package/dist/core/storage/objectStorage.js +3 -3
- package/dist/core/storage/ossStorage.d.ts +29 -26
- package/dist/core/storage/ossStorage.js +215 -193
- package/dist/core/storage/ossStorage.js.map +1 -1
- package/dist/core/storage/storageFlusher.d.ts +14 -14
- package/dist/core/storage/storageFlusher.js +54 -54
- package/dist/core/storage/storageLogger.d.ts +16 -16
- package/dist/core/storage/storageLogger.js +100 -100
- package/dist/core/storage/storageLogger.js.map +1 -1
- package/dist/core/storage/storagePath.d.ts +16 -16
- package/dist/core/storage/storagePath.js +49 -49
- package/dist/core/storage/wrapperStorage.d.ts +17 -17
- package/dist/core/storage/wrapperStorage.js +47 -47
- package/dist/core/storage/wrapperStorage.js.map +1 -1
- package/dist/core/utils/flusher.d.ts +18 -18
- package/dist/core/utils/flusher.js +66 -62
- package/dist/core/utils/flusher.js.map +1 -1
- package/dist/core/utils/http.d.ts +3 -3
- package/dist/core/utils/http.js +35 -35
- package/dist/core/utils/http.js.map +1 -1
- package/dist/core/utils/index.d.ts +57 -56
- package/dist/core/utils/index.js +247 -243
- package/dist/core/utils/index.js.map +1 -1
- package/dist/core/utils/number.d.ts +2 -2
- package/dist/core/utils/number.js +19 -19
- package/dist/core/utils/retry.d.ts +1 -1
- package/dist/core/utils/retry.js +34 -34
- package/dist/core/utils/retry.js.map +1 -1
- package/dist/core/utils/suanpan.d.ts +21 -20
- package/dist/core/utils/suanpan.js +103 -92
- package/dist/core/utils/suanpan.js.map +1 -1
- package/dist/core/web/app.d.ts +2 -2
- package/dist/core/web/app.js +38 -38
- package/dist/core/web/app.js.map +1 -1
- package/dist/core/web/server.d.ts +3 -3
- package/dist/core/web/server.js +64 -60
- package/dist/core/web/server.js.map +1 -1
- package/dist/main.d.ts +5 -5
- package/dist/main.js +28 -24
- package/dist/main.js.map +1 -1
- package/dist/types/conmonTypes.d.ts +21 -21
- package/dist/types/conmonTypes.js +16 -16
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.js +19 -15
- package/dist/types/index.js.map +1 -1
- package/dist/types/storageTypes.d.ts +59 -58
- package/dist/types/storageTypes.js +9 -9
- package/dist/types/streamTypes.d.ts +21 -21
- package/dist/types/streamTypes.js +2 -2
- package/package.json +1 -1
|
@@ -1,262 +1,262 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
exports.ScriptManager = void 0;
|
|
16
|
-
const _ = require('lodash');
|
|
17
|
-
const log_1 = __importDefault(require("../common/log"));
|
|
18
|
-
const babel = require('./script-babel/babel');
|
|
19
|
-
const scriptTpl = require('./script-template');
|
|
20
|
-
const EventEmitter = require('events');
|
|
21
|
-
const ScriptInsert = require('./script-insert');
|
|
22
|
-
const requireFromString = require('require-from-string');
|
|
23
|
-
const { tryJSONParse } = require('../utils');
|
|
24
|
-
const { AppScriptContext, NodeScriptContext } = require('./script-context');
|
|
25
|
-
const { PRE_IN, POST_OUT, HANDLERS, SCRIPT_LOG, PORT_IN_REG, CONSOLE_REG, INITIALIZEFN, PORT_OUT_REG, LEFT_BRACKET, RIGHT_BRACKET, RETURN_STATEMENT, INJECTED_MODULES, BUILT_IN_MODULES, RIGHT_CURLY_BRACKET, SYSTEM_MESSAGE_HANDLERS, CLOSURE_PARAMETER_DEFINITION } = require('./script-constant');
|
|
26
|
-
class HandlerRepository {
|
|
27
|
-
constructor(handlers = {}) {
|
|
28
|
-
this.handlers = handlers;
|
|
29
|
-
}
|
|
30
|
-
addHandler(nodeId, portId, when, handler) {
|
|
31
|
-
const h = this.handlers;
|
|
32
|
-
h[nodeId] = h[nodeId] || {};
|
|
33
|
-
h[nodeId][portId] = h[nodeId][portId] || {};
|
|
34
|
-
h[nodeId][portId][when] = handler;
|
|
35
|
-
}
|
|
36
|
-
findHandler(nodeId, portId, when) {
|
|
37
|
-
const h = this.handlers;
|
|
38
|
-
if (h[nodeId] && h[nodeId][portId]) {
|
|
39
|
-
return h[nodeId][portId][when];
|
|
40
|
-
}
|
|
41
|
-
return null;
|
|
42
|
-
}
|
|
43
|
-
addAll(handlers) {
|
|
44
|
-
this.handlers = Object.assign(this.handlers, handlers);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
class ScriptManager extends EventEmitter {
|
|
48
|
-
constructor(userId, appId, opt = {}) {
|
|
49
|
-
super();
|
|
50
|
-
this.userId = userId;
|
|
51
|
-
this.appId = appId;
|
|
52
|
-
this.portTypes = opt.portTypes;
|
|
53
|
-
this.spmqClient = opt.spmqClient;
|
|
54
|
-
this.utils = opt.utils || {};
|
|
55
|
-
this.enabled = true;
|
|
56
|
-
this.handlerRepo = new HandlerRepository();
|
|
57
|
-
this.appScriptContext = new AppScriptContext(this.userId, this.appId, this.portTypes, this.spmqClient, this.utils, BUILT_IN_MODULES, this);
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* @param {string} scriptCode
|
|
61
|
-
* @returns {string}
|
|
62
|
-
(function(@function generateFormalParameter {
|
|
63
|
-
(function() { ... })();
|
|
64
|
-
(function() { ... })();
|
|
65
|
-
return @constant RETURN_STATEMENT
|
|
66
|
-
})
|
|
67
|
-
*/
|
|
68
|
-
buildExecutionContext(scriptCode) {
|
|
69
|
-
return new ScriptInsert(scriptCode)
|
|
70
|
-
.updateInsertIndex(LEFT_BRACKET, 2, true)
|
|
71
|
-
.insert(this.generateFormalParameter())
|
|
72
|
-
.updateInsertIndex(RIGHT_CURLY_BRACKET, 1)
|
|
73
|
-
.insert(RETURN_STATEMENT, { leftInsert: true })
|
|
74
|
-
.updateInsertIndex(RIGHT_BRACKET, 1)
|
|
75
|
-
.insert(' ', { replace: true })
|
|
76
|
-
.updateInsertIndex(LEFT_BRACKET, 1)
|
|
77
|
-
.insert(' ', { replace: true })
|
|
78
|
-
.get();
|
|
79
|
-
}
|
|
80
|
-
handleInputWithBabel(input) {
|
|
81
|
-
// 1. build execution context
|
|
82
|
-
const scriptCode = this.buildExecutionContext(input);
|
|
83
|
-
// 2. replace log
|
|
84
|
-
const replaceContent = scriptCode.replace(CONSOLE_REG, SCRIPT_LOG);
|
|
85
|
-
// 3. babel trnasform
|
|
86
|
-
const babelResult = babel.transform(replaceContent);
|
|
87
|
-
// 4. return the code generated by babel
|
|
88
|
-
return babelResult.code;
|
|
89
|
-
}
|
|
90
|
-
/**
|
|
91
|
-
* @param {*} scriptInput script content
|
|
92
|
-
*/
|
|
93
|
-
parseScripts(scriptInput, globalHook = true) {
|
|
94
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
-
log_1.default.debug('scriptInput is: %s', scriptInput);
|
|
96
|
-
if (_.isEmpty(scriptInput)) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
try {
|
|
100
|
-
log_1.default.debug('start parse script...');
|
|
101
|
-
const compiledCode = this.handleInputWithBabel(scriptInput);
|
|
102
|
-
log_1.default.debug('code converted by babel is: %s', compiledCode);
|
|
103
|
-
const scriptTemplate = this.generateSrciptTemplate(compiledCode);
|
|
104
|
-
log_1.default.debug('generated script template is: %s', scriptTemplate);
|
|
105
|
-
const exportedScriptFn = this.exportScriptTemplate(scriptTemplate);
|
|
106
|
-
const resultOfExportedFn = this.executeFunction(exportedScriptFn, this.appScriptContext, ...this.getInjectedModules());
|
|
107
|
-
const handlers = resultOfExportedFn[HANDLERS];
|
|
108
|
-
const initializeFn = resultOfExportedFn[INITIALIZEFN];
|
|
109
|
-
const systemMessageHandlers = resultOfExportedFn[SYSTEM_MESSAGE_HANDLERS];
|
|
110
|
-
this.storeHandlers(handlers, systemMessageHandlers);
|
|
111
|
-
if (globalHook && initializeFn && _.isFunction(initializeFn) && this.enabled) {
|
|
112
|
-
yield this.executeAsyncFunction(initializeFn, this.appScriptContext);
|
|
113
|
-
}
|
|
114
|
-
log_1.default.debug('parsed successfully.');
|
|
115
|
-
}
|
|
116
|
-
catch (err) {
|
|
117
|
-
this.emitToSuanpanWeb('scriptParseError', { err: this.serializeError(err) });
|
|
118
|
-
throw new Error(`Script parsing failed, ${err}`);
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* @param {string} outNodeId
|
|
124
|
-
* @param {object} data { out[N]: xxxx }
|
|
125
|
-
* @param {object} extra
|
|
126
|
-
*/
|
|
127
|
-
postOut(outNodeId, data, extra) {
|
|
128
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
-
yield this.process(outNodeId, POST_OUT, data, extra);
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* @param {string} outNodeId
|
|
134
|
-
* @param {string} inNodeId
|
|
135
|
-
* @param {object} data { in[N]: xxxx }
|
|
136
|
-
* @param {object} extra
|
|
137
|
-
*/
|
|
138
|
-
preIn(outNodeId, inNodeId, data, extra) {
|
|
139
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
-
yield this.process(inNodeId, PRE_IN, data, extra);
|
|
141
|
-
});
|
|
142
|
-
}
|
|
143
|
-
process(nodeId, when, data, extra = {}) {
|
|
144
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
145
|
-
log_1.default.debug('start execute hanlder...');
|
|
146
|
-
let port;
|
|
147
|
-
try {
|
|
148
|
-
log_1.default.debug('(nodeId: \'%s\', when: \'%s\', data: %j, extra: %j)', nodeId, when, data, extra);
|
|
149
|
-
port = this.getTargetPort(when, data);
|
|
150
|
-
if (!this.enabled) {
|
|
151
|
-
log_1.default.debug('(userId: \'%s\', appId: \'%s\', nodeId: \'%s\', port: \'%s\', when: \'%s\') ' +
|
|
152
|
-
'The script\'s switch is off, skipping processing...', this.userId, this.appId, nodeId, port, when);
|
|
153
|
-
return;
|
|
154
|
-
}
|
|
155
|
-
const handler = this.handlerRepo.findHandler(nodeId, port, when);
|
|
156
|
-
if (!handler || !handler.enabled) {
|
|
157
|
-
log_1.default.debug('No handler was found, skip.');
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
const raw = data[port];
|
|
161
|
-
const parsedData = tryJSONParse(raw);
|
|
162
|
-
const nodeScriptContext = new NodeScriptContext(this.userId, this.appId, nodeId, port, when, data, extra, this.spmqClient, this.portTypes, this.utils, this, this.appScriptContext.g || {}, BUILT_IN_MODULES);
|
|
163
|
-
yield handler.handle(parsedData, nodeScriptContext);
|
|
164
|
-
this.emitToSuanpanWeb('scriptProcessed', { node: nodeId, port, when, before: raw, after: data[port] });
|
|
165
|
-
log_1.default.debug('execute successfully.');
|
|
166
|
-
}
|
|
167
|
-
catch (err) {
|
|
168
|
-
log_1.default.error(`(${this.userId},${this.appId},${nodeId},${port},${when}) process failed:`, err);
|
|
169
|
-
this.emitToSuanpanWeb('scriptRuntimeError', { node: nodeId, port, when, err: this.serializeError(err) });
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
serializeError(ex) {
|
|
174
|
-
return {
|
|
175
|
-
message: ex.message,
|
|
176
|
-
stack: ex.stack
|
|
177
|
-
};
|
|
178
|
-
}
|
|
179
|
-
generateFormalParameter() {
|
|
180
|
-
const injectedModuleNames = Object.keys(INJECTED_MODULES);
|
|
181
|
-
return [CLOSURE_PARAMETER_DEFINITION, ...injectedModuleNames].join(',');
|
|
182
|
-
}
|
|
183
|
-
getInjectedModules() {
|
|
184
|
-
return _.values(INJECTED_MODULES);
|
|
185
|
-
}
|
|
186
|
-
generateSrciptTemplate(code) {
|
|
187
|
-
return scriptTpl.generateTemplate(code);
|
|
188
|
-
}
|
|
189
|
-
exportScriptTemplate(moduleString) {
|
|
190
|
-
try {
|
|
191
|
-
// https://github.com/floatdrop/require-from-string/issues/23
|
|
192
|
-
return requireFromString(moduleString, { appendPaths: __dirname });
|
|
193
|
-
}
|
|
194
|
-
catch (err) {
|
|
195
|
-
throw new Error(`error when require from modle string. ${err}`);
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
storeHandlers(handlers, systemMessageHandlers) {
|
|
199
|
-
log_1.default.debug('The handles collected by HandlerRepository is %O:', handlers);
|
|
200
|
-
log_1.default.debug('The handles collected by SystemMessageHandlers is %O:', systemMessageHandlers);
|
|
201
|
-
this.handlerRepo.addAll(handlers);
|
|
202
|
-
this.systemMessageHandlers = systemMessageHandlers;
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* handle system message callback
|
|
206
|
-
* @param {*} nodeId
|
|
207
|
-
* @param {*} data
|
|
208
|
-
*/
|
|
209
|
-
processSystemMessage(nodeId, data) {
|
|
210
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
211
|
-
log_1.default.debug('start execute system message hanlder...');
|
|
212
|
-
if (!this.systemMessageHandlers || !this.systemMessageHandlers[nodeId]) {
|
|
213
|
-
log_1.default.debug(`no system message handler was found, nodeId: ${nodeId}`);
|
|
214
|
-
return;
|
|
215
|
-
}
|
|
216
|
-
const systemMessageCallBack = this.systemMessageHandlers[nodeId];
|
|
217
|
-
try {
|
|
218
|
-
yield systemMessageCallBack(this.appScriptContext);
|
|
219
|
-
}
|
|
220
|
-
catch (e) {
|
|
221
|
-
throw new Error(`CallbackError: nodeId: ${nodeId}, data: ${JSON.stringify(data)}, e: ${e}`);
|
|
222
|
-
}
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
executeFunction(fn, ...args) {
|
|
226
|
-
if (!_.isFunction(fn)) {
|
|
227
|
-
throw new Error(`TypeError: ${fn} is not function.`);
|
|
228
|
-
}
|
|
229
|
-
return fn(...args);
|
|
230
|
-
}
|
|
231
|
-
executeAsyncFunction(fn, ...args) {
|
|
232
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
233
|
-
if (!_.isFunction(fn)) {
|
|
234
|
-
throw new Error(`TypeError: ${fn} is not function.`);
|
|
235
|
-
}
|
|
236
|
-
return yield fn(...args);
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
/**
|
|
240
|
-
* @param {object} data { <in/out>[N]: xxxx }
|
|
241
|
-
* @param {regular expression} regx
|
|
242
|
-
*/
|
|
243
|
-
filterKeybyRegx(data, regx) {
|
|
244
|
-
return Object.keys(data).filter((key) => key.match(regx));
|
|
245
|
-
}
|
|
246
|
-
getTargetPort(when, data) {
|
|
247
|
-
if (when === POST_OUT) {
|
|
248
|
-
return _.head(this.filterKeybyRegx(data, PORT_OUT_REG));
|
|
249
|
-
}
|
|
250
|
-
else if (when === PRE_IN) {
|
|
251
|
-
return _.head(this.filterKeybyRegx(data, PORT_IN_REG));
|
|
252
|
-
}
|
|
253
|
-
throw new Error(`invalid argument when = ${when}`);
|
|
254
|
-
}
|
|
255
|
-
emitToSuanpanWeb() {
|
|
256
|
-
if (this.utils.emitEventToSuanpanWeb) {
|
|
257
|
-
this.utils.emitEventToSuanpanWeb(...arguments);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
exports.ScriptManager = ScriptManager;
|
|
1
|
+
'use strict';
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ScriptManager = void 0;
|
|
16
|
+
const _ = require('lodash');
|
|
17
|
+
const log_1 = __importDefault(require("../common/log"));
|
|
18
|
+
const babel = require('./script-babel/babel');
|
|
19
|
+
const scriptTpl = require('./script-template');
|
|
20
|
+
const EventEmitter = require('events');
|
|
21
|
+
const ScriptInsert = require('./script-insert');
|
|
22
|
+
const requireFromString = require('require-from-string');
|
|
23
|
+
const { tryJSONParse } = require('../utils');
|
|
24
|
+
const { AppScriptContext, NodeScriptContext } = require('./script-context');
|
|
25
|
+
const { PRE_IN, POST_OUT, HANDLERS, SCRIPT_LOG, PORT_IN_REG, CONSOLE_REG, INITIALIZEFN, PORT_OUT_REG, LEFT_BRACKET, RIGHT_BRACKET, RETURN_STATEMENT, INJECTED_MODULES, BUILT_IN_MODULES, RIGHT_CURLY_BRACKET, SYSTEM_MESSAGE_HANDLERS, CLOSURE_PARAMETER_DEFINITION } = require('./script-constant');
|
|
26
|
+
class HandlerRepository {
|
|
27
|
+
constructor(handlers = {}) {
|
|
28
|
+
this.handlers = handlers;
|
|
29
|
+
}
|
|
30
|
+
addHandler(nodeId, portId, when, handler) {
|
|
31
|
+
const h = this.handlers;
|
|
32
|
+
h[nodeId] = h[nodeId] || {};
|
|
33
|
+
h[nodeId][portId] = h[nodeId][portId] || {};
|
|
34
|
+
h[nodeId][portId][when] = handler;
|
|
35
|
+
}
|
|
36
|
+
findHandler(nodeId, portId, when) {
|
|
37
|
+
const h = this.handlers;
|
|
38
|
+
if (h[nodeId] && h[nodeId][portId]) {
|
|
39
|
+
return h[nodeId][portId][when];
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
addAll(handlers) {
|
|
44
|
+
this.handlers = Object.assign(this.handlers, handlers);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
class ScriptManager extends EventEmitter {
|
|
48
|
+
constructor(userId, appId, opt = {}) {
|
|
49
|
+
super();
|
|
50
|
+
this.userId = userId;
|
|
51
|
+
this.appId = appId;
|
|
52
|
+
this.portTypes = opt.portTypes;
|
|
53
|
+
this.spmqClient = opt.spmqClient;
|
|
54
|
+
this.utils = opt.utils || {};
|
|
55
|
+
this.enabled = true;
|
|
56
|
+
this.handlerRepo = new HandlerRepository();
|
|
57
|
+
this.appScriptContext = new AppScriptContext(this.userId, this.appId, this.portTypes, this.spmqClient, this.utils, BUILT_IN_MODULES, this);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* @param {string} scriptCode
|
|
61
|
+
* @returns {string}
|
|
62
|
+
(function(@function generateFormalParameter {
|
|
63
|
+
(function() { ... })();
|
|
64
|
+
(function() { ... })();
|
|
65
|
+
return @constant RETURN_STATEMENT
|
|
66
|
+
})
|
|
67
|
+
*/
|
|
68
|
+
buildExecutionContext(scriptCode) {
|
|
69
|
+
return new ScriptInsert(scriptCode)
|
|
70
|
+
.updateInsertIndex(LEFT_BRACKET, 2, true)
|
|
71
|
+
.insert(this.generateFormalParameter())
|
|
72
|
+
.updateInsertIndex(RIGHT_CURLY_BRACKET, 1)
|
|
73
|
+
.insert(RETURN_STATEMENT, { leftInsert: true })
|
|
74
|
+
.updateInsertIndex(RIGHT_BRACKET, 1)
|
|
75
|
+
.insert(' ', { replace: true })
|
|
76
|
+
.updateInsertIndex(LEFT_BRACKET, 1)
|
|
77
|
+
.insert(' ', { replace: true })
|
|
78
|
+
.get();
|
|
79
|
+
}
|
|
80
|
+
handleInputWithBabel(input) {
|
|
81
|
+
// 1. build execution context
|
|
82
|
+
const scriptCode = this.buildExecutionContext(input);
|
|
83
|
+
// 2. replace log
|
|
84
|
+
const replaceContent = scriptCode.replace(CONSOLE_REG, SCRIPT_LOG);
|
|
85
|
+
// 3. babel trnasform
|
|
86
|
+
const babelResult = babel.transform(replaceContent);
|
|
87
|
+
// 4. return the code generated by babel
|
|
88
|
+
return babelResult.code;
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* @param {*} scriptInput script content
|
|
92
|
+
*/
|
|
93
|
+
parseScripts(scriptInput, globalHook = true) {
|
|
94
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
log_1.default.debug('scriptInput is: %s', scriptInput);
|
|
96
|
+
if (_.isEmpty(scriptInput)) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
log_1.default.debug('start parse script...');
|
|
101
|
+
const compiledCode = this.handleInputWithBabel(scriptInput);
|
|
102
|
+
log_1.default.debug('code converted by babel is: %s', compiledCode);
|
|
103
|
+
const scriptTemplate = this.generateSrciptTemplate(compiledCode);
|
|
104
|
+
log_1.default.debug('generated script template is: %s', scriptTemplate);
|
|
105
|
+
const exportedScriptFn = this.exportScriptTemplate(scriptTemplate);
|
|
106
|
+
const resultOfExportedFn = this.executeFunction(exportedScriptFn, this.appScriptContext, ...this.getInjectedModules());
|
|
107
|
+
const handlers = resultOfExportedFn[HANDLERS];
|
|
108
|
+
const initializeFn = resultOfExportedFn[INITIALIZEFN];
|
|
109
|
+
const systemMessageHandlers = resultOfExportedFn[SYSTEM_MESSAGE_HANDLERS];
|
|
110
|
+
this.storeHandlers(handlers, systemMessageHandlers);
|
|
111
|
+
if (globalHook && initializeFn && _.isFunction(initializeFn) && this.enabled) {
|
|
112
|
+
yield this.executeAsyncFunction(initializeFn, this.appScriptContext);
|
|
113
|
+
}
|
|
114
|
+
log_1.default.debug('parsed successfully.');
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
this.emitToSuanpanWeb('scriptParseError', { err: this.serializeError(err) });
|
|
118
|
+
throw new Error(`Script parsing failed, ${err}`);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* @param {string} outNodeId
|
|
124
|
+
* @param {object} data { out[N]: xxxx }
|
|
125
|
+
* @param {object} extra
|
|
126
|
+
*/
|
|
127
|
+
postOut(outNodeId, data, extra) {
|
|
128
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
+
yield this.process(outNodeId, POST_OUT, data, extra);
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* @param {string} outNodeId
|
|
134
|
+
* @param {string} inNodeId
|
|
135
|
+
* @param {object} data { in[N]: xxxx }
|
|
136
|
+
* @param {object} extra
|
|
137
|
+
*/
|
|
138
|
+
preIn(outNodeId, inNodeId, data, extra) {
|
|
139
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
140
|
+
yield this.process(inNodeId, PRE_IN, data, extra);
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
process(nodeId, when, data, extra = {}) {
|
|
144
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
145
|
+
log_1.default.debug('start execute hanlder...');
|
|
146
|
+
let port;
|
|
147
|
+
try {
|
|
148
|
+
log_1.default.debug('(nodeId: \'%s\', when: \'%s\', data: %j, extra: %j)', nodeId, when, data, extra);
|
|
149
|
+
port = this.getTargetPort(when, data);
|
|
150
|
+
if (!this.enabled) {
|
|
151
|
+
log_1.default.debug('(userId: \'%s\', appId: \'%s\', nodeId: \'%s\', port: \'%s\', when: \'%s\') ' +
|
|
152
|
+
'The script\'s switch is off, skipping processing...', this.userId, this.appId, nodeId, port, when);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const handler = this.handlerRepo.findHandler(nodeId, port, when);
|
|
156
|
+
if (!handler || !handler.enabled) {
|
|
157
|
+
log_1.default.debug('No handler was found, skip.');
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const raw = data[port];
|
|
161
|
+
const parsedData = tryJSONParse(raw);
|
|
162
|
+
const nodeScriptContext = new NodeScriptContext(this.userId, this.appId, nodeId, port, when, data, extra, this.spmqClient, this.portTypes, this.utils, this, this.appScriptContext.g || {}, BUILT_IN_MODULES);
|
|
163
|
+
yield handler.handle(parsedData, nodeScriptContext);
|
|
164
|
+
this.emitToSuanpanWeb('scriptProcessed', { node: nodeId, port, when, before: raw, after: data[port] });
|
|
165
|
+
log_1.default.debug('execute successfully.');
|
|
166
|
+
}
|
|
167
|
+
catch (err) {
|
|
168
|
+
log_1.default.error(`(${this.userId},${this.appId},${nodeId},${port},${when}) process failed:`, err);
|
|
169
|
+
this.emitToSuanpanWeb('scriptRuntimeError', { node: nodeId, port, when, err: this.serializeError(err) });
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
serializeError(ex) {
|
|
174
|
+
return {
|
|
175
|
+
message: ex.message,
|
|
176
|
+
stack: ex.stack
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
generateFormalParameter() {
|
|
180
|
+
const injectedModuleNames = Object.keys(INJECTED_MODULES);
|
|
181
|
+
return [CLOSURE_PARAMETER_DEFINITION, ...injectedModuleNames].join(',');
|
|
182
|
+
}
|
|
183
|
+
getInjectedModules() {
|
|
184
|
+
return _.values(INJECTED_MODULES);
|
|
185
|
+
}
|
|
186
|
+
generateSrciptTemplate(code) {
|
|
187
|
+
return scriptTpl.generateTemplate(code);
|
|
188
|
+
}
|
|
189
|
+
exportScriptTemplate(moduleString) {
|
|
190
|
+
try {
|
|
191
|
+
// https://github.com/floatdrop/require-from-string/issues/23
|
|
192
|
+
return requireFromString(moduleString, { appendPaths: __dirname });
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
throw new Error(`error when require from modle string. ${err}`);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
storeHandlers(handlers, systemMessageHandlers) {
|
|
199
|
+
log_1.default.debug('The handles collected by HandlerRepository is %O:', handlers);
|
|
200
|
+
log_1.default.debug('The handles collected by SystemMessageHandlers is %O:', systemMessageHandlers);
|
|
201
|
+
this.handlerRepo.addAll(handlers);
|
|
202
|
+
this.systemMessageHandlers = systemMessageHandlers;
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* handle system message callback
|
|
206
|
+
* @param {*} nodeId
|
|
207
|
+
* @param {*} data
|
|
208
|
+
*/
|
|
209
|
+
processSystemMessage(nodeId, data) {
|
|
210
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
211
|
+
log_1.default.debug('start execute system message hanlder...');
|
|
212
|
+
if (!this.systemMessageHandlers || !this.systemMessageHandlers[nodeId]) {
|
|
213
|
+
log_1.default.debug(`no system message handler was found, nodeId: ${nodeId}`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const systemMessageCallBack = this.systemMessageHandlers[nodeId];
|
|
217
|
+
try {
|
|
218
|
+
yield systemMessageCallBack(this.appScriptContext);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
throw new Error(`CallbackError: nodeId: ${nodeId}, data: ${JSON.stringify(data)}, e: ${e}`);
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
executeFunction(fn, ...args) {
|
|
226
|
+
if (!_.isFunction(fn)) {
|
|
227
|
+
throw new Error(`TypeError: ${fn} is not function.`);
|
|
228
|
+
}
|
|
229
|
+
return fn(...args);
|
|
230
|
+
}
|
|
231
|
+
executeAsyncFunction(fn, ...args) {
|
|
232
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
233
|
+
if (!_.isFunction(fn)) {
|
|
234
|
+
throw new Error(`TypeError: ${fn} is not function.`);
|
|
235
|
+
}
|
|
236
|
+
return yield fn(...args);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* @param {object} data { <in/out>[N]: xxxx }
|
|
241
|
+
* @param {regular expression} regx
|
|
242
|
+
*/
|
|
243
|
+
filterKeybyRegx(data, regx) {
|
|
244
|
+
return Object.keys(data).filter((key) => key.match(regx));
|
|
245
|
+
}
|
|
246
|
+
getTargetPort(when, data) {
|
|
247
|
+
if (when === POST_OUT) {
|
|
248
|
+
return _.head(this.filterKeybyRegx(data, PORT_OUT_REG));
|
|
249
|
+
}
|
|
250
|
+
else if (when === PRE_IN) {
|
|
251
|
+
return _.head(this.filterKeybyRegx(data, PORT_IN_REG));
|
|
252
|
+
}
|
|
253
|
+
throw new Error(`invalid argument when = ${when}`);
|
|
254
|
+
}
|
|
255
|
+
emitToSuanpanWeb() {
|
|
256
|
+
if (this.utils.emitEventToSuanpanWeb) {
|
|
257
|
+
this.utils.emitEventToSuanpanWeb(...arguments);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
exports.ScriptManager = ScriptManager;
|
|
262
262
|
//# sourceMappingURL=script-manager.js.map
|
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
export function getOssClient(ossType: any): Promise<any>;
|
|
2
|
-
/**
|
|
3
|
-
* Delete multi objects in one request.
|
|
4
|
-
* @param {*} objectNames
|
|
5
|
-
*/
|
|
6
|
-
export function remove(objectNames: any): Promise<void>;
|
|
7
|
-
/**
|
|
8
|
-
* https://github.com/ali-sdk/ali-oss#putname-file-options
|
|
9
|
-
* @param {*} objectName object name store on OSS
|
|
10
|
-
* @param {*} toBeUploaded String(file path)|Buffer|ReadStream
|
|
11
|
-
*/
|
|
12
|
-
export function upload(objectName: any, toBeUploaded: any): Promise<void>;
|
|
13
|
-
export function getString(objectName: any): Promise<unknown>;
|
|
14
|
-
export function getStream(objectName: any): Promise<any>;
|
|
15
|
-
export function getJson(objectName: any): Promise<any>;
|
|
16
|
-
export function downloadToLocal(objectName: any, localPath: any): Promise<void>;
|
|
17
|
-
/**
|
|
18
|
-
* check objectName exist
|
|
19
|
-
* @param {*} objectName
|
|
20
|
-
*/
|
|
21
|
-
declare function checkObjectNameExist(objectName: any): Promise<boolean>;
|
|
22
|
-
export { checkObjectNameExist as fileExist };
|
|
1
|
+
export function getOssClient(ossType: any): Promise<any>;
|
|
2
|
+
/**
|
|
3
|
+
* Delete multi objects in one request.
|
|
4
|
+
* @param {*} objectNames
|
|
5
|
+
*/
|
|
6
|
+
export function remove(objectNames: any): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* https://github.com/ali-sdk/ali-oss#putname-file-options
|
|
9
|
+
* @param {*} objectName object name store on OSS
|
|
10
|
+
* @param {*} toBeUploaded String(file path)|Buffer|ReadStream
|
|
11
|
+
*/
|
|
12
|
+
export function upload(objectName: any, toBeUploaded: any): Promise<void>;
|
|
13
|
+
export function getString(objectName: any): Promise<unknown>;
|
|
14
|
+
export function getStream(objectName: any): Promise<any>;
|
|
15
|
+
export function getJson(objectName: any): Promise<any>;
|
|
16
|
+
export function downloadToLocal(objectName: any, localPath: any): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* check objectName exist
|
|
19
|
+
* @param {*} objectName
|
|
20
|
+
*/
|
|
21
|
+
declare function checkObjectNameExist(objectName: any): Promise<boolean>;
|
|
22
|
+
export { checkObjectNameExist as fileExist };
|