zudello-execute-local 1.0.37 → 1.1.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.
Files changed (3) hide show
  1. package/index.js +62 -326
  2. package/package.json +23 -23
  3. package/src/utils/nodeVM.js +272 -0
package/index.js CHANGED
@@ -1,338 +1,74 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- const yargs = require("yargs");
4
- const dotenv = require("dotenv");
5
- const fs = require("fs");
6
- const path = require("path");
7
- const { NodeVM, makeResolverFromLegacyOptions } = require("vm2");
3
+ const yargs = require('yargs')
4
+ const dotenv = require('dotenv')
5
+ const fs = require('fs')
6
+ const path = require('path')
7
+ const { runScript } = require('./src/utils/nodeVM')
8
8
 
9
9
  const argv = yargs
10
- .option("script", {
11
- alias: "s",
12
- description: "Path to the script file",
13
- type: "string",
14
- demandOption: true,
15
- })
16
- .option("env", {
17
- alias: "e",
18
- description: "Path to the .env file",
19
- type: "string",
20
- demandOption: true,
21
- })
22
- .option("handlerName", {
23
- alias: "hn",
24
- description: "Handler function name",
25
- type: "string",
26
- default: "handle",
27
- })
28
- .option("data", {
29
- alias: "d",
30
- description:
31
- "Provided data that are passed to the script handler function (should be in JSON format)",
32
- type: "string",
33
- default: "{}",
34
- })
35
- .option("loggerMode", {
36
- alias: "lm",
37
- description:
38
- "Logger Mode",
39
- type: "string",
40
- default: "PRODUCTION",
41
- })
42
- .help()
43
- .alias("help", "h").argv;
44
-
45
- dotenv.config({ path: argv.env });
10
+ .option('script', {
11
+ alias: 's',
12
+ description: 'Path to the script file',
13
+ type: 'string',
14
+ demandOption: true,
15
+ })
16
+ .option('env', {
17
+ alias: 'e',
18
+ description: 'Path to the .env file',
19
+ type: 'string',
20
+ demandOption: true,
21
+ })
22
+ .option('handlerName', {
23
+ alias: 'hn',
24
+ description: 'Handler function name',
25
+ type: 'string',
26
+ default: 'handle',
27
+ })
28
+ .option('data', {
29
+ alias: 'd',
30
+ description:
31
+ 'Provided data that are passed to the script handler function (should be in JSON format)',
32
+ type: 'string',
33
+ default: '{}',
34
+ })
35
+ .option('loggerMode', {
36
+ alias: 'lm',
37
+ description:
38
+ 'Logger Mode',
39
+ type: 'string',
40
+ default: 'PRODUCTION',
41
+ })
42
+ .help()
43
+ .alias('help', 'h').argv
44
+
45
+ dotenv.config({ path: argv.env })
46
46
 
