1 | import { createHash, randomBytes, createHmac } from 'crypto'
|
2 | import { resolve } from 'path'
|
3 | import { MiddlewareMethod } from '../types/middleware'
|
4 |
|
5 | export const sha256 = (preimage: Buffer) => {
|
6 | return createHash('sha256').update(preimage).digest()
|
7 | }
|
8 |
|
9 | export function moduleExists (path: string) {
|
10 | try {
|
11 | require.resolve(path)
|
12 | return true
|
13 | } catch (err) {
|
14 | return false
|
15 | }
|
16 | }
|
17 |
|
18 | export const loadModuleFromPathOrDirectly = (searchPath: string, module: string) => {
|
19 | const localPath = resolve(searchPath, module)
|
20 | if (moduleExists(localPath)) {
|
21 | return localPath
|
22 | } else if (moduleExists(module)) {
|
23 | return module
|
24 | } else {
|
25 | return null
|
26 | }
|
27 | }
|
28 |
|
29 | export const loadModuleOfType = (type: string, name: string) => {
|
30 | const module = loadModuleFromPathOrDirectly(resolve(__dirname, `../${type}s/`), name)
|
31 |
|
32 | if (!module) {
|
33 | throw new Error(`${type} not found as a module name or under /${type}s/. moduleName=${name}`)
|
34 | }
|
35 |
|
36 | const loadedModule = require(module)
|
37 |
|
38 | if (loadedModule && typeof loadedModule === 'object' && typeof loadedModule.default === 'function') {
|
39 | // support ES6 modules
|
40 | return loadedModule.default
|
41 | } else if (typeof loadedModule === 'function') {
|
42 | return loadedModule
|
43 | } else {
|
44 | throw new TypeError(`${type} does not export a constructor. module=${module}`)
|
45 | }
|
46 | }
|
47 |
|
48 | export const extractDefaultsFromSchema = (schema: any, path = '') => {
|
49 | if (typeof schema.default !== 'undefined') {
|
50 | return schema.default
|
51 | }
|
52 |
|
53 | switch (schema.type) {
|
54 | case 'object':
|
55 | const result = {}
|
56 | for (let key of Object.keys(schema.properties)) {
|
57 | result[key] = extractDefaultsFromSchema(schema.properties[key], path + '.' + key)
|
58 | }
|
59 | return result
|
60 | default:
|
61 | throw new Error('No default found for schema path: ' + path)
|
62 | }
|
63 | }
|
64 |
|
65 | export function composeMiddleware<T, U> (
|
66 | middleware: MiddlewareMethod<T, U>[]
|
67 | ): MiddlewareMethod<T, U> {
|
68 | return function (val: T, next: MiddlewareMethod<T, U>) {
|
69 |
|
70 | let index = -1
|
71 | return dispatch(0, val)
|
72 | async function dispatch (i: number, val: T): Promise<U> {
|
73 | if (i <= index) {
|
74 | throw new Error('next() called multiple times.')
|
75 | }
|
76 | index = i
|
77 | const fn = (i === middleware.length) ? next : middleware[i]
|
78 | return fn(val, function next (val: T) {
|
79 | return dispatch(i + 1, val)
|
80 | })
|
81 | }
|
82 | }
|
83 | }
|
84 |
|
85 | export function uuid () {
|
86 | const random = randomBytes(16)
|
87 | random[6] = (random[6] & 0x0f) | 0x40
|
88 | random[8] = (random[8] & 0x3f) | 0x80
|
89 | return random.toString('hex')
|
90 | .replace(/(.{8})(.{4})(.{4})(.{4})(.{12})/, '$1-$2-$3-$4-$5')
|
91 | }
|
92 |
|
93 | export function hmac (secret: Buffer, message: string | Buffer) {
|
94 | const hmac = createHmac('sha256', secret)
|
95 | if (message instanceof Buffer) {
|
96 | hmac.update(message)
|
97 | } else {
|
98 | hmac.update(message, 'utf8')
|
99 | }
|
100 |
|
101 | return hmac.digest()
|
102 | }
|