@srfnstack/spliffy 1.2.4 → 1.2.6

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/src/log.mjs CHANGED
@@ -1,59 +1,59 @@
1
- import util from 'util'
2
-
3
- const inspect = util.inspect
4
- const levelOrder = { TRACE: 10, DEBUG: 20, INFO: 30, ACCESS: 30, 'GOOD NEWS EVERYONE!': 30, WARN: 40, ERROR: 50, FATAL: 60, NONE: 100 }
5
- let logLevel = levelOrder.INFO
6
-
7
- const ifLevelEnabled = (fn, level, args) => {
8
- const configLevel = levelOrder[logLevel] || levelOrder.INFO
9
- if (levelOrder[level] >= configLevel) {
10
- fn(`[${new Date().toISOString()}] [${level}] ${args.map(a => typeof a === 'string' ? a : inspect(a, { depth: null })).join(' ')}`)
11
- }
12
- }
13
-
14
- const callLog = (level, logImplFn, defaultFn, args) => {
15
- if (logImpl && typeof logImpl[logImplFn] === 'function') {
16
- logImpl[logImplFn](...args)
17
- } else {
18
- ifLevelEnabled(defaultFn, level, args)
19
- }
20
- }
21
-
22
- let logImpl = null
23
-
24
- export default {
25
- setLogLevel (level) {
26
- level = level.toUpperCase()
27
- if (!(level in levelOrder)) {
28
- throw new Error(`Invalid level: ${level}`)
29
- }
30
- logLevel = level
31
- },
32
- setLogger (logger) {
33
- logImpl = logger
34
- },
35
- trace () {
36
- callLog('TRACE', 'trace', console.trace, [...arguments])
37
- },
38
- debug () {
39
- callLog('DEBUG', 'debug', console.debug, [...arguments])
40
- },
41
- info () {
42
- callLog('INFO', 'info', console.info, [...arguments])
43
- },
44
- gne () {
45
- callLog('GOOD NEWS EVERYONE!', 'info', console.info, [...arguments])
46
- },
47
- access () {
48
- callLog('ACCESS', 'info', console.info, [...arguments])
49
- },
50
- warn () {
51
- callLog('WARN', 'warn', console.warn, [...arguments])
52
- },
53
- error () {
54
- callLog('ERROR', 'error', console.error, [...arguments].map(arg => arg.stack ? arg.stack : arg))
55
- },
56
- fatal () {
57
- callLog('ERROR', 'error', console.error, [...arguments].map(arg => arg.stack ? arg.stack : arg))
58
- }
59
- }
1
+ import util from 'util'
2
+
3
+ const inspect = util.inspect
4
+ const levelOrder = { TRACE: 10, DEBUG: 20, INFO: 30, ACCESS: 30, 'GOOD NEWS EVERYONE!': 30, WARN: 40, ERROR: 50, FATAL: 60, NONE: 100 }
5
+ let logLevel = levelOrder.INFO
6
+
7
+ const ifLevelEnabled = (fn, level, args) => {
8
+ const configLevel = levelOrder[logLevel] || levelOrder.INFO
9
+ if (levelOrder[level] >= configLevel) {
10
+ fn(`[${new Date().toISOString()}] [${level}] ${args.map(a => typeof a === 'string' ? a : inspect(a, { depth: null })).join(' ')}`)
11
+ }
12
+ }
13
+
14
+ const callLog = (level, logImplFn, defaultFn, args) => {
15
+ if (logImpl && typeof logImpl[logImplFn] === 'function') {
16
+ logImpl[logImplFn](...args)
17
+ } else {
18
+ ifLevelEnabled(defaultFn, level, args)
19
+ }
20
+ }
21
+
22
+ let logImpl = null
23
+
24
+ export default {
25
+ setLogLevel (level) {
26
+ level = level.toUpperCase()
27
+ if (!(level in levelOrder)) {
28
+ throw new Error(`Invalid level: ${level}`)
29
+ }
30
+ logLevel = level
31
+ },
32
+ setLogger (logger) {
33
+ logImpl = logger
34
+ },
35
+ trace () {
36
+ callLog('TRACE', 'trace', console.trace, [...arguments])
37
+ },
38
+ debug () {
39
+ callLog('DEBUG', 'debug', console.debug, [...arguments])
40
+ },
41
+ info () {
42
+ callLog('INFO', 'info', console.info, [...arguments])
43
+ },
44
+ gne () {
45
+ callLog('GOOD NEWS EVERYONE!', 'info', console.info, [...arguments])
46
+ },
47
+ access () {
48
+ callLog('ACCESS', 'info', console.info, [...arguments])
49
+ },
50
+ warn () {
51
+ callLog('WARN', 'warn', console.warn, [...arguments])
52
+ },
53
+ error () {
54
+ callLog('ERROR', 'error', console.error, [...arguments].map(arg => arg.stack ? arg.stack : arg))
55
+ },
56
+ fatal () {
57
+ callLog('ERROR', 'error', console.error, [...arguments].map(arg => arg.stack ? arg.stack : arg))
58
+ }
59
+ }
@@ -1,89 +1,89 @@
1
- import log from './log.mjs'
2
- /**
3
- * middleware is stored as an object where the properties are request methods the middleware applies to
4
- * if a middleware applies to all methods, the property ALL is used
5
- * example:
6
- * {
7
- * GET: [(req,res,next)=>console.log('ice cream man')]
8
- * POST: [(req,res,next)=>console.log('gelato')]
9
- * ALL: [(req,res,next)=>console.log('bruce banner')]
10
- * }
11
- */
12
- export const mergeMiddleware = (incoming, existing) => {
13
- const mergeInto = cloneMiddleware(existing)
14
-
15
- validateMiddleware(incoming)
16
- if (Array.isArray(incoming)) {
17
- mergeInto.ALL = (existing.ALL || []).concat(incoming)
18
- } else if (typeof incoming === 'object') {
19
- for (const method in incoming) {
20
- const upMethod = method.toUpperCase()
21
- mergeInto[upMethod] = (mergeInto[method] || []).concat(incoming[upMethod] || [])
22
- }
23
- }
24
- return mergeInto
25
- }
26
-
27
- export const cloneMiddleware = (middleware) => {
28
- const clone = { ...middleware }
29
- for (const method in middleware) {
30
- clone[method] = [...(middleware[method] || [])]
31
- }
32
- return clone
33
- }
34
-
35
- /**
36
- * Ensure the given middleware is valid
37
- * @param middleware
38
- */
39
- export const validateMiddleware = (middleware) => {
40
- if (!Array.isArray(middleware) && typeof middleware === 'object') {
41
- for (const method in middleware) {
42
- // ensure methods are always available as uppercase
43
- const upMethod = method.toUpperCase()
44
- middleware[upMethod] = middleware[method]
45
- validateMiddlewareArray(middleware[upMethod])
46
- }
47
- } else {
48
- validateMiddlewareArray(middleware)
49
- }
50
- }
51
-
52
- export const validateMiddlewareArray = (arr) => {
53
- if (!arr) return
54
- if (!Array.isArray(arr)) {
55
- throw new Error('middleware must be an array of functions')
56
- }
57
- for (const f of arr) {
58
- if (typeof f !== 'function') {
59
- throw new Error('Each element in the array of middleware must be a function')
60
- }
61
- }
62
- }
63
-
64
- export async function invokeMiddleware (middleware, req, res, reqErr) {
65
- await new Promise((resolve, reject) => {
66
- let current = -1
67
- const next = (err) => {
68
- if (err) reject(err)
69
- if (res.writableEnded) {
70
- resolve()
71
- return
72
- }
73
- current++
74
- if (current === middleware.length) {
75
- resolve()
76
- } else {
77
- try {
78
- if (reqErr) middleware[current](reqErr, req, res, next)
79
- else middleware[current](req, res, next)
80
- } catch (e) {
81
- log.error('Middleware threw exception', e)
82
- reject(e)
83
- }
84
- }
85
- }
86
-
87
- next()
88
- })
89
- }
1
+ import log from './log.mjs'
2
+ /**
3
+ * middleware is stored as an object where the properties are request methods the middleware applies to
4
+ * if a middleware applies to all methods, the property ALL is used
5
+ * example:
6
+ * {
7
+ * GET: [(req,res,next)=>console.log('ice cream man')]
8
+ * POST: [(req,res,next)=>console.log('gelato')]
9
+ * ALL: [(req,res,next)=>console.log('bruce banner')]
10
+ * }
11
+ */
12
+ export const mergeMiddleware = (incoming, existing) => {
13
+ const mergeInto = cloneMiddleware(existing)
14
+
15
+ validateMiddleware(incoming)
16
+ if (Array.isArray(incoming)) {
17
+ mergeInto.ALL = (existing.ALL || []).concat(incoming)
18
+ } else if (typeof incoming === 'object') {
19
+ for (const method in incoming) {
20
+ const upMethod = method.toUpperCase()
21
+ mergeInto[upMethod] = (mergeInto[method] || []).concat(incoming[upMethod] || [])
22
+ }
23
+ }
24
+ return mergeInto
25
+ }
26
+
27
+ export const cloneMiddleware = (middleware) => {
28
+ const clone = { ...middleware }
29
+ for (const method in middleware) {
30
+ clone[method] = [...(middleware[method] || [])]
31
+ }
32
+ return clone
33
+ }
34
+
35
+ /**
36
+ * Ensure the given middleware is valid
37
+ * @param middleware
38
+ */
39
+ export const validateMiddleware = (middleware) => {
40
+ if (!Array.isArray(middleware) && typeof middleware === 'object') {
41
+ for (const method in middleware) {
42
+ // ensure methods are always available as uppercase
43
+ const upMethod = method.toUpperCase()
44
+ middleware[upMethod] = middleware[method]
45
+ validateMiddlewareArray(middleware[upMethod])
46
+ }
47
+ } else {
48
+ validateMiddlewareArray(middleware)
49
+ }
50
+ }
51
+
52
+ export const validateMiddlewareArray = (arr) => {
53
+ if (!arr) return
54
+ if (!Array.isArray(arr)) {
55
+ throw new Error('middleware must be an array of functions')
56
+ }
57
+ for (const f of arr) {
58
+ if (typeof f !== 'function') {
59
+ throw new Error('Each element in the array of middleware must be a function')
60
+ }
61
+ }
62
+ }
63
+
64
+ export async function invokeMiddleware (middleware, req, res, reqErr) {
65
+ await new Promise((resolve, reject) => {
66
+ let current = -1
67
+ const next = (err) => {
68
+ if (err) reject(err)
69
+ if (res.writableEnded) {
70
+ resolve()
71
+ return
72
+ }
73
+ current++
74
+ if (current === middleware.length) {
75
+ resolve()
76
+ } else {
77
+ try {
78
+ if (reqErr) middleware[current](reqErr, req, res, next)
79
+ else middleware[current](req, res, next)
80
+ } catch (e) {
81
+ log.error('Middleware threw exception', e)
82
+ reject(e)
83
+ }
84
+ }
85
+ }
86
+
87
+ next()
88
+ })
89
+ }
@@ -1,75 +1,75 @@
1
- import fs from 'fs'
2
- import path from 'path'
3
- import { mergeMiddleware } from './middleware.mjs'
4
- import { createStaticHandler } from './staticHandler.mjs'
5
- import { getContentTypeByExtension } from './content.mjs'
6
-
7
- const stripLeadingSlash = p => p.startsWith('/') ? p.substr(1) : p
8
-
9
- /**
10
- This helper will add all the configured node_module files to the given routes.
11
- The configured node moduleRoutes must be explicit files, no pattern matching is supported.
12
- Generating the list of files using pattern matching yourself is highly discouraged.
13
- It is much safer to explicitly list every file you wish to be served so you don't inadvertently serve additional files.
14
-
15
- The default method is to read and serve directly from the node_modules directory without copying.
16
- if method is set to "copy", files are copied from node_modules to their final location within the routes dir folder.
17
-
18
- The primary benefit of using this in copy mode is that the files will be automatically updated when the package version
19
- is updated, and it improves IDE integration by making the file really available after first run.
20
-
21
- This could be destructive if not configured correctly, hence the default of read only
22
- */
23
- export function getNodeModuleRoutes (config) {
24
- const nodeModuleRoutes = config.nodeModuleRoutes
25
- const routes = []
26
- if (nodeModuleRoutes && typeof nodeModuleRoutes === 'object') {
27
- const nodeModulesDir = nodeModuleRoutes.nodeModulesPath ? path.resolve(nodeModuleRoutes.nodeModulesPath) : path.resolve(config.routeDir, '..', 'node_modules')
28
- if (!fs.existsSync(nodeModulesDir)) {
29
- throw new Error(`Unable to find node_modules dir at ${nodeModulesDir}`)
30
- }
31
- const prefix = stripLeadingSlash(nodeModuleRoutes.routePrefix || 'lib/ext')
32
- if (!Array.isArray(nodeModuleRoutes.files)) {
33
- nodeModuleRoutes.files = [nodeModuleRoutes.files]
34
- }
35
- for (const file of nodeModuleRoutes.files) {
36
- let filePath, urlPath
37
- if (file && typeof file === 'object') {
38
- filePath = path.join(nodeModulesDir, file.modulePath)
39
- urlPath = `/${prefix}/${stripLeadingSlash(file.urlPath || file.modulePath)}`
40
- } else if (file && typeof file === 'string') {
41
- filePath = path.join(nodeModulesDir, file)
42
- urlPath = `/${prefix}/${stripLeadingSlash(file)}`
43
- } else {
44
- throw new Error('Invalid node_module file: ' + file)
45
- }
46
-
47
- if (fs.existsSync(filePath)) {
48
- if (nodeModuleRoutes.method === 'copy') {
49
- const dest = path.join(config.routeDir, urlPath)
50
- fs.mkdirSync(path.dirname(dest), { recursive: true })
51
- fs.copyFileSync(filePath, dest)
52
- } else {
53
- const parts = urlPath.split('/')
54
- const lastPart = parts.pop()
55
- const mw = {}
56
- mergeMiddleware(config.middleware, mw)
57
- mergeMiddleware(nodeModuleRoutes.middleware || {}, mw)
58
- routes.push({
59
- pathParameters: [],
60
- urlPath,
61
- filePath,
62
- handlers: createStaticHandler(
63
- filePath, getContentTypeByExtension(lastPart, config.staticContentTypes),
64
- config.cacheStatic, config.staticCacheControl
65
- ),
66
- middleware: mw
67
- })
68
- }
69
- } else {
70
- console.warn(`The specified node_modules file: ${file} does not exist and will not be served.`)
71
- }
72
- }
73
- }
74
- return routes
75
- }
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import { mergeMiddleware } from './middleware.mjs'
4
+ import { createStaticHandler } from './staticHandler.mjs'
5
+ import { getContentTypeByExtension } from './content.mjs'
6
+
7
+ const stripLeadingSlash = p => p.startsWith('/') ? p.substr(1) : p
8
+
9
+ /**
10
+ This helper will add all the configured node_module files to the given routes.
11
+ The configured node moduleRoutes must be explicit files, no pattern matching is supported.
12
+ Generating the list of files using pattern matching yourself is highly discouraged.
13
+ It is much safer to explicitly list every file you wish to be served so you don't inadvertently serve additional files.
14
+
15
+ The default method is to read and serve directly from the node_modules directory without copying.
16
+ if method is set to "copy", files are copied from node_modules to their final location within the routes dir folder.
17
+
18
+ The primary benefit of using this in copy mode is that the files will be automatically updated when the package version
19
+ is updated, and it improves IDE integration by making the file really available after first run.
20
+
21
+ This could be destructive if not configured correctly, hence the default of read only
22
+ */
23
+ export function getNodeModuleRoutes (config) {
24
+ const nodeModuleRoutes = config.nodeModuleRoutes
25
+ const routes = []
26
+ if (nodeModuleRoutes && typeof nodeModuleRoutes === 'object') {
27
+ const nodeModulesDir = nodeModuleRoutes.nodeModulesPath ? path.resolve(nodeModuleRoutes.nodeModulesPath) : path.resolve(config.routeDir, '..', 'node_modules')
28
+ if (!fs.existsSync(nodeModulesDir)) {
29
+ throw new Error(`Unable to find node_modules dir at ${nodeModulesDir}`)
30
+ }
31
+ const prefix = stripLeadingSlash(nodeModuleRoutes.routePrefix || 'lib/ext')
32
+ if (!Array.isArray(nodeModuleRoutes.files)) {
33
+ nodeModuleRoutes.files = [nodeModuleRoutes.files]
34
+ }
35
+ for (const file of nodeModuleRoutes.files) {
36
+ let filePath, urlPath
37
+ if (file && typeof file === 'object') {
38
+ filePath = path.join(nodeModulesDir, file.modulePath)
39
+ urlPath = `/${prefix}/${stripLeadingSlash(file.urlPath || file.modulePath)}`
40
+ } else if (file && typeof file === 'string') {
41
+ filePath = path.join(nodeModulesDir, file)
42
+ urlPath = `/${prefix}/${stripLeadingSlash(file)}`
43
+ } else {
44
+ throw new Error('Invalid node_module file: ' + file)
45
+ }
46
+
47
+ if (fs.existsSync(filePath)) {
48
+ if (nodeModuleRoutes.method === 'copy') {
49
+ const dest = path.join(config.routeDir, urlPath)
50
+ fs.mkdirSync(path.dirname(dest), { recursive: true })
51
+ fs.copyFileSync(filePath, dest)
52
+ } else {
53
+ const parts = urlPath.split('/')
54
+ const lastPart = parts.pop()
55
+ const mw = {}
56
+ mergeMiddleware(config.middleware, mw)
57
+ mergeMiddleware(nodeModuleRoutes.middleware || {}, mw)
58
+ routes.push({
59
+ pathParameters: [],
60
+ urlPath,
61
+ filePath,
62
+ handlers: createStaticHandler(
63
+ filePath, getContentTypeByExtension(lastPart, config.staticContentTypes),
64
+ config.cacheStatic, config.staticCacheControl
65
+ ),
66
+ middleware: mw
67
+ })
68
+ }
69
+ } else {
70
+ console.warn(`The specified node_modules file: ${file} does not exist and will not be served.`)
71
+ }
72
+ }
73
+ }
74
+ return routes
75
+ }