47
47
  const init = async () => {
48
- let data = {};
49
- let scriptContent = "";
50
-
51
- console.log(argv);
52
-
53
- try {
54
- data = JSON.parse(argv.data);
55
- } catch (err) {
56
- console.error("Error: Invalid JSON provided in --data");
57
- process.exit(1);
58
- }
59
-
60
- const scriptPath = path.resolve(argv.script);
61
-
62
- try {
63
- scriptContent = fs.readFileSync(scriptPath, "utf8");
64
- } catch (err) {
65
- console.error(`Error: Unable to read script file at ${scriptPath}`);
66
- console.error(err.message);
67
- process.exit(1);
68
- }
69
-
70
- await runScript(argv.handlerName, scriptContent, data, argv.loggerMode);
71
- };
72
-
73
- const initNodeVM = () => {
74
- return new NodeVM({
75
- console: "inherit",
76
- sandbox: {
77
- process,
78
- },
79
- require: makeResolverFromLegacyOptions({
80
- external: {
81
- modules: [
82
- "lodash",
83
- "performance-now",
84
- "moment",
85
- "moment-timezone",
86
- "he",
87
- "zudello-integration-sdk",
88
- ],
89
- },
90
- builtin: ["https"],
91
- root: path.resolve(__dirname),
92
- import: [
93
- "lodash",
94
- "performance-now",
95
- "moment",
96
- "moment-timezone",
97
- "he",
98
- "zudello-integration-sdk",
99
- ],
100
- mock: {
101
- fs: {
102
- readFileSync() {
103
- return "Nice try!";
104
- },
105
- },
106
- },
107
- }),
108
- });
109
- };
110
-
111
- const runScript = async (handler, source, object, loggerMode) => {
112
- const nodeVM = initNodeVM();
113
-
114
- const authData = {
115
- team_uuid: process.env.AUTH_TEAM_UUID,
116
- jwt_token: process.env.AUTH_JWT_TOKEN,
117
- organization_uuid: process.env.AUTH_ORGANIZATION_UUID,
118
- api_url: process.env.AUTH_API_URL,
119
- api_version: process.env.AUTH_API_VERSION,
120
- external_api_url: process.env.AUTH_EXTERNAL_API_URL,
121
- auth_api_url: process.env.AUTH_AUTH_API_URL
122
- };
123
-
124
- const externalIntegrationName = process.env.EXTERNAL_INTEGRATION_NAME;
125
- const externalConnectionUUID = process.env.EXTERNAL_CONNECTION_UUID;
126
-
127
- const triggerAuthenticate = `
128
- const auth = new Auth({
129
- teamUUID: '${authData.team_uuid}',
130
- token: '${authData.jwt_token}'
131
- })
132
- await auth.authenticate()
133
- `;
134
-
135
- const triggerZudello = `
136
- const Zudello = new ZudelloSDK(auth, '${authData.organization_uuid}', '${authData.api_url}', '${authData.api_version}', logger)
137
- const ZudelloAuth = new ZudelloAuthSDK(auth, '${authData.organization_uuid}', '${authData.auth_api_url}', '${authData.api_version}', logger)
138
- `;
139
-
140
- let triggerExternal = "";
141
-
142
- if (externalIntegrationName && externalConnectionUUID) {
143
- switch (externalIntegrationName) {
144
- case "netsuite":
145
- triggerExternal = `
146
- const Netsuite = new NetsuiteSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
147
- const NetsuiteSOAP = new NetsuiteSoapSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
148
- `;
149
- break;
150
- case "intacct":
151
- triggerExternal = `
152
- const Intacct = new IntacctSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
153
- `;
154
- break;
155
- case "bc":
156
- triggerExternal = `
157
- const BC = new BusinessCentralSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
158
- `;
159
- break;
160
- case "zenoti":
161
- triggerExternal = `
162
- const Zenoti = new ZenotiSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
163
- `;
164
- break;
165
- case "dear":
166
- triggerExternal = `
167
- const Dear = new DearSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
168
- `;
169
- break;
170
- case "nexvia":
171
- triggerExternal = `
172
- const Nexvia = new NexviaSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
173
- `;
174
- break;
175
- case "fo":
176
- triggerExternal = `
177
- const FO = new FoSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
178
- `;
179
- break;
180
- case "retailExpress":
181
- triggerExternal = `
182
- const RetailExpress = new RetailExpressSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
183
- `;
184
- break;
185
- case "myobAcumatica":
186
- triggerExternal = `
187
- const MYOBAcumatica = new MYOBAcumaticaSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
188
- `;
189
- break;
190
- case "sybiz":
191
- triggerExternal = `
192
- const Sybiz = new SybizSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
193
- `;
194
- break;
195
- case "xero":
196
- triggerExternal = `
197
- const Xero = new XeroSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
198
- `;
199
- break;
200
- case "jobready":
201
- triggerExternal = `
202
- const JobReady = new JobReadySDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
203
- `;
204
- break;
205
- case "x3":
206
- triggerExternal = `
207
- const X3 = new X3SDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
208
- `;
209
- break;
210
- case "navision":
211
- triggerExternal = `
212
- const Navision = new NavisionSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
213
- `;
214
- break;
215
- case "myobAccountRight":
216
- triggerExternal = `
217
- const MYOBAccountRight = new MYOBAccountRightSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
218
- `;
219
- break;
220
- case "sunSystems":
221
- triggerExternal = `
222
- const SunSystems = new SunSystemsSDK(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
223
- `;
224
- break;
225
- }
226
- }
227
-
228
- let scriptFunction = nodeVM.run(
229
- `module.exports = async function(callback) {
230
- try {
231
- const {
232
- Auth,
233
- ZudelloSDK,
234
- ZudelloAuthSDK,
235
- NetsuiteSDK,
236
- NetsuiteSoapSDK,
237
- IntacctSDK,
238
- X3SDK,
239
- BusinessCentralSDK,
240
- ZenotiSDK,
241
- DearSDK,
242
- NexviaSDK,
243
- FoSDK,
244
- RetailExpressSDK,
245
- MYOBAcumaticaSDK,
246
- MYOBAccountRightSDK,
247
- SybizSDK,
248
- SunSystemsSDK,
249
- NavisionSDK,
250
- XeroSDK,
251
- JobReadySDK,
252
- Logger,
253
- Metadata,
254
- Tags,
255
- Trigger,
256
- Properties,
257
- MiscHelper,
258
- ModelHelper,
259
- DatasetHelper,
260
- S3Client
261
- } = require('zudello-integration-sdk')
262
- const _ = require('lodash')
263
- const now = require('performance-now')
264
- const moment = require('moment-timezone')
265
- const he = require('he')
266
-
267
- const logger = new Logger('${loggerMode}')
268
- const metadata = new Metadata()
269
- const properties = new Properties()
270
- const tags = new Tags()
271
- const misc = new MiscHelper()
272
-
273
- ${triggerAuthenticate}
274
- ${triggerZudello}
275
- ${triggerExternal}
276
-
277
- let Model
278
- let Dataset
279
-
280
- if (typeof Zudello !== 'undefined') {
281
- Model = new ModelHelper(Zudello, logger)
282
- Dataset = new DatasetHelper(Zudello, logger)
283
- }
284
-
285
- let triggerNode
286
-
287
- if (auth) {
288
- triggerNode = new Trigger(auth.getApiInstance(), auth.teamUUID);
289
- }
290
-
291
- ${source}
292
-
293
- const startTime = now()
294
-
295
- let result = null
296
- let status = 'success'
297
- let error = ''
298
-
299
- try {
300
- result = await ${handler}(${JSON.stringify(object)})
301
- } catch (e) {
302
- logger.error('Script Failed', e)
303
- status = 'failed'
304
- error = e.message
305
- }
306
-
307
- logger.info('status', status)
48
+ let data = {}
49
+ let scriptContent = ''
308
50
 
309
- if (error) {
310
- logger.info('error', error)
311
- }
51
+ try {
52
+ data = JSON.parse(argv.data)
53
+ } catch (err) {
54
+ console.error('Error: Invalid JSON provided in --data')
55
+ process.exit(1)
56
+ }
312
57
 
313
- const endTime = now()
314
- const duration = endTime - startTime
58
+ const scriptPath = path.resolve(argv.script)
315
59
 
316
- logger.info('duration', duration)
60
+ try {
61
+ scriptContent = fs.readFileSync(scriptPath, 'utf8')
62
+ } catch (err) {
63
+ console.error(`Error: Unable to read script file at ${scriptPath}`)
64
+ console.error(err.message)
65
+ process.exit(1)
66
+ }
317
67
 
318
- callback(null, result)
319
- } catch (error) {
320
- callback(error)
321
- }
322
- }`,
323
- path.resolve(__dirname, "index.js")
324
- );
68
+ const dirNamePath = path.resolve(__dirname)
69
+ const dirNameFilePath = path.resolve(__dirname, 'index.js')
325
70
 
326
- return new Promise((resolve, reject) => {
327
- scriptFunction((err, response) => {
328
- if (err) {
329
- console.error(err);
330
- reject(new Error(`Error executing script: ${err.message}`));
331
- } else {
332
- resolve(response);
333
- }
334
- });
335
- });
336
- };
71
+ await runScript(argv.handlerName, scriptContent, data, argv.loggerMode, dirNamePath, dirNameFilePath)
72
+ }
337
73
 
