@scout9/app 1.0.0-alpha.0.2.1 → 1.0.0-alpha.0.2.2
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/package.json +2 -2
- package/src/core/templates/app.js +83 -1
- package/src/public.d.ts +128 -2930
- package/types/index.d.ts +633 -3436
- package/types/index.d.ts.map +25 -20
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@scout9/app",
|
|
3
|
-
"version": "1.0.0-alpha.0.2.
|
|
3
|
+
"version": "1.0.0-alpha.0.2.2",
|
|
4
4
|
"description": "Build and deploy your Scout9 app for SMS auto replies",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"postinstall": "node postinstall.js",
|
|
20
20
|
"prepublishOnly": "npm run build",
|
|
21
21
|
"generate:types": "node scripts/generate-dts.js",
|
|
22
|
-
"prebuild": "rimraf dist/",
|
|
22
|
+
"prebuild": "rimraf dist/ && rimraf types/index.d.ts && rimraf types/index.d.ts.map",
|
|
23
23
|
"build": "rollup -c",
|
|
24
24
|
"postbuild": "npm run generate:types && node scripts/post-build.js && npx tsc --noEmit",
|
|
25
25
|
"build-no-test": "npm run prebuild && rollup -c"
|
|
@@ -6,12 +6,13 @@ import colors from 'kleur';
|
|
|
6
6
|
import { config as dotenv } from 'dotenv';
|
|
7
7
|
import { Configuration, Scout9Api } from '@scout9/admin';
|
|
8
8
|
import { EventResponse, WorkflowEventSchema } from '@scout9/app';
|
|
9
|
-
import path from 'node:path';
|
|
9
|
+
import path, { resolve } from 'node:path';
|
|
10
10
|
import fs from 'node:fs';
|
|
11
11
|
import https from 'node:https';
|
|
12
12
|
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
13
13
|
import projectApp from './src/app.js';
|
|
14
14
|
import config from './config.js';
|
|
15
|
+
import { readdir } from 'fs/promises';
|
|
15
16
|
|
|
16
17
|
const __filename = fileURLToPath(import.meta.url);
|
|
17
18
|
const __dirname = path.dirname(__filename);
|
|
@@ -229,6 +230,7 @@ async function resolveEntityApi(entity, method) {
|
|
|
229
230
|
|
|
230
231
|
}
|
|
231
232
|
|
|
233
|
+
|
|
232
234
|
function extractParamsFromPath(path) {
|
|
233
235
|
const segments = path.split('/').filter(Boolean); // Split and remove empty segments
|
|
234
236
|
let params = {};
|
|
@@ -284,6 +286,86 @@ async function runEntityApi(req, res) {
|
|
|
284
286
|
}
|
|
285
287
|
}
|
|
286
288
|
|
|
289
|
+
async function getFilesRecursive(dir) {
|
|
290
|
+
let results = [];
|
|
291
|
+
const list = await readdir(dir, { withFileTypes: true });
|
|
292
|
+
|
|
293
|
+
for (const dirent of list) {
|
|
294
|
+
const res = resolve(dir, dirent.name);
|
|
295
|
+
if (dirent.isDirectory()) {
|
|
296
|
+
results = results.concat(await getFilesRecursive(res)); // Recursively get files from subdirectories
|
|
297
|
+
} else {
|
|
298
|
+
results.push(res); // Add file to results
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
return results;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async function runCommandApi(req, res) {
|
|
306
|
+
let file;
|
|
307
|
+
const {body, url} = req;
|
|
308
|
+
const params = url.split('/').slice(2).filter(Boolean);
|
|
309
|
+
const commandsDir = resolve(__dirname, `./src/commands`);
|
|
310
|
+
|
|
311
|
+
try {
|
|
312
|
+
const files = await getFilesRecursive(commandsDir).then(files => files.map(file => file.replace(commandsDir, '.')).filter(file => params.every(p => file.includes(p))))
|
|
313
|
+
file = files?.[0];
|
|
314
|
+
} catch (e) {
|
|
315
|
+
console.log('No commands found', e.message)
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
if (!file) {
|
|
320
|
+
throw new Error(`Unable to find command for ${url}`);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
let mod;
|
|
324
|
+
try {
|
|
325
|
+
mod = await import(pathToFileURL(path.resolve(commandsDir, file)).href)
|
|
326
|
+
console.log(mod);
|
|
327
|
+
} catch (e) {
|
|
328
|
+
if ('code' in e) {
|
|
329
|
+
switch (e.code) {
|
|
330
|
+
case 'ERR_MODULE_NOT_FOUND':
|
|
331
|
+
case 'MODULE_NOT_FOUND':
|
|
332
|
+
console.error(e);
|
|
333
|
+
throw new Error(`Invalid command: no API method`);
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
console.error(e);
|
|
337
|
+
throw new Error(`Invalid command: Internal system error`);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
if (!mod || !mod.default) {
|
|
341
|
+
throw new Error(`Command file "${file}" does not export a default command function`);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
console.log(mod);
|
|
345
|
+
|
|
346
|
+
let result;
|
|
347
|
+
|
|
348
|
+
try {
|
|
349
|
+
result = await mod.default(body);
|
|
350
|
+
} catch (e) {
|
|
351
|
+
console.error('Failed to run command', e);
|
|
352
|
+
throw new Error(`Failed to run command: ${e.message}`)
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
if (result) {
|
|
356
|
+
if (typeof result === 'string') {
|
|
357
|
+
return {message: result};
|
|
358
|
+
} else if (typeof result === 'object' && 'message' in result) {
|
|
359
|
+
return result;
|
|
360
|
+
} else {
|
|
361
|
+
throw new Error(`Invalid Command Response, must either return a string or {"message": "<your message>"}`);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return {message: `${mod.default.name} Complete`};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
app.post('/commands/:command', runCommandApi);
|
|
368
|
+
app.post('/commands/:command/*', runCommandApi);
|
|
287
369
|
app.get('/entity/:entity', runEntityApi);
|
|
288
370
|
app.put('/entity/:entity', runEntityApi);
|
|
289
371
|
app.patch('/entity/:entity', runEntityApi);
|