biz-a-cli 2.3.73 → 2.3.74

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.
@@ -3,255 +3,339 @@ import { insertHistory } from "./watcherController.js";
3
3
  import axios from "axios";
4
4
  import * as dayjs from "dayjs";
5
5
  import timezone from "dayjs/plugin/timezone.js";
6
- import utc from "dayjs/plugin/utc.js"
6
+ import utc from "dayjs/plugin/utc.js";
7
7
  import crypto from "crypto";
8
8
  import { createLogger, transports, format } from "winston";
9
+ import { execCLIScriptWorker } from "../worker/cliWorkerPool.js";
9
10
 
10
- import customParseFormat from 'dayjs/plugin/customParseFormat.js'
11
- dayjs.default.extend(customParseFormat)
12
- dayjs.default.extend(timezone)
13
- dayjs.default.extend(utc)
11
+ import customParseFormat from "dayjs/plugin/customParseFormat.js";
12
+ dayjs.default.extend(customParseFormat);
13
+ dayjs.default.extend(timezone);
14
+ dayjs.default.extend(utc);
14
15
 
15
16
  export const AXIOS_TIMEOUT = 30 * 1000;
16
17
  const logger = createLogger({
17
- level: 'info',
18
- transports: [
19
- new transports.File({ filename: 'log/error.log', level: 'error' }),
20
- new transports.File({ filename: 'log/debug.log', level: 'debug' }),
21
- new transports.File({ filename: 'log/info.log', level: 'info' }),
22
- new transports.File({ filename: 'log/exception.log', handleExceptions: true })
23
- ],
24
- })
25
- if (process.env.NODE_ENV !== 'production') {
26
- logger.add(new transports.Console({ format: format.simple(), level: 'info' }))
18
+ level: "info",
19
+ transports: [
20
+ new transports.File({ filename: "log/error.log", level: "error" }),
21
+ new transports.File({ filename: "log/debug.log", level: "debug" }),
22
+ new transports.File({ filename: "log/info.log", level: "info" }),
23
+ new transports.File({
24
+ filename: "log/exception.log",
25
+ handleExceptions: true,
26
+ }),
27
+ ],
28
+ });
29
+ if (process.env.NODE_ENV !== "production") {
30
+ logger.add(
31
+ new transports.Console({ format: format.simple(), level: "info" }),
32
+ );
27
33
  }
28
34
 
29
35
  export function mapData2Key(res, cols) {
30
- return res.map(e => {
31
- return cols.reduce((o, k) => {
32
- // o[k.key ?? k.data] = e[k.data]
33
- o[k.key ? k.key : k.data] = e[k.data]
34
- return o;
35
- }, {})
36
- })
36
+ return res.map((e) => {
37
+ return cols.reduce((o, k) => {
38
+ // o[k.key ?? k.data] = e[k.data]
39
+ o[k.key ? k.key : k.data] = e[k.data];
40
+ return o;
41
+ }, {});
42
+ });
37
43
  }
38
44
 
39
45
  export function getUrlApi(config, methodName, isPost = true) {
40
- return `${config.url}/fina/rest/${config.methodClass ?? 'TOrmMethod'}/` +
41
- `${isPost ? '%22' : ''}${methodName}${isPost ? '%22' : ''}`
46
+ return (
47
+ `${config.url}/fina/rest/${config.methodClass ?? "TOrmMethod"}/` +
48
+ `${isPost ? "%22" : ""}${methodName}${isPost ? "%22" : ""}`
49
+ );
42
50
  }
43
51
 
44
52
  export function json2Parameters(obj) {
45
- return JSON.stringify({ _parameters: obj.map((el) => JSON.stringify(el)) });
53
+ return JSON.stringify({
54
+ _parameters: obj.map((el) =>
55
+ typeof el === "string" ? el : JSON.stringify(el),
56
+ ),
57
+ });
46
58
  }
47
59
 
48
60
  export function getUrlAndParam(config, method, obj, path) {
49
- return {
50
- url: getUrlApi(config, path),
51
- params: json2Parameters([
52
- {
53
- dbIndex: config.dbindex,
54
- method: method,
55
- object: obj
56
- }
57
- ])
58
- }
61
+ return {
62
+ url: getUrlApi(config, path),
63
+ params: json2Parameters([
64
+ {
65
+ dbIndex: config.dbindex,
66
+ method: method,
67
+ object: obj,
68
+ },
69
+ ]),
70
+ };
59
71
  }
60
72
 
61
73
  export function getTableObj(model, tableName) {
62
- let obj = {};
63
- obj[tableName] = model;
64
- return obj;
74
+ let obj = {};
75
+ obj[tableName] = model;
76
+ return obj;
65
77
  }
