zcatalyst-cli 1.17.4 → 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/command_needs/rc.toml +2 -2
- 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/command_needs/rc.js +8 -8
- package/lib/commands/functions/shell.js +97 -1
- package/lib/commands/serve.js +1 -1
- package/lib/deploy/features/appsail/index.js +4 -3
- package/lib/deploy/features/appsail/utils.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/init/features/appsail/index.js +2 -2
- package/lib/internal/api.js +9 -1
- package/lib/port-resolver.js +1 -1
- package/lib/repl-server.js +9 -0
- package/lib/serve/server/lib/appsail/index.js +9 -8
- 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/shell/prepare/languages/java.js +1 -1
- package/lib/shell/prepare/languages/node.js +3 -1
- package/lib/shell/prepare/languages/python.js +1 -0
- 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;
|