zcatalyst-cli 1.17.5 → 1.18.0-beta.0
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/docs/commands/functions/shell.toml +4 -0
- package/docs/endpoints/lib/env.toml +3 -0
- package/docs/shell/dependencies/tunnel-server.toml +4 -0
- package/docs/shell/index.toml +7 -0
- package/lib/appsail-utils.js +7 -1
- package/lib/commands/functions/shell.js +97 -1
- package/lib/commands/serve.js +1 -1
- package/lib/endpoints/index.js +8 -1
- package/lib/endpoints/lib/env.js +20 -2
- package/lib/endpoints/lib/sdk.js +2 -2
- package/lib/endpoints/lib/tunnel.js +66 -0
- package/lib/internal/api.js +5 -0
- package/lib/port-resolver.js +1 -1
- package/lib/repl-server.js +9 -0
- package/lib/serve/server/lib/master.js +18 -9
- package/lib/serve/server/lib/python/index.js +3 -0
- package/lib/shell/dependencies/http-functions.js +21 -8
- package/lib/shell/dependencies/invoker/bio/java/JavabioInvoker.java +28 -32
- package/lib/shell/dependencies/invoker/bio/node.mjs +2 -2
- package/lib/shell/dependencies/invoker/cron/java/JavacronInvoker.java +62 -13
- package/lib/shell/dependencies/invoker/cron/node.mjs +28 -24
- package/lib/shell/dependencies/invoker/event/java/JavaeventInvoker.java +40 -6
- package/lib/shell/dependencies/invoker/event/node.mjs +22 -9
- package/lib/shell/dependencies/invoker/integ/java/JavaintegInvoker.java +3 -3
- package/lib/shell/dependencies/invoker/integ/node.mjs +6 -6
- package/lib/shell/dependencies/local-function.js +290 -199
- package/lib/shell/dependencies/tunnel-server.js +173 -0
- package/lib/shell/index.js +55 -1
- package/lib/util_modules/constants/index.js +3 -1
- package/lib/util_modules/constants/lib/needed-scopes.js +52 -0
- package/lib/util_modules/constants/lib/scopes.js +5 -0
- package/lib/util_modules/constants/lib/urls.js +8 -0
- package/package.json +3 -3
|
@@ -28,10 +28,290 @@ const logger_1 = require("../../util_modules/logger");
|
|
|
28
28
|
const project_1 = require("../../util_modules/project");
|
|
29
29
|
const shell_1 = require("../../util_modules/shell");
|
|
30
30
|
const http_functions_1 = require("../dependencies/http-functions");
|
|
31
|
+
const events_1 = __importDefault(require("events"));
|
|
31
32
|
const ensure_java_userconfig_1 = require("../../fn-utils/lib/ensure-java-userconfig");
|
|
32
33
|
class LocalFunction {
|
|
33
34
|
constructor(repl, target) {
|
|
34
35
|
var _a, _b, _c;
|
|
36
|
+
this.localFnEvents = new events_1.default();
|
|
37
|
+
this.killed = false;
|
|
38
|
+
this._call = (shell = true) => (rawData = {}) => {
|
|
39
|
+
let data;
|
|
40
|
+
try {
|
|
41
|
+
if (shell) {
|
|
42
|
+
if (typeof rawData === 'string') {
|
|
43
|
+
const content = fs_1.SYNC.readJSONFile((0, path_1.resolve)(runtime_store_1.default.get('cwd'), rawData));
|
|
44
|
+
if (content === undefined) {
|
|
45
|
+
return new error_1.default('content is undefined for provided file path');
|
|
46
|
+
}
|
|
47
|
+
rawData = content;
|
|
48
|
+
}
|
|
49
|
+
switch (this.target.type) {
|
|
50
|
+
case constants_1.FN_TYPE.cron: {
|
|
51
|
+
data = { data: rawData };
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
case constants_1.FN_TYPE.event:
|
|
55
|
+
if (!('event_bus_details' in rawData)) {
|
|
56
|
+
(0, logger_1.info)('For event function kindly use event:generate command to generate the input json.');
|
|
57
|
+
(0, logger_1.info)('You can also provide event details as per documentation.');
|
|
58
|
+
return new error_1.default('Event bus details missing');
|
|
59
|
+
}
|
|
60
|
+
data = rawData;
|
|
61
|
+
break;
|
|
62
|
+
default: {
|
|
63
|
+
data = rawData;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
data = rawData;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch (e) {
|
|
72
|
+
(0, logger_1.info)('the input must be in the form of json or a path to a file containing json data.');
|
|
73
|
+
return new error_1.default('Invalid input');
|
|
74
|
+
}
|
|
75
|
+
return (() => __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
var _a, _b, _c, _d, _e, _f;
|
|
77
|
+
const projectRoot = runtime_store_1.default.get('project.root');
|
|
78
|
+
const accessToken = yield credential_1.default.getAccessToken();
|
|
79
|
+
const slaveOptions = [];
|
|
80
|
+
const debugPort = runtime_store_1.default.get('context.port.debug.' + constants_1.FN_TYPE.basic, null);
|
|
81
|
+
yield fs_1.ASYNC.ensureFile(this.responseFile, true);
|
|
82
|
+
yield fs_1.ASYNC.ensureFile(this.metaFile, true);
|
|
83
|
+
const slaveFnTarget = { index: this.target.index, name: this.target.name };
|
|
84
|
+
if ((_a = this.target.stack) === null || _a === void 0 ? void 0 : _a.startsWith(runtime_1.default.language.node.value)) {
|
|
85
|
+
if (debugPort !== null) {
|
|
86
|
+
slaveOptions.push('--inspect-brk=' + debugPort);
|
|
87
|
+
}
|
|
88
|
+
slaveOptions.push(this.nodeInvoker);
|
|
89
|
+
slaveOptions.push(JSON.stringify(slaveFnTarget));
|
|
90
|
+
slaveOptions.push(JSON.stringify(data));
|
|
91
|
+
slaveOptions.push(JSON.stringify({
|
|
92
|
+
'x-zc-projectid': (0, project_1.getProjectId)(),
|
|
93
|
+
'x-zc-project-domain': (0, project_1.getDomainPrefix)() + '.' + constants_1.ORIGIN.app.replace('https://', ''),
|
|
94
|
+
'x-zc-project-key': (0, project_1.getDomainKey)(),
|
|
95
|
+
'x-zc-environment': (0, project_1.getEnvName)()
|
|
96
|
+
}));
|
|
97
|
+
slaveOptions.push(JSON.stringify({
|
|
98
|
+
'x-zc-user-cred-type': 'token',
|
|
99
|
+
'x-zc-user-cred-token': accessToken,
|
|
100
|
+
'x-zc-admin-cred-type': 'token',
|
|
101
|
+
'x-zc-admin-cred-token': accessToken,
|
|
102
|
+
'x-zc-user-type': 'admin'
|
|
103
|
+
}));
|
|
104
|
+
slaveOptions.push(JSON.stringify((0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build)));
|
|
105
|
+
this.slave = (0, shell_1.spawn)('node', slaveOptions, {
|
|
106
|
+
cwd: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name),
|
|
107
|
+
stdio: 'pipe',
|
|
108
|
+
env: Object.assign({ X_ZOHO_CATALYST_IS_LOCAL: 'true', X_ZOHO_CATALYST_FUNCTION_LOADED: 'true', X_ZOHO_CATALYST_ACCOUNTS_URL: constants_1.ORIGIN.auth, X_ZOHO_CATALYST_CONSOLE_URL: constants_1.ORIGIN.admin, CATALYST_PROJECT_TIMEZONE: (0, project_1.getProjectTimezone)(Intl.DateTimeFormat().resolvedOptions().timeZone) }, this.target.env_var)
|
|
109
|
+
}).RAW();
|
|
110
|
+
}
|
|
111
|
+
else if ((_b = this.target.stack) === null || _b === void 0 ? void 0 : _b.startsWith(runtime_1.default.language.java.value)) {
|
|
112
|
+
const javaInvokerDir = (0, path_1.parse)(this.javaInvoker).dir;
|
|
113
|
+
slaveOptions.push('-cp');
|
|
114
|
+
slaveOptions.push(javaInvokerDir +
|
|
115
|
+
fn_utils_1.fnUtils.java.classPathSep +
|
|
116
|
+
(0, path_1.join)(javaInvokerDir, 'lib', '*'));
|
|
117
|
+
if (debugPort !== null) {
|
|
118
|
+
slaveOptions.push('-Xdebug');
|
|
119
|
+
slaveOptions.push('-Xrunjdwp:transport=dt_socket,address=' +
|
|
120
|
+
debugPort +
|
|
121
|
+
',server=y,suspend=y');
|
|
122
|
+
}
|
|
123
|
+
slaveOptions.push((0, path_1.basename)(this.javaInvoker));
|
|
124
|
+
slaveOptions.push(javaInvokerDir);
|
|
125
|
+
slaveOptions.push(JSON.stringify(slaveFnTarget));
|
|
126
|
+
slaveOptions.push(JSON.stringify(data));
|
|
127
|
+
slaveOptions.push(JSON.stringify({
|
|
128
|
+
'x-zc-projectid': (0, project_1.getProjectId)(),
|
|
129
|
+
'x-zc-project-domain': (0, project_1.getDomainPrefix)() + '.' + constants_1.ORIGIN.app.replace('https://', ''),
|
|
130
|
+
'x-zc-project-key': (0, project_1.getDomainKey)(),
|
|
131
|
+
'x-zc-environment': (0, project_1.getEnvName)()
|
|
132
|
+
}));
|
|
133
|
+
slaveOptions.push(JSON.stringify({
|
|
134
|
+
'x-zc-user-cred-type': 'token',
|
|
135
|
+
'x-zc-user-cred-token': accessToken,
|
|
136
|
+
'x-zc-admin-cred-type': 'token',
|
|
137
|
+
'x-zc-admin-cred-token': accessToken,
|
|
138
|
+
'x-zc-user-type': 'admin'
|
|
139
|
+
}));
|
|
140
|
+
const configKey = `${this.target.stack}.bin`;
|
|
141
|
+
const userConfigCmd = userConfig_1.default.get(configKey);
|
|
142
|
+
const spawnCommand = (0, ensure_java_userconfig_1.getJavaSpawnCommand)(userConfigCmd, 'java', this.target.stack);
|
|
143
|
+
this.slave = (0, shell_1.spawn)(spawnCommand, slaveOptions, {
|
|
144
|
+
cwd: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name),
|
|
145
|
+
stdio: 'pipe',
|
|
146
|
+
env: Object.assign({ X_ZOHO_CATALYST_IS_LOCAL: 'true', X_ZOHO_CATALYST_FUNCTION_LOADED: 'true', X_ZOHO_CATALYST_ACCOUNTS_URL: constants_1.ORIGIN.auth, X_ZOHO_CATALYST_CONSOLE_URL: constants_1.ORIGIN.admin, CATALYST_PROJECT_TIMEZONE: (0, project_1.getProjectTimezone)(Intl.DateTimeFormat().resolvedOptions().timeZone) }, this.target.env_var)
|
|
147
|
+
}).RAW();
|
|
148
|
+
}
|
|
149
|
+
else if ((_c = this.target.stack) === null || _c === void 0 ? void 0 : _c.startsWith(runtime_1.default.language.python.value)) {
|
|
150
|
+
const stackVersion = (_d = this.target.stack) === null || _d === void 0 ? void 0 : _d.replace('python_', '');
|
|
151
|
+
const runtimesDir = constants_1.ENVPATH.runtimes.data;
|
|
152
|
+
const httpPort = parseInt(runtime_store_1.default.get('context.port.http.' + constants_1.REMOTE_REF.functions.type[constants_1.FN_TYPE.basic]), 10);
|
|
153
|
+
const runTimePort = yield port_resolver_1.default.getFreePort(httpPort, 20, false);
|
|
154
|
+
yield fs_1.ASYNC.ensureFile(this.responseFile, true);
|
|
155
|
+
yield fs_1.ASYNC.ensureFile(this.metaFile, true);
|
|
156
|
+
slaveOptions.push('-u');
|
|
157
|
+
slaveOptions.push((0, path_1.join)(runtimesDir, runtime_1.default.language.python.value, `zcatalyst_runtime_${stackVersion.replace('_', '')}`, 'main.py'));
|
|
158
|
+
this.slave = (0, shell_1.spawn)(userConfig_1.default.get(`python${stackVersion}.bin`), slaveOptions, {
|
|
159
|
+
cwd: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name),
|
|
160
|
+
stdio: 'pipe',
|
|
161
|
+
env: Object.assign({ X_ZOHO_CATALYST_IS_LOCAL: 'true', X_ZOHO_CATALYST_FUNCTION_LOADED: 'true', X_ZOHO_CATALYST_ACCOUNTS_URL: constants_1.ORIGIN.auth, X_ZOHO_CATALYST_CONSOLE_URL: constants_1.ORIGIN.admin, X_ZOHO_CATALYST_CODE_LOCATION: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name), X_ZOHO_CATALYST_SERVER_LISTEN_PORT: runTimePort.toString(), CATALYST_PROJECT_TIMEZONE: (0, project_1.getProjectTimezone)(Intl.DateTimeFormat().resolvedOptions().timeZone) }, this.target.env_var)
|
|
162
|
+
}).RAW();
|
|
163
|
+
this.slave.once('spawn', () => __awaiter(this, void 0, void 0, function* () {
|
|
164
|
+
const jsonData = data;
|
|
165
|
+
jsonData.timestamp = Date.now();
|
|
166
|
+
const reqJson = JSON.stringify(jsonData);
|
|
167
|
+
yield (0, http_functions_1.checkIfRuntimeServerRunning)(runTimePort.toString());
|
|
168
|
+
const writeResponse = (response, status) => {
|
|
169
|
+
fs_1.SYNC.writeFile(this.responseFile, response);
|
|
170
|
+
fs_1.SYNC.writeFile(this.metaFile, JSON.stringify({ response: { statusCode: status } }));
|
|
171
|
+
};
|
|
172
|
+
const req = http_1.default
|
|
173
|
+
.request(`http://127.0.0.1:${runTimePort}`, {
|
|
174
|
+
headers: {
|
|
175
|
+
'x-zc-projectid': (0, project_1.getProjectId)(),
|
|
176
|
+
'x-zc-project-domain': (0, project_1.getDomainPrefix)() +
|
|
177
|
+
'.' +
|
|
178
|
+
constants_1.ORIGIN.app.replace('https://', ''),
|
|
179
|
+
'x-zc-project-key': (0, project_1.getDomainKey)(),
|
|
180
|
+
'x-zc-environment': (0, project_1.getEnvName)(),
|
|
181
|
+
'x-zc-user-cred-type': 'token',
|
|
182
|
+
'x-zc-user-cred-token': accessToken,
|
|
183
|
+
'x-zc-admin-cred-type': 'token',
|
|
184
|
+
'x-zc-admin-cred-token': accessToken,
|
|
185
|
+
'x-zc-user-type': 'admin',
|
|
186
|
+
'Content-Length': reqJson.length
|
|
187
|
+
}
|
|
188
|
+
}, (resp) => {
|
|
189
|
+
var _a;
|
|
190
|
+
if ([
|
|
191
|
+
constants_1.REMOTE_REF.functions.type.cron,
|
|
192
|
+
constants_1.REMOTE_REF.functions.type.event
|
|
193
|
+
].includes(this.target.type + '')) {
|
|
194
|
+
switch (resp.statusCode) {
|
|
195
|
+
case 200: {
|
|
196
|
+
writeResponse('SUCCESS', 200);
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case 532: {
|
|
200
|
+
writeResponse('CODE_EXCEPTION', 532);
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
case 530: {
|
|
204
|
+
writeResponse('FAILURE', 530);
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
case 500: {
|
|
208
|
+
writeResponse('INTERNAL_SERVER_ERROR', 500);
|
|
209
|
+
break;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
(_a = this.slave) === null || _a === void 0 ? void 0 : _a.kill('SIGTERM');
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
resp.on('data', (data) => {
|
|
216
|
+
const respStr = data.toString();
|
|
217
|
+
fs_1.SYNC.writeFile(this.responseFile, respStr);
|
|
218
|
+
});
|
|
219
|
+
resp.on('close', () => {
|
|
220
|
+
var _a;
|
|
221
|
+
const metaJson = {
|
|
222
|
+
response: { statusCode: resp.statusCode }
|
|
223
|
+
};
|
|
224
|
+
fs_1.SYNC.writeFile(this.metaFile, JSON.stringify(metaJson));
|
|
225
|
+
(_a = this.slave) === null || _a === void 0 ? void 0 : _a.kill('SIGTERM');
|
|
226
|
+
});
|
|
227
|
+
})
|
|
228
|
+
.on('error', (err) => {
|
|
229
|
+
var _a;
|
|
230
|
+
(0, logger_1.debug)(err);
|
|
231
|
+
(_a = this.slave) === null || _a === void 0 ? void 0 : _a.kill('SIGTERM');
|
|
232
|
+
});
|
|
233
|
+
req.write(reqJson);
|
|
234
|
+
req.end();
|
|
235
|
+
}));
|
|
236
|
+
}
|
|
237
|
+
if (this.slave === null) {
|
|
238
|
+
throw new error_1.default('Slave listening started before initializing', {
|
|
239
|
+
exit: 2
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
(_e = this.slave.stdout) === null || _e === void 0 ? void 0 : _e.on('data', (message) => {
|
|
243
|
+
(0, shell_1.clearLine)(process.stdout);
|
|
244
|
+
(0, logger_1.info)(message.toString());
|
|
245
|
+
});
|
|
246
|
+
(_f = this.slave.stderr) === null || _f === void 0 ? void 0 : _f.on('data', (message) => {
|
|
247
|
+
const errorStr = js_1.JS.trim(message.toString());
|
|
248
|
+
(0, shell_1.clearLine)(process.stdout);
|
|
249
|
+
(0, logger_1.info)(errorStr);
|
|
250
|
+
});
|
|
251
|
+
this.slave.on('exit', (code, sig) => __awaiter(this, void 0, void 0, function* () {
|
|
252
|
+
(0, logger_1.debug)(`local fn slave exit: ${code}, ${sig}`);
|
|
253
|
+
if (code === 0) {
|
|
254
|
+
(0, logger_1.info)(`[CLI] Function ${this.target.name} execution complete`);
|
|
255
|
+
(0, logger_1.info)();
|
|
256
|
+
const response = yield fs_1.ASYNC.readFile(this.responseFile);
|
|
257
|
+
let meta;
|
|
258
|
+
try {
|
|
259
|
+
meta = JSON.parse((yield fs_1.ASYNC.readFile(this.metaFile))).response;
|
|
260
|
+
}
|
|
261
|
+
catch (err) {
|
|
262
|
+
meta = {};
|
|
263
|
+
}
|
|
264
|
+
switch (this.target.type) {
|
|
265
|
+
case constants_1.FN_TYPE.basic:
|
|
266
|
+
(0, logger_1.info)(`[response - ${this.target.name}] ${response + ''}`);
|
|
267
|
+
(0, logger_1.info)(`[status - ${this.target.name}] ${(meta.statusCode || 200) + ''}`);
|
|
268
|
+
this.localFnEvents.emit('response', {
|
|
269
|
+
data: response,
|
|
270
|
+
status: meta.statsCode
|
|
271
|
+
});
|
|
272
|
+
break;
|
|
273
|
+
case constants_1.FN_TYPE.cron:
|
|
274
|
+
case constants_1.FN_TYPE.event:
|
|
275
|
+
(0, logger_1.info)(`[status - ${this.target.name}] ${response || 'Unknown'}`);
|
|
276
|
+
if (!response) {
|
|
277
|
+
(0, logger_1.info)(`[CLI] Make sure to close the ${this.target.name} (${this.target.type}) function.`);
|
|
278
|
+
}
|
|
279
|
+
this.localFnEvents.emit('response', {
|
|
280
|
+
status: meta.statusCode
|
|
281
|
+
});
|
|
282
|
+
break;
|
|
283
|
+
case constants_1.FN_TYPE.integration:
|
|
284
|
+
(0, logger_1.info)(`[response - ${this.target.name}] ${response + ''}`);
|
|
285
|
+
try {
|
|
286
|
+
this.localFnEvents.emit('response', JSON.parse(response || ''));
|
|
287
|
+
}
|
|
288
|
+
catch (er) {
|
|
289
|
+
(0, logger_1.debug)('Invalid integration response: ', er);
|
|
290
|
+
}
|
|
291
|
+
break;
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
(code === 130 || sig === 'SIGINT') &&
|
|
296
|
+
(0, logger_1.info)(`[CLI] Function ${this.target.name} interrupted`);
|
|
297
|
+
(code === 143 ||
|
|
298
|
+
sig === 'SIGTERM' ||
|
|
299
|
+
sig === 'SIGQUIT' ||
|
|
300
|
+
sig === 'SIGKILL') &&
|
|
301
|
+
(0, logger_1.info)(`[CLI] Function ${this.target.name} process killed`);
|
|
302
|
+
this.localFnEvents.listenerCount('error') > 0 &&
|
|
303
|
+
this.localFnEvents.emit('error', new error_1.default(`Function(${this.target.name}) process exited with ${code ? 'status: ' + code : 'signal: ' + sig}`, {
|
|
304
|
+
skipHelp: true
|
|
305
|
+
}));
|
|
306
|
+
}
|
|
307
|
+
this.repl.showPrompt();
|
|
308
|
+
}));
|
|
309
|
+
this.slave.on('error', (err) => {
|
|
310
|
+
this.localFnEvents.emit('error', err);
|
|
311
|
+
});
|
|
312
|
+
return this.slave;
|
|
313
|
+
}))();
|
|
314
|
+
};
|
|
35
315
|
if (target.type === undefined ||
|
|
36
316
|
!Object.values(constants_1.FN_TYPE).includes(target.type)) {
|
|
37
317
|
throw new error_1.default('target type is not defined', { exit: 2 });
|
|
@@ -66,209 +346,12 @@ class LocalFunction {
|
|
|
66
346
|
}, 1000);
|
|
67
347
|
});
|
|
68
348
|
}
|
|
69
|
-
_call(rawData = {}) {
|
|
70
|
-
let data;
|
|
71
|
-
try {
|
|
72
|
-
data = JSON.stringify(rawData);
|
|
73
|
-
if (!data.startsWith('{') || !data.endsWith('}')) {
|
|
74
|
-
const content = fs_1.SYNC.readFile((0, path_1.resolve)(runtime_store_1.default.get('cwd'), data.slice(1, data.length - 1)));
|
|
75
|
-
if (content === undefined) {
|
|
76
|
-
return new error_1.default('content is undefined for provided file path');
|
|
77
|
-
}
|
|
78
|
-
data = content;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
catch (e) {
|
|
82
|
-
(0, logger_1.info)('the input must be in the form of json or a path to a file containing json data.');
|
|
83
|
-
return new error_1.default('Invalid input');
|
|
84
|
-
}
|
|
85
|
-
if (this.target.type === constants_1.FN_TYPE.event && !data.includes('event_bus_details')) {
|
|
86
|
-
(0, logger_1.info)('For event function kindly use event:generate command to generate the input json.');
|
|
87
|
-
(0, logger_1.info)('You can also provide event details as per documentation.');
|
|
88
|
-
return new error_1.default('Event bus details missing');
|
|
89
|
-
}
|
|
90
|
-
return (() => __awaiter(this, void 0, void 0, function* () {
|
|
91
|
-
var _a, _b, _c, _d, _e, _f;
|
|
92
|
-
const projectRoot = runtime_store_1.default.get('project.root');
|
|
93
|
-
const accessToken = yield credential_1.default.getAccessToken();
|
|
94
|
-
const slaveOptions = [];
|
|
95
|
-
const debugPort = runtime_store_1.default.get('context.port.debug.' + constants_1.FN_TYPE.basic, null);
|
|
96
|
-
yield fs_1.ASYNC.ensureFile(this.responseFile, true);
|
|
97
|
-
yield fs_1.ASYNC.ensureFile(this.metaFile, true);
|
|
98
|
-
const slaveFnTarget = { index: this.target.index, name: this.target.name };
|
|
99
|
-
if ((_a = this.target.stack) === null || _a === void 0 ? void 0 : _a.startsWith(runtime_1.default.language.node.value)) {
|
|
100
|
-
if (debugPort !== null) {
|
|
101
|
-
slaveOptions.push('--inspect-brk=' + debugPort);
|
|
102
|
-
}
|
|
103
|
-
slaveOptions.push(this.nodeInvoker);
|
|
104
|
-
slaveOptions.push(JSON.stringify(slaveFnTarget));
|
|
105
|
-
slaveOptions.push(data);
|
|
106
|
-
slaveOptions.push(JSON.stringify({
|
|
107
|
-
'x-zc-projectid': (0, project_1.getProjectId)(),
|
|
108
|
-
'x-zc-project-domain': (0, project_1.getDomainPrefix)() + '.' + constants_1.ORIGIN.app.replace('https://', ''),
|
|
109
|
-
'x-zc-project-key': (0, project_1.getDomainKey)(),
|
|
110
|
-
'x-zc-environment': (0, project_1.getEnvName)()
|
|
111
|
-
}));
|
|
112
|
-
slaveOptions.push(JSON.stringify({
|
|
113
|
-
'x-zc-user-cred-type': 'token',
|
|
114
|
-
'x-zc-user-cred-token': accessToken,
|
|
115
|
-
'x-zc-admin-cred-type': 'token',
|
|
116
|
-
'x-zc-admin-cred-token': accessToken,
|
|
117
|
-
'x-zc-user-type': 'admin'
|
|
118
|
-
}));
|
|
119
|
-
slaveOptions.push(JSON.stringify((0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build)));
|
|
120
|
-
this.slave = (0, shell_1.spawn)('node', slaveOptions, {
|
|
121
|
-
cwd: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name),
|
|
122
|
-
stdio: 'pipe',
|
|
123
|
-
env: Object.assign({ X_ZOHO_CATALYST_IS_LOCAL: 'true', X_ZOHO_CATALYST_FUNCTION_LOADED: 'true', X_ZOHO_CATALYST_ACCOUNTS_URL: constants_1.ORIGIN.auth, X_ZOHO_CATALYST_CONSOLE_URL: constants_1.ORIGIN.admin, CATALYST_PROJECT_TIMEZONE: (0, project_1.getProjectTimezone)(Intl.DateTimeFormat().resolvedOptions().timeZone) }, this.target.env_var)
|
|
124
|
-
}).RAW();
|
|
125
|
-
}
|
|
126
|
-
else if ((_b = this.target.stack) === null || _b === void 0 ? void 0 : _b.startsWith(runtime_1.default.language.java.value)) {
|
|
127
|
-
const javaInvokerDir = (0, path_1.parse)(this.javaInvoker).dir;
|
|
128
|
-
slaveOptions.push('-cp');
|
|
129
|
-
slaveOptions.push(javaInvokerDir + fn_utils_1.fnUtils.java.classPathSep + (0, path_1.join)(javaInvokerDir, 'lib', '*'));
|
|
130
|
-
if (debugPort !== null) {
|
|
131
|
-
slaveOptions.push('-Xdebug');
|
|
132
|
-
slaveOptions.push('-Xrunjdwp:transport=dt_socket,address=' + debugPort + ',server=y,suspend=y');
|
|
133
|
-
}
|
|
134
|
-
slaveOptions.push((0, path_1.basename)(this.javaInvoker));
|
|
135
|
-
slaveOptions.push(javaInvokerDir);
|
|
136
|
-
slaveOptions.push(JSON.stringify(slaveFnTarget));
|
|
137
|
-
slaveOptions.push(data);
|
|
138
|
-
slaveOptions.push(JSON.stringify({
|
|
139
|
-
'x-zc-projectid': (0, project_1.getProjectId)(),
|
|
140
|
-
'x-zc-project-domain': (0, project_1.getDomainPrefix)() + '.' + constants_1.ORIGIN.app.replace('https://', ''),
|
|
141
|
-
'x-zc-project-key': (0, project_1.getDomainKey)(),
|
|
142
|
-
'x-zc-environment': (0, project_1.getEnvName)()
|
|
143
|
-
}));
|
|
144
|
-
slaveOptions.push(JSON.stringify({
|
|
145
|
-
'x-zc-user-cred-type': 'token',
|
|
146
|
-
'x-zc-user-cred-token': accessToken,
|
|
147
|
-
'x-zc-admin-cred-type': 'token',
|
|
148
|
-
'x-zc-admin-cred-token': accessToken,
|
|
149
|
-
'x-zc-user-type': 'admin'
|
|
150
|
-
}));
|
|
151
|
-
const configKey = `${this.target.stack}.bin`;
|
|
152
|
-
const userConfigCmd = userConfig_1.default.get(configKey);
|
|
153
|
-
const spawnCommand = (0, ensure_java_userconfig_1.getJavaSpawnCommand)(userConfigCmd, 'java', this.target.stack);
|
|
154
|
-
this.slave = (0, shell_1.spawn)(spawnCommand, slaveOptions, {
|
|
155
|
-
cwd: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name),
|
|
156
|
-
stdio: 'pipe',
|
|
157
|
-
env: Object.assign({ X_ZOHO_CATALYST_IS_LOCAL: 'true', X_ZOHO_CATALYST_FUNCTION_LOADED: 'true', X_ZOHO_CATALYST_ACCOUNTS_URL: constants_1.ORIGIN.auth, X_ZOHO_CATALYST_CONSOLE_URL: constants_1.ORIGIN.admin, CATALYST_PROJECT_TIMEZONE: (0, project_1.getProjectTimezone)(Intl.DateTimeFormat().resolvedOptions().timeZone) }, this.target.env_var)
|
|
158
|
-
}).RAW();
|
|
159
|
-
}
|
|
160
|
-
else if ((_c = this.target.stack) === null || _c === void 0 ? void 0 : _c.startsWith(runtime_1.default.language.python.value)) {
|
|
161
|
-
const stackVersion = (_d = this.target.stack) === null || _d === void 0 ? void 0 : _d.replace('python_', '');
|
|
162
|
-
const runtimesDir = constants_1.ENVPATH.runtimes.data;
|
|
163
|
-
const httpPort = parseInt(runtime_store_1.default.get('context.port.http.' + constants_1.REMOTE_REF.functions.type[constants_1.FN_TYPE.basic]), 10);
|
|
164
|
-
const runTimePort = yield port_resolver_1.default.getFreePort(httpPort, 20, false);
|
|
165
|
-
yield fs_1.ASYNC.ensureFile(this.responseFile, true);
|
|
166
|
-
yield fs_1.ASYNC.ensureFile(this.metaFile, true);
|
|
167
|
-
slaveOptions.push('-u');
|
|
168
|
-
slaveOptions.push((0, path_1.join)(runtimesDir, runtime_1.default.language.python.value, `zcatalyst_runtime_${stackVersion.replace('_', '')}`, 'main.py'));
|
|
169
|
-
this.slave = (0, shell_1.spawn)(userConfig_1.default.get(`python${stackVersion}.bin`), slaveOptions, {
|
|
170
|
-
cwd: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name),
|
|
171
|
-
stdio: 'pipe',
|
|
172
|
-
env: Object.assign({ X_ZOHO_CATALYST_IS_LOCAL: 'true', X_ZOHO_CATALYST_FUNCTION_LOADED: 'true', X_ZOHO_CATALYST_ACCOUNTS_URL: constants_1.ORIGIN.auth, X_ZOHO_CATALYST_CONSOLE_URL: constants_1.ORIGIN.admin, X_ZOHO_CATALYST_CODE_LOCATION: (0, path_1.join)(projectRoot, constants_1.FOLDERNAME.build, constants_1.FOLDERNAME.functions, this.target.name), X_ZOHO_CATALYST_SERVER_LISTEN_PORT: runTimePort.toString(), CATALYST_PROJECT_TIMEZONE: (0, project_1.getProjectTimezone)(Intl.DateTimeFormat().resolvedOptions().timeZone) }, this.target.env_var)
|
|
173
|
-
}).RAW();
|
|
174
|
-
this.slave.on('spawn', () => __awaiter(this, void 0, void 0, function* () {
|
|
175
|
-
const jsonData = JSON.parse(data);
|
|
176
|
-
jsonData.timestamp = Date.now();
|
|
177
|
-
const reqJson = JSON.stringify(jsonData);
|
|
178
|
-
yield (0, http_functions_1.checkIfRuntimeServerRunning)(runTimePort.toString());
|
|
179
|
-
const req = http_1.default
|
|
180
|
-
.request(`http://127.0.0.1:${runTimePort}`, {
|
|
181
|
-
headers: {
|
|
182
|
-
'x-zc-projectid': (0, project_1.getProjectId)(),
|
|
183
|
-
'x-zc-project-domain': (0, project_1.getDomainPrefix)() +
|
|
184
|
-
'.' +
|
|
185
|
-
constants_1.ORIGIN.app.replace('https://', ''),
|
|
186
|
-
'x-zc-project-key': (0, project_1.getDomainKey)(),
|
|
187
|
-
'x-zc-environment': (0, project_1.getEnvName)(),
|
|
188
|
-
'x-zc-user-cred-type': 'token',
|
|
189
|
-
'x-zc-user-cred-token': accessToken,
|
|
190
|
-
'x-zc-admin-cred-type': 'token',
|
|
191
|
-
'x-zc-admin-cred-token': accessToken,
|
|
192
|
-
'x-zc-user-type': 'admin',
|
|
193
|
-
'Content-Length': reqJson.length
|
|
194
|
-
}
|
|
195
|
-
}, (resp) => {
|
|
196
|
-
resp.on('data', (data) => {
|
|
197
|
-
const respStr = data.toString();
|
|
198
|
-
fs_1.SYNC.writeFile(this.responseFile, respStr);
|
|
199
|
-
});
|
|
200
|
-
resp.on('close', () => {
|
|
201
|
-
var _a;
|
|
202
|
-
const metaJson = { response: { statusCode: resp.statusCode } };
|
|
203
|
-
fs_1.SYNC.writeFile(this.metaFile, JSON.stringify(metaJson));
|
|
204
|
-
(_a = this.slave) === null || _a === void 0 ? void 0 : _a.kill('SIGINT');
|
|
205
|
-
});
|
|
206
|
-
})
|
|
207
|
-
.on('error', (err) => {
|
|
208
|
-
var _a;
|
|
209
|
-
console.log(err);
|
|
210
|
-
(_a = this.slave) === null || _a === void 0 ? void 0 : _a.kill('SIGINT');
|
|
211
|
-
});
|
|
212
|
-
req.write(reqJson);
|
|
213
|
-
req.end();
|
|
214
|
-
}));
|
|
215
|
-
}
|
|
216
|
-
if (this.slave === null) {
|
|
217
|
-
throw new error_1.default('Slave listening started before initialising', {
|
|
218
|
-
exit: 2
|
|
219
|
-
});
|
|
220
|
-
}
|
|
221
|
-
(_e = this.slave.stdout) === null || _e === void 0 ? void 0 : _e.on('data', (message) => {
|
|
222
|
-
(0, shell_1.clearLine)(process.stdout);
|
|
223
|
-
(0, logger_1.info)(message.toString());
|
|
224
|
-
});
|
|
225
|
-
(_f = this.slave.stderr) === null || _f === void 0 ? void 0 : _f.on('data', (message) => {
|
|
226
|
-
const errorStr = js_1.JS.trim(message.toString());
|
|
227
|
-
(0, shell_1.clearLine)(process.stdout);
|
|
228
|
-
(0, logger_1.info)(errorStr);
|
|
229
|
-
});
|
|
230
|
-
this.slave.on('exit', (code) => __awaiter(this, void 0, void 0, function* () {
|
|
231
|
-
if (code !== null && code !== 130) {
|
|
232
|
-
(0, logger_1.info)('[cli] Function execution complete');
|
|
233
|
-
(0, logger_1.info)();
|
|
234
|
-
const response = yield fs_1.ASYNC.readFile(this.responseFile);
|
|
235
|
-
let meta;
|
|
236
|
-
try {
|
|
237
|
-
meta = JSON.parse((yield fs_1.ASYNC.readFile(this.metaFile))).response;
|
|
238
|
-
}
|
|
239
|
-
catch (err) {
|
|
240
|
-
meta = {};
|
|
241
|
-
}
|
|
242
|
-
switch (this.target.type) {
|
|
243
|
-
case constants_1.FN_TYPE.basic:
|
|
244
|
-
(0, logger_1.info)('[response]');
|
|
245
|
-
(0, logger_1.info)(response);
|
|
246
|
-
(0, logger_1.info)('[status]');
|
|
247
|
-
(0, logger_1.info)(meta.statusCode || 200);
|
|
248
|
-
break;
|
|
249
|
-
case constants_1.FN_TYPE.cron:
|
|
250
|
-
case constants_1.FN_TYPE.event:
|
|
251
|
-
(0, logger_1.info)('[status]');
|
|
252
|
-
(0, logger_1.info)(response);
|
|
253
|
-
break;
|
|
254
|
-
case constants_1.FN_TYPE.integration:
|
|
255
|
-
(0, logger_1.info)('[response]');
|
|
256
|
-
(0, logger_1.info)(response);
|
|
257
|
-
break;
|
|
258
|
-
default:
|
|
259
|
-
break;
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
this.repl.showPrompt();
|
|
263
|
-
}));
|
|
264
|
-
return this.slave;
|
|
265
|
-
}))();
|
|
266
|
-
}
|
|
267
349
|
shutdown() {
|
|
268
350
|
return __awaiter(this, void 0, void 0, function* () {
|
|
269
351
|
return new Promise((res) => {
|
|
270
352
|
if (this.slave) {
|
|
271
|
-
this.
|
|
353
|
+
this.killed = true;
|
|
354
|
+
this.slave.kill('SIGTERM');
|
|
272
355
|
}
|
|
273
356
|
if (this.watcher) {
|
|
274
357
|
this.watcher.close().then(res).catch(res);
|
|
@@ -279,5 +362,13 @@ class LocalFunction {
|
|
|
279
362
|
});
|
|
280
363
|
});
|
|
281
364
|
}
|
|
365
|
+
once(event, fn) {
|
|
366
|
+
this.localFnEvents.once(event, fn);
|
|
367
|
+
return this;
|
|
368
|
+
}
|
|
369
|
+
removeListener(event, fn) {
|
|
370
|
+
this.localFnEvents.removeListener(event, fn);
|
|
371
|
+
return this;
|
|
372
|
+
}
|
|
282
373
|
}
|
|
283
374
|
exports.default = LocalFunction;
|