66
78
 
67
79
  export function options(apiConfig) {
68
- return {
69
- headers: { 'content-type': 'text/plain' },
70
- params: { subdomain: apiConfig.subdomain },
71
- timeout: apiConfig.timeout ?? AXIOS_TIMEOUT //SCY BZ 4316
72
- };
80
+ return {
81
+ headers: { "content-type": "text/plain" },
82
+ params: { subdomain: apiConfig.subdomain },
83
+ timeout: apiConfig.timeout ?? AXIOS_TIMEOUT, //SCY BZ 4316
84
+ };
73
85
  }
74
86
 
75
87
  export async function json2fina(obj, apiConfig, raiseError = false) {
76
- const url = getUrlApi(
77
- {
78
- url: apiConfig.url,
79
- dbIndex: obj.dbIndex,
80
- methodClass: 'TFinaMethod'
81
- },
82
- 'json2fina'
83
- );
84
-
85
- const params = json2Parameters([obj]);
86
- const res = await axios.post(url, params, options(apiConfig));
87
-
88
- if (res.data?.error && raiseError) {
89
- throw new Error(res.data.error);
90
- }
91
- return res;
88
+ const url = getUrlApi(
89
+ {
90
+ url: apiConfig.url,
91
+ dbIndex: obj.dbIndex,
92
+ methodClass: "TFinaMethod",
93
+ },
94
+ "json2fina",
95
+ );
96
+
97
+ const params = json2Parameters([obj]);
98
+ const res = await axios.post(url, params, options(apiConfig));
99
+
100
+ if (res.data?.error && raiseError) {
101
+ throw new Error(res.data.error);
102
+ }
103
+ return res;
92
104
  }
93
105
 
94
106
  export function sendModel(model, apiConfig, tableName) {
95
- const { url, params } = getUrlAndParam(
96
- apiConfig,
97
- 'put',
98
- getTableObj(model, tableName),
99
- 'orm'
100
- );
101
-
102
- return axios.post(url, params, options(apiConfig))
107
+ const { url, params } = getUrlAndParam(
108
+ apiConfig,
109
+ "put",
110
+ getTableObj(model, tableName),
111
+ "orm",
112
+ );
113
+
114
+ return axios.post(url, params, options(apiConfig));
103
115
  }
104
116
 
105
117
  export async function queryData(param, apiConfig, mapField) {
106
- const defaultParam = {
107
- start: 0, length: -1, order: [], filter: [], columns: []
108
- };
109
-
110
- const { url, params } = getUrlAndParam(
111
- apiConfig,
112
- 'list',
113
- { ...defaultParam, ...param },
114
- 'list'
115
- );
116
-
117
- let res = await axios.post(url, params, options(apiConfig));
118
- res = res.data?.data ? JSON.parse(res.data.data) : res.data;
119
- return (!mapField || res.error) ? res : mapData2Key(res, param.columns);
118
+ const defaultParam = {
119
+ start: 0,
120
+ length: -1,
121
+ order: [],
122
+ filter: [],
123
+ columns: [],
124
+ };
125
+
126
+ const { url, params } = getUrlAndParam(
127
+ apiConfig,
128
+ "list",
129
+ { ...defaultParam, ...param },
130
+ "list",
131
+ );
132
+
133
+ let res = await axios.post(url, params, options(apiConfig));
134
+ res = res.data?.data ? JSON.parse(res.data.data) : res.data;
135
+ return !mapField || res.error ? res : mapData2Key(res, param.columns);
120
136
  }
121
137
 
122
138
  export async function crudData(param, apiConfig, method, path) {
123
- const { url, params } = getUrlAndParam(
124
- apiConfig,
125
- method,
126
- { ...param },
127
- path
128
- );
129
-
130
- const res = await axios.post(url, params, options(apiConfig));
131
- return res.data?.data ? JSON.parse(res.data.data) : res.data;
139
+ const { url, params } = getUrlAndParam(
140
+ apiConfig,
141
+ method,
142
+ { ...param },
143
+ path,
144
+ );
145
+
146
+ const res = await axios.post(url, params, options(apiConfig));
147
+ // return res.data?.data ? JSON.parse(res.data.data) : res.data;
148
+ return res.data?.data
149
+ ? typeof res.data.data === "string"
150
+ ? JSON.parse(res.data.data)
151
+ : res.data.data
152
+ : res.data;
132
153
  }
133
154
 