338
- init();
74
+ init()
package/package.json CHANGED
@@ -1,25 +1,25 @@
1
1
  {
2
- "name": "zudello-execute-local",
3
- "version": "1.0.37",
4
- "description": "Zudello Execute tool for local runs",
5
- "main": "index.js",
6
- "bin": {
7
- "zexec": "./index.js"
8
- },
9
- "scripts": {},
10
- "author": "Zudello",
11
- "license": "ISC",
12
- "dependencies": {
13
- "dotenv": "^16.3.1",
14
- "fs": "^0.0.1-security",
15
- "he": "^1.2.0",
16
- "lodash": "^4.17.21",
17
- "moment": "^2.30.1",
18
- "moment-timezone": "^0.5.46",
19
- "path": "^0.12.7",
20
- "performance-now": "^2.1.0",
21
- "vm2": "^3.9.19",
22
- "yargs": "^17.7.2",
23
- "zudello-integration-sdk": "^1.0.43"
24
- }
2
+ "name": "zudello-execute-local",
3
+ "version": "1.1.0",
4
+ "description": "Zudello Execute tool for local runs",
5
+ "main": "index.js",
6
+ "bin": {
7
+ "zexec": "./index.js"
8
+ },
9
+ "scripts": {},
10
+ "author": "Zudello",
11
+ "license": "ISC",
12
+ "dependencies": {
13
+ "dotenv": "^16.3.1",
14
+ "fs": "^0.0.1-security",
15
+ "he": "^1.2.0",
16
+ "lodash": "^4.17.21",
17
+ "moment": "^2.30.1",
18
+ "moment-timezone": "^0.5.46",
19
+ "path": "^0.12.7",
20
+ "performance-now": "^2.1.0",
21
+ "vm2": "^3.9.19",
22
+ "yargs": "^17.7.2",
23
+ "zudello-integration-sdk": "^1.0.43"
24
+ }
25
25
  }
