-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathroutes.js
72 lines (64 loc) · 2.29 KB
/
routes.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { resolve, relative, extname, basename, dirname } from 'path'
import { readdir } from 'fs/promises'
import os from "os";
import { pathToFileURL } from "url";
import recordError from './api/record-error.js'
/**
* Lists all files in {dir}
* @function
* @param {string} dir - The root directory name
* @returns {Promise<string[]>}
*/
async function getFiles(dir) {
const dirents = await readdir(dir, { withFileTypes: true })
const files = await Promise.all(dirents.map((dirent) => {
const res = resolve(dir, dirent.name)
return dirent.isDirectory() ? getFiles(res) : res
}))
return Array.prototype.concat(...files)
}
/**
* Creates an API endpoint for files in the /api directory
* @function
* @param {Object} app - An express app instance
* @returns {Promise<void>}
*/
export default async (app) => {
const startTS = Date.now()
const files = await getFiles('./api/endpoints')
const filesToLoad = files.map(async file => {
try {
const ext = extname(file)
if (!['.js', '.mjs'].includes(ext)) {
// skip loading non-js files
return
}
const moduleURL = new URL(import.meta.url);
const __dirname = decodeURIComponent(dirname(moduleURL.pathname));
// if it's an index.js file, use the parent directory's name
// ex. '/api/slack/index.js' is hosted at '/api/slack' (no index)
let routePath = relative(__dirname, dirname(file))
// if it's NOT an index.js file, include the basename
// ex. '/api/zoom/new.js' is hosted at '/api/zoom/new'
if (basename(file, extname(file)) != 'index') {
routePath = `${routePath}/${basename(file, extname(file))}`
}
routePath = os.platform() === "win32" ? routePath.split("\\").slice(7).join("/") : routePath;
const fileUri = os.platform() === "win32" ? pathToFileURL(file) : file;
const route = (await import(fileUri)).default // just to test we can load the file
app.all('/' + routePath, async (req, res) => {
try {
await route(req, res)
} catch (err) {
console.error(err)
recordError(err)
}
})
} catch (err) {
console.error(err)
console.log('Failed to load file:', file)
}
})
await Promise.all(filesToLoad)
console.log(`Finished loading in ${Date.now() - startTS}ms`)
}