134
155
  export async function genId(apiConfig, genName) {
135
- const url = `${getUrlApi(apiConfig, 'genId', false)}/${genName}/${apiConfig.dbindex}`;
156
+ const url = `${getUrlApi(apiConfig, "genId", false)}/${genName}/${apiConfig.dbindex}`;
136
157
 
137
- const res = await axios.get(url, options(apiConfig));
138
- return res.data?.data ? JSON.parse(res.data.data) : res.data;
158
+ const res = await axios.get(url, options(apiConfig));
159
+ return res.data?.data ? JSON.parse(res.data.data) : res.data;
139
160
  }
140
161
 
141
162
  function runScriptInThisContext(script) {
142
- return runInThisContext(script, { importModuleDynamically: constants.USE_MAIN_CONTEXT_DEFAULT_LOADER });
163
+ return runInThisContext(script, {
164
+ importModuleDynamically: constants.USE_MAIN_CONTEXT_DEFAULT_LOADER,
165
+ });
143
166
  }
144
167
 
145
168
  export async function setLibrary(config, libraries, defaultLib) {
146
- let libs = {};
147
- for (const lib of libraries) {
148
- const data = await loadCliScript(config, 'SCRIPT_NAME', lib);
149
- const libFn = runScriptInThisContext(data[0].script);
150
- Object.assign(libs, { [`${lib}`]: libFn(defaultLib).functions });
151
- }
152
-
153
- return libs;
169
+ let libs = {};
170
+ for (const lib of libraries) {
171
+ const data = await loadCliScript(config, "SCRIPT_NAME", lib);
172
+ const libFn = runScriptInThisContext(data[0].script);
173
+ Object.assign(libs, { [`${lib}`]: libFn(defaultLib).functions });
174
+ }
175
+
176
+ return libs;
154
177
  }
155
178
 
156
179
  export async function extractFunctionScript(selectedConfig, data) {
157
- const config = getConfig(selectedConfig);
158
-
159
- if (data.error) {
160
- console.log(data.error, 'error')
161
- return
162
- }
163
- if (data.length == 0) return
164
-
165
- const scriptFn = runScriptInThisContext(data[0].script);
166
- if (!scriptFn().functions) return
167
-
168
- const axiosInstance = axios.create({ timeout: AXIOS_TIMEOUT });
169
-
170
- let lib = {
171
- // axios: axios.default,
172
- axios: axiosInstance, //SCY BZ 4316
173
- dayjs: dayjs.default,
174
- crypto: crypto,
175
- log: logger,
176
- data: { sendModel, queryData, crudData, genId, getUrlAndParam }
177
- }
178
-
179
- if (scriptFn().functions.useLibrary) {
180
- Object.assign(lib, await setLibrary(config, scriptFn().functions.useLibrary(), lib));
181
- }
182
-
183
- return scriptFn(lib).functions;
180
+ const config = getConfig(selectedConfig);
181
+
182
+ if (data.error) {
183
+ console.log(data.error, "error");
184
+ return;
185
+ }
186
+ if (data.length == 0) return;
187
+
188
+ const scriptFn = runScriptInThisContext(data[0].script);
189
+ if (!scriptFn().functions) return;
190
+
191
+ const axiosInstance = axios.create({ timeout: AXIOS_TIMEOUT });
192
+
193
+ let lib = {
194
+ // axios: axios.default,
195
+ axios: axiosInstance, //SCY BZ 4316
196
+ dayjs: dayjs.default,
197
+ crypto: crypto,
198
+ log: logger,
199
+ data: { sendModel, queryData, crudData, genId, getUrlAndParam },
200
+ };
201
+
202
+ if (scriptFn().functions.useLibrary) {
203
+ Object.assign(
204
+ lib,
205
+ await setLibrary(config, scriptFn().functions.useLibrary(), lib),
206
+ );
207
+ }
208
+
209
+ return scriptFn(lib).functions;
184
210
  }
185
211
 
186
212
  export function getQueryDataPrmsParameters(column, value) {
187
- return {
188
- length: 1,
189
- filter: [{ junction: '', column: column, operator: '=', value1: `'${value}'` }],
190
- columns: [{ data: "SYS$CLI_SCRIPT.SCRIPT", key: 'script' }]
191
- }
213
+ return {
214
+ length: 1,
215
+ filter: [
216
+ {
217
+ junction: "",
218
+ column: column,
219
+ operator: "=",
220
+ value1: `'${value}'`,
221
+ },
222
+ ],
223
+ columns: [{ data: "SYS$CLI_SCRIPT.SCRIPT", key: "script" }],
224
+ };
192
225
  }
193
226
 