@@ -0,0 +1,272 @@
1
+ const { NodeVM, makeResolverFromLegacyOptions } = require('vm2')
2
+
3
+ const connectionSdkMapping = {
4
+ netsuite: [{
5
+ variable: 'Netsuite',
6
+ class: 'NetsuiteSDK',
7
+ isExternal: true
8
+ }, {
9
+ variable: 'NetsuiteSOAP',
10
+ class: 'NetsuiteSoapSDK',
11
+ isExternal: true
12
+ }],
13
+ intacct: [{
14
+ variable: 'Intacct',
15
+ class: 'IntacctSDK',
16
+ isExternal: true
17
+ }],
18
+ xero: [{
19
+ variable: 'Xero',
20
+ class: 'XeroSDK',
21
+ isExternal: true
22
+ }],
23
+ bc: [{
24
+ variable: 'BC',
25
+ class: 'BusinessCentralSDK',
26
+ isExternal: true
27
+ }],
28
+ zenoti: [{
29
+ variable: 'Zenoti',
30
+ class: 'ZenotiSDK',
31
+ isExternal: true
32
+ }],
33
+ dear: [{
34
+ variable: 'Dear',
35
+ class: 'DearSDK',
36
+ isExternal: true
37
+ }],
38
+ nexvia: [{
39
+ variable: 'Nexvia',
40
+ class: 'NexviaSDK',
41
+ isExternal: true
42
+ }],
43
+ fo: [{
44
+ variable: 'FO',
45
+ class: 'FoSDK',
46
+ isExternal: true
47
+ }],
48
+ retailExpress: [{
49
+ variable: 'RetailExpress',
50
+ class: 'RetailExpressSDK',
51
+ isExternal: true
52
+ }],
53
+ myobAcumatica: [{
54
+ variable: 'MYOBAcumatica',
55
+ class: 'MYOBAcumaticaSDK',
56
+ isExternal: true
57
+ }],
58
+ sybiz: [{
59
+ variable: 'Sybiz',
60
+ class: 'SybizSDK',
61
+ isExternal: true
62
+ }],
63
+ jobready: [{
64
+ variable: 'JobReady',
65
+ class: 'JobReadySDK',
66
+ isExternal: true
67
+ }],
68
+ sapb1: [{
69
+ variable: 'SapB1',
70
+ class: 'SAPB1SDK',
71
+ isExternal: true
72
+ }],
73
+ gp: [{
74
+ variable: 'GP',
75
+ class: 'GPSDK',
76
+ isExternal: true
77
+ }],
78
+ x3: [{
79
+ variable: 'X3',
80
+ class: 'X3SDK',
81
+ isExternal: true
82
+ }],
83
+ navision: [{
84
+ variable: 'Navision',
85
+ class: 'NavisionSDK',
86
+ isExternal: true
87
+ }],
88
+ myobAccountRight: [{
89
+ variable: 'MYOBAccountRight',
90
+ class: 'MYOBAccountRightSDK',
91
+ isExternal: true
92
+ }],
93
+ sunSystems: [{
94
+ variable: 'SunSystems',
95
+ class: 'SunSystemsSDK',
96
+ isExternal: true
97
+ }]
98
+ }
99
+
100
+ const initiateNodeVM = (dirNamePath) => {
101
+ return new NodeVM({
102
+ console: 'inherit',
103
+ sandbox: {
104
+ process,
105
+ },
106
+ require: makeResolverFromLegacyOptions({
107
+ external: {
108
+ modules: [
109
+ 'lodash',
110
+ 'performance-now',
111
+ 'moment',
112
+ 'moment-timezone',
113
+ 'he',
114
+ 'zudello-integration-sdk',
115
+ ],
116
+ },
117
+ builtin: ['https'],
118
+ root: dirNamePath,
119
+ import: [
120
+ 'lodash',
121
+ 'performance-now',
122
+ 'moment',
123
+ 'moment-timezone',
124
+ 'he',
125
+ 'zudello-integration-sdk',
126
+ ],
127
+ mock: {
128
+ fs: {
129
+ readFileSync() {
130
+ return 'Nice try!'
131
+ },
132
+ },
133
+ },
134
+ }),
135
+ })
136
+ }
137
+
138
+ const runScript = async (handler, source, object, loggerMode, dirNamePath, dirNameFilePath) => {
139
+ const nodeVM = initiateNodeVM(dirNamePath)
140
+
141
+ console.log(process.env)
142
+
143
+ const authData = {
144
+ team_uuid: process.env.AUTH_TEAM_UUID,
145
+ jwt_token: process.env.AUTH_JWT_TOKEN,
146
+ organization_uuid: process.env.AUTH_ORGANIZATION_UUID,
147
+ api_url: process.env.AUTH_API_URL,
148
+ api_version: process.env.AUTH_API_VERSION,
149
+ external_api_url: process.env.AUTH_EXTERNAL_API_URL,
150
+ auth_api_url: process.env.AUTH_AUTH_API_URL
151
+ }
152
+
153
+ console.log(authData)
154
+ console.log(dirNamePath)
155
+ console.log(dirNameFilePath)
156
+
157
+ const externalIntegrationName = process.env.EXTERNAL_INTEGRATION_NAME
158
+ const externalConnectionUUID = process.env.EXTERNAL_CONNECTION_UUID
159
+
160
+ const classesInUse = [
161
+ 'Logger', 'Metadata', 'Tags', 'Trigger', 'Properties', 'MiscHelper',
162
+ 'ModelHelper', 'DatasetHelper', 'S3Client', 'Auth', 'ZudelloSDK', 'ZudelloAuthSDK'
163
+ ]
164
+
165
+ const initAuth = `
166
+ const auth = new Auth({
167
+ teamUUID: '${authData.team_uuid}',
168
+ token: '${authData.jwt_token}'
169
+ })
170
+ await auth.authenticate()
171
+ `
172
+ const initZudello = `
173
+ const Zudello = new ZudelloSDK(auth, '${authData.organization_uuid}', '${authData.api_url}', '${authData.api_version}', logger)
174
+ const ZudelloAuth = new ZudelloAuthSDK(auth, '${authData.organization_uuid}', '${authData.auth_api_url}', '${authData.api_version}', logger)
175
+ `
176
+
177
+ let initExternalConnections = ''
178
+
179
+ if (connectionSdkMapping[externalIntegrationName]) {
180
+ const connectionInfoArray = connectionSdkMapping[externalIntegrationName]
181
+
182
+ connectionInfoArray.forEach(info => {
183
+ classesInUse.push(info.class)
184
+ initExternalConnections += `
185
+ const ${info.variable} = new ${info.class}(auth, '${externalConnectionUUID}', '${authData.organization_uuid}', '${authData.external_api_url}', '${authData.api_version}', logger)
186
+ `
187
+ })
188
+ }
189
+
190
+ let scriptFunction = nodeVM.run(
191
+ `module.exports = async function(callback) {
192
+ try {
193
+ const { ${classesInUse.join(',')} } = require('zudello-integration-sdk')
194
+ const _ = require('lodash')
195
+ const now = require('performance-now')
196
+ const moment = require('moment-timezone')
197
+ const he = require('he')
198
+
199
+ const logger = new Logger('${loggerMode}')
200
+ const metadata = new Metadata()
201
+ const properties = new Properties()
202
+ const tags = new Tags()
203
+ const misc = new MiscHelper()
204
+
205
+ ${initAuth}
206
+ ${initZudello}
207
+ ${initExternalConnections}
208
+
209
+ let Model
210
+ let Dataset
211
+
212
+ if (typeof Zudello !== 'undefined') {
213
+ Model = new ModelHelper(Zudello, logger)
214
+ Dataset = new DatasetHelper(Zudello, logger)
215
+ }
216
+
217
+ let triggerNode
218
+
219
+ if (auth) {
220
+ triggerNode = new Trigger(auth.getApiInstance(), auth.teamUUID)
221
+ }
222
+
223
+ ${source}
224
+
225
+ const startTime = now()
226
+
227
+ let result = null
228
+ let status = 'success'
229
+ let error = ''
230
+
231
+ try {
232
+ result = await ${handler}(${JSON.stringify(object)})
233
+ } catch (e) {
234
+ logger.error('Script Failed', e)
235
+ status = 'failed'
236
+ error = e.message
237
+ }
238
+
239
+ logger.info('status', status)
240
+
241
+ if (error) {
242
+ logger.info('error', error)
243
+ }
244
+
245
+ const endTime = now()
246
+ const duration = endTime - startTime
247
+
248
+ logger.info('duration', duration)
249
+
250
+ callback(null, result)
251
+ } catch (error) {
252
+ callback(error)
253
+ }
254
+ }`,
255
+ dirNameFilePath
256
+ )
257
+
258
+ return new Promise((resolve, reject) => {
259
+ scriptFunction((err, response) => {
260
+ if (err) {
261
+ console.error(err)
262
+ reject(new Error(`Error executing script: ${err.message}`))
263
+ } else {
264
+ resolve(response)
265
+ }
266
+ })
267
+ })
268
+ }
269
+
270
+ module.exports = {
271
+ runScript
272
+ }