194
227
  export async function queryDataPromise(config, column, value) {
195
- let param = getQueryDataPrmsParameters(column, value);
228
+ let param = getQueryDataPrmsParameters(column, value);
196
229
 
197
- return await queryData(param, config, true);
230
+ return await queryData(param, config, true);
198
231
  }
199
232
 
200
233
  export function getConfig(config) {
201
- return (Array.isArray(config)) ? config[0] : config;
234
+ return Array.isArray(config) ? config[0] : config;
202
235
  }
203
236
 
204
237
  export const loadCliScript = async (selectedConfig, column, value) => {
205
- const config = getConfig(selectedConfig);
238
+ const config = getConfig(selectedConfig);
206
239
 
207
- return await queryDataPromise(config, column, value);
208
- }
240
+ return await queryDataPromise(config, column, value);
241
+ };
209
242
 
210
243
  export function getInputData(config, trigger) {
211
- const urlAndPort = config.url.split(':');
212
- return {
213
- arguments: {
214
- hostname: urlAndPort[1].split('//')[1],
215
- port: +urlAndPort[2],
216
- dbindex: config.dbindex,
217
- finaDbIndex: config.finaDbIndex,
218
- subdomain: config.subdomain,
219
- smtp: config.smtp
220
- },
221
- body: trigger.data
222
- }
244
+ const urlAndPort = config.url.split(":");
245
+ return {
246
+ arguments: {
247
+ hostname: urlAndPort[1].split("//")[1],
248
+ port: +urlAndPort[2],
249
+ dbindex: config.dbindex,
250
+ finaDbIndex: config.finaDbIndex,
251
+ subdomain: config.subdomain,
252
+ smtp: config.smtp,
253
+ },
254
+ // body: trigger.data,
255
+ body: trigger.data ?? null,
256
+ };
223
257
  }
224
258
 
225
- export async function scheduleSubscription(config, data, trigger, needSetHistory, isTest = false) {
226
- try {
227
- let functions = await extractFunctionScript(config, data);
228
-
229
- if (functions) {
230
- if (!isTest) { // next, change isTest to test better
231
- functions.onInit(getInputData(config, trigger));
232
- }
233
-
234
- if (needSetHistory) {
235
- await insertHistory(config, trigger._id, new Date());
236
- console.log(`Run Recent Schedule : ${trigger.name}`);
237
- } else {
238
- console.log(`Run Schedule : ${trigger.name}`);
239
- }
240
- } else {
241
- console.log(`CLI Script does not exist : ${trigger.name}`);
242
- }
243
- } catch (error) {
244
- console.error(error);
245
- throw new Error(error);
246
- }
259
+ // export async function scheduleSubscription(
260
+ // config,
261
+ // data,
262
+ // trigger,
263
+ // needSetHistory,
264
+ // isTest = false,
265
+ // ) {
266
+ // try {
267
+ // let functions = await extractFunctionScript(config, data);
268
+
269
+ // if (functions) {
270
+ // if (!isTest) {
271
+ // // next, change isTest to test better
272
+ // functions.onInit(getInputData(config, trigger));
273
+ // }
274
+
275
+ // if (needSetHistory) {
276
+ // await insertHistory(config, trigger._id, new Date());
277
+ // console.log(`Run Recent Schedule : ${trigger.name}`);
278
+ // } else {
279
+ // console.log(`Run Schedule : ${trigger.name}`);
280
+ // }
281
+ // } else {
282
+ // console.log(`CLI Script does not exist : ${trigger.name}`);
283
+ // }
284
+ // } catch (error) {
285
+ // console.error(error);
286
+ // throw new Error(error);
287
+ // }
288
+ // }
289
+
290
+ // export async function checkSchedule(selectedConfig, trigger, needSetHistory) {
291
+ // try {
292
+ // const data = await loadCliScript(
293
+ // selectedConfig,
294
+ // "ID",
295
+ // trigger.scriptid,
296
+ // );
297
+ // await scheduleSubscription(
298
+ // selectedConfig,
299
+ // data,
300
+ // trigger,
301
+ // needSetHistory,
302
+ // );
303
+ // } catch (error) {
304
+ // console.error(error);
305
+ // throw new Error(error);
306
+ // }
307
+ // }
308
+
309
+ export async function scheduleSubscription(
310
+ config,
311
+ trigger,
312
+ needSetHistory,
313
+ isTest = false,
314
+ ) {
315
+ try {
316
+ if (!isTest) {
317
+ await execCLIScriptWorker(
318
+ config,
319
+ { searchBy: "ID", searchValue: trigger.scriptid },
320
+ getInputData(config, trigger),
321
+ );
322
+ }
323
+ if (needSetHistory) {
324
+ await insertHistory(config, trigger._id, new Date());
325
+ console.info(`Run Recent Schedule : ${trigger.name}`);
326
+ } else {
327
+ console.info(`Run Schedule : ${trigger.name}`);
328
+ }
329
+ } catch (error) {
330
+ console.error(error);
331
+ throw new Error(error);
332
+ }
247
333
  }
248
334
 
249
335
  export async function checkSchedule(selectedConfig, trigger, needSetHistory) {
250
- try {
251
- const data = await loadCliScript(selectedConfig, 'ID', trigger.scriptid);
252
- await scheduleSubscription(selectedConfig, data, trigger, needSetHistory);
253
- } catch (error) {
254
- console.error(error);
255
- throw new Error(error);
256
- }
257
- }
336
+ try {
337
+ await scheduleSubscription(selectedConfig, trigger, needSetHistory);
338
+ } catch (error) {
339
+ console.error(error);
340
+ }
341
+ }
@@ -1,30 +1,63 @@
1
- import workerpool from 'workerpool';
1
+ import workerpool from "workerpool";
2
2
  import { loadCliScript, extractFunctionScript } from "../scheduler/datalib.js";
3
3
  import { createLogger, transports, format } from "winston";
4
4
 
5
- const logger = createLogger({ // logger must used worker thread context
6
- level: 'info',
7
- transports: [
8
- new transports.File({ filename: 'log/error.log', level: 'error' }),
9
- new transports.File({ filename: 'log/debug.log', level: 'debug' }),
10
- new transports.File({ filename: 'log/info.log', level: 'info' }),
11
- ],
5
+ const logger = createLogger({
6
+ // logger must used worker thread context
7
+ level: "info",
8
+ transports: [
9
+ new transports.File({ filename: "log/error.log", level: "error" }),
10
+ new transports.File({ filename: "log/debug.log", level: "debug" }),
11
+ new transports.File({ filename: "log/info.log", level: "info" }),
12
+ new transports.File({
13
+ filename: "log/exception.log",
14
+ handleExceptions: true,
15
+ }),
16
+ ],
12
17
  });
13
18
 
14
- if (process.env.NODE_ENV !== 'production') {
15
- logger.add(new transports.Console({ format: format.simple(), level: 'info' }))
16
- };
19
+ if (process.env.NODE_ENV !== "production") {
20
+ logger.add(
21
+ new transports.Console({ format: format.simple(), level: "info" }),
22
+ );
23
+ }
24
+
25
+ export const run = async (apiConfig, scriptIdentifier, scriptData) => {
26
+ const searchBy =
27
+ typeof scriptIdentifier === "object"
28
+ ? scriptIdentifier.searchBy
29
+ : "SCRIPT_NAME";
30
+ const searchValue =
31
+ typeof scriptIdentifier === "object"
32
+ ? scriptIdentifier.searchValue
33
+ : scriptIdentifier;
34
+ try {
35
+ const functions = await extractFunctionScript(
36
+ apiConfig,
37
+ await loadCliScript(apiConfig, searchBy, searchValue),
38
+ );
39
+ const result =
40
+ functions && functions.onInit
41
+ ? await functions.onInit(scriptData)
42
+ : "'onInit' not found. Nothing to execute";
17
43
 
18
- export const run = async (apiConfig, scriptName, scriptData)=>{
19
- try {
20
- const functions = await extractFunctionScript(apiConfig, await loadCliScript(apiConfig, 'SCRIPT_NAME', scriptName));
21
- const result = (functions && functions.onInit) ? await functions.onInit(scriptData) : "'onInit' not found. Nothing to execute";
22
- logger.info(`CLI script '${scriptName}' success. Result : ${result} ${process.env.NODE_ENV}`);
23
- return result;
24
- } catch (err) {
25
- logger.error(`CLI script '${scriptName}' fail. Error : ${err.message || err}`);
26
- throw new Error(err);
27
- };
44
+ logger.info(
45
+ `CLI script with ${searchBy} = ${searchValue} success. Result : ${result}`,
46
+ );
47
+ return result;
48
+ } catch (err) {
49
+ logger.error(
50
+ `CLI script with ${searchBy} = ${searchValue} fail. Error : ${err.message || err}`,
51
+ );
52
+ throw new Error(err);
53
+ }
28
54
  };
29
55
 
30
- workerpool.worker({run}, {onTerminate: (code)=>{logger.info(`CLI script worker terminated. Exit code : (${code})`)}});
56
+ workerpool.worker(
57
+ { run },
58
+ {
59
+ onTerminate: (code) => {
60
+ logger.info(`CLI script worker terminated. Exit code : (${code})`);
61
+ },
62
+ },
63
+ );