@srfnstack/spliffy 0.7.0 → 0.8.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.
package/src/handler.js DELETED
@@ -1,262 +0,0 @@
1
- const log = require( './log' )
2
- const content = require( './content' )
3
- const { executeMiddleware } = require( "./middleware" );
4
- const { decorateResponse } = require( './decorator.js' )
5
- const { decorateRequest } = require( './decorator.js' )
6
- const uuid = require( 'uuid' ).v4
7
- const { Readable } = require( 'stream' )
8
-
9
- /**
10
- * Execute the handler
11
- * @param url The url being requested
12
- * @param res The uws response object
13
- * @param req The uws request object
14
- * @param body The request body
15
- * @param handler The handler function for the route
16
- * @param middleware The middleware that applies to this request
17
- * @param errorTransformer An errorTransformer to convert error objects into response data
18
- */
19
- const executeHandler = async ( url, res, req, body, handler, middleware, errorTransformer ) => {
20
- try {
21
- if( body )
22
- body = content.deserialize( body, req.headers['content-type'] )
23
- } catch( e ) {
24
- log.error( 'Failed to parse request.', e )
25
- end( res, 400, 'Failed to parse request body' )
26
- return
27
- }
28
-
29
- try {
30
- let handled = handler(
31
- {
32
- url,
33
- body,
34
- headers: req.headers,
35
- req,
36
- res
37
- } )
38
- if( handled && typeof handled.then == 'function' ) {
39
- await handled.then( ( h ) => finalizeResponse( req, res, h ) )
40
- .catch(
41
- e => {
42
- let refId = uuid()
43
- log.error( 'handler failed', e, refId )
44
- endError( res, e, refId, errorTransformer )
45
- }
46
- )
47
- } else {
48
- finalizeResponse( req, res, handled )
49
- }
50
-
51
- } catch( e ) {
52
- let refId = uuid()
53
- log.error( 'handler failed', e, refId )
54
- await tryExecuteMiddleware( middleware, req, res, e, errorTransformer, refId )
55
- endError( res, e, refId, errorTransformer )
56
- }
57
- }
58
-
59
- const endError = ( res, e, refId, errorTransformer ) => {
60
- if( e.body && typeof e.body !== 'string' ) {
61
- e.body = JSON.stringify( e.body )
62
- }
63
- if( typeof errorTransformer === 'function' ) {
64
- e = errorTransformer( e, refId )
65
- }
66
- end( res, e.statusCode || 500, ( e.statusMessage || 'Internal Server Error' ) + ' refId: ' + refId, e.body || '' )
67
- }
68
-
69
- const end = ( res, code, message, body ) => {
70
- //status set directly on res wins
71
- res.statusCode = res.statusCode || code
72
- res.statusMessage = res.statusMessage || message
73
- if( body instanceof Readable || res.streaming ) {
74
- res.streaming = true
75
- if( body instanceof Readable ) {
76
- res.flushHeaders()
77
- pipeResponse( res, body )
78
- }
79
- //handler is responsible for ending the response if they are streaming
80
- } else {
81
- res.end( serializeBody( body, res ) || '' )
82
- }
83
- }
84
-
85
- const writeAccess = function( req, res ) {
86
- const start = new Date().getTime()
87
- return () => {
88
- log.access( req.remoteAddress, res.proxiedRemoteAddress || '', res.statusCode, req.method, req.url, new Date().getTime() - start + 'ms' )
89
- }
90
- }
91
-
92
- const finalizeResponse = ( req, res, handled ) => {
93
- if( !res.finalized ) {
94
- res.finalized = true
95
- if( !handled ) {
96
- //if no error was thrown, assume everything is fine. Otherwise each handler must return truthy which is un-necessary for methods that don't need to return anything
97
- end( res, 200, 'OK' )
98
- } else {
99
- //if the returned object has known fields, treat it as a response object instead of the body
100
- if( handled.body || handled.statusMessage || handled.statusCode || handled.headers ) {
101
- if( handled.headers ) {
102
- res.assignHeaders( handled.headers )
103
- }
104
- end( res, handled.statusCode || 200, handled.statusMessage || 'OK', handled.body )
105
- } else {
106
- end( res, 200, 'OK', handled )
107
- }
108
- }
109
- }
110
- }
111
-
112
- const pipeResponse = ( res, readStream, errorTransformer ) => {
113
- readStream.on( 'data', res.write )
114
- .on( 'end', res.end )
115
- .on( 'error', e => {
116
- try {
117
- readStream.destroy()
118
- } finally {
119
- endError( res, e, uuid(), errorTransformer )
120
- }
121
- } )
122
- }
123
-
124
- const serializeBody = ( body, res ) => {
125
- let contentType = res.getHeader( 'content-type' )
126
- if( typeof body === 'string' ) {
127
- if( !contentType ) {
128
- res.headers['content-type'] = 'text/plain'
129
- }
130
- return body
131
- } else if( body instanceof Readable ) {
132
- return body
133
- }
134
- let serialized = content.serialize( body, contentType )
135
-
136
- if( serialized && serialized.contentType && !contentType ) {
137
- res.headers['content-type'] = serialized.contentType
138
- }
139
- return serialized && serialized.data || ''
140
- }
141
-
142
- async function tryExecuteMiddleware( middleware, req, res, e, errorTransformer, refId ) {
143
- if( !middleware ) return
144
-
145
- let applicableMiddleware = middleware[req.method]
146
- if( middleware.ALL ) {
147
- if( applicableMiddleware ) applicableMiddleware = middleware.ALL.concat( applicableMiddleware )
148
- else applicableMiddleware = middleware.ALL
149
- }
150
-
151
- if( !applicableMiddleware || applicableMiddleware.length === 0 ) {
152
- return
153
- }
154
- const errorMiddleware = applicableMiddleware.filter( mw => mw.length === 4 )
155
- const middlewarez = applicableMiddleware.filter( mw => mw.length === 3 )
156
- try {
157
- if( e )
158
- await executeMiddleware( middlewarez, errorMiddleware, req, res, e )
159
- else
160
- await executeMiddleware( middlewarez, errorMiddleware, req, res )
161
- } catch( e ) {
162
- if( !refId ) refId = uuid()
163
- console.log( 'Failed executing middleware while handling error: ' + e )
164
- endError( res, e, refId, errorTransformer )
165
- }
166
- }
167
-
168
- let currentDate = new Date().toUTCString()
169
- setInterval( () => currentDate = new Date().toUTCString(), 1000 )
170
-
171
- const handleRequest = async ( req, res, handler, middleware, errorTransformer ) => {
172
- res.headers['server'] = 'uWebSockets.js'
173
- res.headers['date'] = currentDate
174
-
175
- try {
176
- let reqBody
177
- if( !handler.streamRequestBody ) {
178
- let buffer
179
- reqBody = await new Promise(
180
- resolve =>
181
- res.onData( async ( data, isLast ) => {
182
- if( isLast ) {
183
- buffer = data.byteLength > 0 ? Buffer.concat( [buffer, Buffer.from( data )].filter( b => b ) ) : buffer
184
- resolve( buffer )
185
- }
186
- buffer = Buffer.concat( [buffer, Buffer.from( data )].filter( b => b ) )
187
- } )
188
- )
189
- } else {
190
- reqBody = new Readable( {
191
- read: () => {
192
- }
193
- } )
194
- res.onData( async ( data, isLast ) => {
195
- if( data.byteLength === 0 && !isLast ) return
196
- //data must be copied so it isn't lost
197
- reqBody.push( Buffer.concat( [Buffer.from( data )] ) )
198
- if( isLast ) {
199
- reqBody.push( null )
200
- }
201
- } )
202
- }
203
- await tryExecuteMiddleware( middleware, req, res, errorTransformer )
204
- if( !res.writableEnded && !res.ended ) {
205
- await executeHandler( req.spliffyUrl, res, req, reqBody, handler, middleware, errorTransformer )
206
- }
207
- } catch( e ) {
208
- let refId = uuid()
209
- log.error( 'Handling request failed', e, refId )
210
- await tryExecuteMiddleware( middleware, req, res, e, errorTransformer, refId );
211
- if( !res.writableEnded )
212
- endError( res, e, refId, errorTransformer )
213
- }
214
- }
215
- const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD', 'CONNECT', 'TRACE']
216
- module.exports =
217
- {
218
- create: ( handler, middleware, pathParameters, config ) => function( res, req ) {
219
- try {
220
- req = decorateRequest( req, pathParameters, res, config );
221
- res = decorateResponse( res, req, finalizeResponse, config.errorTransformer, endError );
222
-
223
- if( config.logAccess ) {
224
- res.onEnd = writeAccess( req, res )
225
- }
226
- handleRequest( req, res, handler, middleware, config.errorTransformer )
227
- } catch( e ) {
228
- log.error( 'Failed handling request', e )
229
- }
230
- },
231
- notFound: config => ( res, req ) => {
232
- try {
233
- let params = config.defaultRoute && config.defaultRoute.pathParameters || []
234
- req = decorateRequest( req, params, res, config );
235
- res = decorateResponse( res, req, finalizeResponse );
236
- if( config.logAccess ) {
237
- res.onEnd = writeAccess( req, res )
238
- }
239
- if( config.defaultRoute && typeof config.defaultRoute ) {
240
- let route = config.defaultRoute
241
- if( route.handlers && route.handlers[req.method] ) {
242
- handleRequest( req, res,
243
- config.defaultRoute.handlers[req.method],
244
- config.defaultRoute.middleware,
245
- config.errorTransformer
246
- )
247
- } else {
248
- res.statusCode = 405
249
- res.statusMessage = 'Method Not Allowed'
250
- res.end()
251
- }
252
- } else {
253
- res.statusCode = 404
254
- res.statusMessage = 'Not Found'
255
- res.end()
256
- }
257
- } catch( e ) {
258
- log.error( 'Failed handling request', e )
259
- }
260
- },
261
- HTTP_METHODS
262
- }
package/src/index.js DELETED
@@ -1,29 +0,0 @@
1
- const log = require( './log' )
2
- let url = require('./url')
3
-
4
- /**
5
- * Startup function for the spliffy server
6
- * Startup will exponentially back off on consecutive failures
7
- * @param config See https://github.com/narcolepticsnowman/spliffy#config
8
- * @returns {Promise<Server>} Either the https server if https is configured or the http server
9
- */
10
- const spliffy = ( config ) => require( './start' )( config )
11
-
12
- /**
13
- * A helper for creating a redirect handler
14
- * @param location The location to redirect to
15
- * @param permanent Whether this is a permanent redirect or not
16
- */
17
- spliffy.redirect = ( location, permanent = true ) => () => ( {
18
- statusCode: permanent ? 301 : 302,
19
- statusMessage: permanent ? 'Moved Permanently' : 'Found',
20
- headers: {
21
- 'location': location
22
- }
23
- } )
24
-
25
- spliffy.log = log
26
- spliffy.parseQuery = url.parseQuery
27
- spliffy.setMultiValueKey = url.setMultiValueKey
28
-
29
- module.exports = spliffy
package/src/log.js DELETED
@@ -1,43 +0,0 @@
1
- const inspect = require( 'util' ).inspect
2
- const levelOrder = { DEBUG: 0, INFO: 1, 'GOOD NEWS EVERYONE!': 1, WARN: 2, ERROR: 3, NONE: 4 }
3
- let logAccess = true
4
- let logLevel = levelOrder.INFO
5
-
6
- const ifLevelEnabled = ( fn, level, args ) => {
7
- const configLevel = levelOrder[logLevel] || levelOrder.INFO
8
- if( !levelOrder[level] || levelOrder[level] >= configLevel ) {
9
- fn( `[${new Date().toISOString()}] [${level}] ${args.map( a => typeof a === 'string' ? a : inspect( a, { depth: null } ) ).join( ' ' )}` )
10
- }
11
- }
12
-
13
- module.exports = {
14
- setLogAccess( enable ) {
15
- logAccess = !!enable
16
- },
17
- setLogLevel( level ) {
18
- if( !levelOrder.hasOwnProperty( level ) ) {
19
- throw `Invalid level: ${level}`
20
- }
21
- logLevel = level
22
- },
23
- warning( e ) {
24
- ifLevelEnabled( console.warn, 'WARN', [...arguments] )
25
- },
26
- warn( e ) {
27
- ifLevelEnabled( console.warn, 'WARN', [...arguments] )
28
- },
29
- info( e ) {
30
- ifLevelEnabled( console.info, 'INFO', [...arguments] )
31
- },
32
- gne( e ) {
33
- ifLevelEnabled( console.info, 'GOOD NEWS EVERYONE!', [...arguments] )
34
- },
35
- access( e ) {
36
- if( logAccess ) {
37
- ifLevelEnabled( console.info, 'ACCESS', [...arguments] )
38
- }
39
- },
40
- error( e ) {
41
- ifLevelEnabled( console.error, 'ERROR', [...arguments].map( arg => arg.stack ? arg.stack : arg ) )
42
- }
43
- }
package/src/middleware.js DELETED
@@ -1,116 +0,0 @@
1
- const log = require( './log' )
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
- 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( let method in incoming ) {
20
- let upMethod = method.toUpperCase()
21
- mergeInto[upMethod] = ( mergeInto[method] || [] ).concat( incoming[upMethod] || [] )
22
- }
23
- }
24
- return mergeInto
25
- }
26
-
27
- const cloneMiddleware = ( middleware ) => {
28
- const clone = { ...middleware }
29
- for( let 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
- const validateMiddleware = ( middleware ) => {
40
- if( Array.isArray( middleware ) ) {
41
- validateMiddlewareArray( middleware )
42
- } else if( typeof middleware === 'object' ) {
43
- for( let method in middleware ) {
44
- //ensure methods are always available as uppercase
45
- let upMethod = method.toUpperCase()
46
- middleware[upMethod] = middleware[method]
47
- validateMiddlewareArray( middleware[upMethod] )
48
- }
49
- } else {
50
- throw new Error( 'Invalid middleware definition: ' + middleware )
51
- }
52
- }
53
-
54
- const validateMiddlewareArray = ( arr ) => {
55
- if( !Array.isArray( arr ) ) {
56
- throw 'middleware must be an array of functions'
57
- }
58
- for(let f of arr){
59
- if( typeof f !== 'function' ) {
60
- throw 'Each element in the array of middleware must be a function'
61
- }
62
- }
63
- }
64
-
65
- async function executeMiddleware( middleware, errorMiddleware, req, res, reqErr ) {
66
- let err
67
- await new Promise( ( resolve, reject ) => {
68
- let current = -1
69
- let isError = false
70
- const next = ( mwErr ) => {
71
- if( !isError && mwErr ) {
72
- isError = true
73
- current = -1
74
- }
75
- if( res.writableEnded ) {
76
- resolve()
77
- return
78
- }
79
- current++
80
- if( ( isError && current === errorMiddleware.length ) ||
81
- ( !isError && current === middleware.length )
82
- ) {
83
- if( mwErr )
84
- reject( mwErr )
85
- resolve()
86
- } else {
87
- try {
88
- let mw = isError ? errorMiddleware[current] : middleware[current]
89
- if( mwErr ) {
90
- mw( mwErr, req, res, next )
91
- } else {
92
- mw( req, res, next )
93
- }
94
- } catch( e ) {
95
-
96
- log.error( 'Middleware threw exception', e )
97
- next( e )
98
- }
99
- }
100
- }
101
-
102
- next( reqErr )
103
- } ).catch( e => {
104
- err = e
105
- return null
106
- } )
107
- if(err) throw err
108
- }
109
-
110
- module.exports = {
111
- validateMiddlewareArray,
112
- cloneMiddleware,
113
- validateMiddleware,
114
- mergeMiddleware,
115
- executeMiddleware
116
- }
@@ -1,63 +0,0 @@
1
- const fs = require( 'fs' )
2
- const path = require( 'path' )
3
- const { mergeMiddleware } = require( "./middleware" );
4
- const staticHandler = require( './staticHandler' )
5
- const { getContentTypeByExtension } = require( './content' )
6
-
7
- const stripLeadingSlash = p => p.startsWith( '/' ) ? p.substr( 1 ) : p
8
-
9
- module.exports = {
10
- /**
11
- This method will add all of the configured node_module files to the given routes.
12
- The configured node moduleRoutes must be explicit files, no pattern matching is supported.
13
- Generating the list of files using pattern matching yourself is highly discouraged.
14
- It is much safer to explicitly list every file you wish to be served so you don't inadvertently serve additional files.
15
- */
16
- getNodeModuleRoutes(config) {
17
- let nodeModuleRoutes = config.nodeModuleRoutes;
18
- let routes = []
19
- if( nodeModuleRoutes && typeof nodeModuleRoutes === 'object' ) {
20
- const nodeModulesDir = nodeModuleRoutes.nodeModulesPath ? path.resolve( nodeModuleRoutes.nodeModulesPath ) : path.resolve( config.routeDir, '..', 'node_modules' )
21
- if( !fs.existsSync( nodeModulesDir ) ) {
22
- throw new Error( `Unable to find node_modules dir at ${nodeModulesDir}` )
23
- }
24
- let prefix = stripLeadingSlash(nodeModuleRoutes.routePrefix || 'lib')
25
- if( !Array.isArray( nodeModuleRoutes.files ) ) {
26
- nodeModuleRoutes.files = [nodeModuleRoutes.files]
27
- }
28
- for( let file of nodeModuleRoutes.files ) {
29
- let filePath, urlPath
30
- if( file && typeof file === 'object' ) {
31
- filePath = path.join( nodeModulesDir, file.modulePath )
32
- urlPath = `/${prefix}/${stripLeadingSlash( file.urlPath || file.modulePath )}`
33
- } else if( file && typeof file === 'string' ) {
34
- filePath = path.join( nodeModulesDir, file )
35
- urlPath = `/${prefix}/${stripLeadingSlash( file )}`
36
- } else {
37
- throw new Error( 'Invalid node_module file: ' + file )
38
- }
39
-
40
- if( fs.existsSync( filePath ) ) {
41
- let parts = urlPath.split( '/' )
42
- let lastPart = parts.pop()
43
- let mw = {}
44
- mergeMiddleware( config.middleware, mw )
45
- mergeMiddleware( nodeModuleRoutes.middleware || {}, mw )
46
- routes.push( {
47
- pathParameters: [],
48
- urlPath,
49
- filePath,
50
- handlers: staticHandler.create(
51
- filePath, getContentTypeByExtension(lastPart, config.staticContentTypes),
52
- config.cacheStatic, config.staticCacheControl
53
- ),
54
- middleware: mw
55
- } )
56
- } else {
57
- console.warn( `The specified node_modules file: ${file} does not exist and will not be served.` )
58
- }
59
- }
60
- }
61
- return routes
62
- }
63
- }
package/src/routes.js DELETED
@@ -1,137 +0,0 @@
1
- const { validateMiddleware, mergeMiddleware } = require( "./middleware" )
2
- const staticHandler = require( './staticHandler' )
3
- const { getContentTypeByExtension } = require( "./content" )
4
- const fs = require( 'fs' )
5
- const path = require( 'path' )
6
- const { HTTP_METHODS } = require( './handler' )
7
-
8
- const isVariable = part => part.startsWith( '$' )
9
- const getVariableName = part => part.substr( 1 )
10
- const getPathPart = name => {
11
- if( name === 'index' ) {
12
- return ''
13
- }
14
- if( name.startsWith( '$' ) ) {
15
- return `:${name.substr( 1 )}`
16
- } else if( name.endsWith( '+' ) ) {
17
- return `${name.substr( 0, name.length - 1 )}/*`
18
- } else {
19
- return name
20
- }
21
- }
22
- const ignoreHandlerFields = { middleware: true, streamRequestBody: true }
23
- const doFindRoutes = ( config, currentFile, filePath, urlPath, pathParameters, inheritedMiddleware ) => {
24
- let routes = []
25
- let name = currentFile.name;
26
- if( currentFile.isDirectory() ) {
27
- if( isVariable( name ) ) {
28
- pathParameters = pathParameters.concat( getVariableName( name ) )
29
- }
30
- const files = fs.readdirSync( filePath, { withFileTypes: true } )
31
-
32
- const dirMiddleware = files
33
- .filter( f => f.name.endsWith( '.mw.js' ) )
34
- .map( f => {
35
- let mw = require( filePath + '/' + f.name )
36
- if( !mw.middleware ) {
37
- throw new Error( `${filePath + '/' + f.name} must export a middleware property` )
38
- }
39
- validateMiddleware( mw.middleware )
40
- return mw.middleware
41
- } )
42
- .reduce( ( result, incoming ) => mergeMiddleware( incoming, result ), inheritedMiddleware )
43
-
44
- routes = routes.concat( (
45
- files
46
- .filter( f => !f.name.endsWith( '.mw.js' ) )
47
- .map(
48
- ( f ) => doFindRoutes(
49
- config,
50
- f,
51
- filePath + '/' + f.name,
52
- urlPath + '/' + getPathPart( name ),
53
- pathParameters,
54
- dirMiddleware
55
- )
56
- )
57
- ).flat()
58
- )
59
- } else if( !config.staticMode && name.endsWith( '.rt.js' ) ) {
60
- name = name.substr( 0, name.length - '.rt.js'.length )
61
- if( isVariable( name ) ) {
62
- pathParameters = pathParameters.concat( getVariableName( name ) )
63
- }
64
- let route = {
65
- pathParameters,
66
- urlPath: `${urlPath}/${getPathPart( name )}`,
67
- filePath,
68
- handlers: {}
69
- }
70
- const handlers = require( filePath )
71
- route.middleware = mergeMiddleware( handlers.middleware || [], inheritedMiddleware )
72
- for( let method of Object.keys( handlers ).filter( k => !ignoreHandlerFields[k] ) ) {
73
- if( HTTP_METHODS.indexOf( method ) === -1 ) {
74
- throw `Method: ${method} in file ${filePath} is not a valid http method. It must be one of: ${HTTP_METHODS}. Method names must be all uppercase.`
75
- }
76
- let loadedHandler = handlers[method]
77
- let handler = loadedHandler
78
- if( typeof loadedHandler.handler === 'function' ) {
79
- handler = loadedHandler.handler
80
- }
81
- if( typeof handler !== 'function' ) {
82
- throw `Request method ${method} in file ${filePath} must be a function. Got: ${handlers[method]}`
83
- }
84
- if( !loadedHandler.hasOwnProperty( 'streamRequestBody' ) ) {
85
- handler.streamRequestBody = handlers.streamRequestBody
86
- } else {
87
- handler.streamRequestBody = loadedHandler.streamRequestBody
88
- }
89
- route.handlers[method] = handler
90
- }
91
- routes.push( route )
92
- } else {
93
- if( isVariable( name ) ) {
94
- pathParameters = pathParameters.concat( getVariableName( name ) )
95
- }
96
- let contentType = getContentTypeByExtension( name, config.staticContentTypes )
97
- let route = {
98
- pathParameters,
99
- urlPath: `${urlPath}/${getPathPart( name )}`,
100
- filePath,
101
- handlers: staticHandler.create( filePath, contentType,
102
- config.cacheStatic, config.staticCacheControl ),
103
- middleware: inheritedMiddleware
104
- }
105
-
106
- if( !route.handlers.OPTIONS ) {
107
-
108
- }
109
-
110
- routes.push( route )
111
-
112
- for( let ext of config.resolveWithoutExtension ) {
113
- if( name.endsWith( ext ) ) {
114
- let noExtRoute = Object.assign( {}, route )
115
- noExtRoute.urlPath = `${urlPath}/${getPathPart( name.substr( 0, name.length - ext.length ) )}`
116
- routes.push( noExtRoute )
117
- }
118
- }
119
- }
120
- return routes
121
- }
122
-
123
-
124
- module.exports = {
125
- findRoutes(config) {
126
- const fullRouteDir = path.resolve( config.routeDir )
127
- if( !fs.existsSync( fullRouteDir ) ) {
128
- throw `can't find route directory: ${fullRouteDir}`
129
- }
130
- let appMiddleware = mergeMiddleware( config.middleware || [], {} )
131
- return fs.readdirSync( fullRouteDir, { withFileTypes: true } )
132
- .map(
133
- f => doFindRoutes( config, f, fullRouteDir + '/' + f.name, '', [], appMiddleware )
134
- )
135
- .flat()
136
- }
137
- }
package/src/secure.js DELETED
@@ -1,39 +0,0 @@
1
- const fs = require( 'fs' )
2
- const log = require( './log' )
3
- const path = require( 'path' )
4
- const uws = require( 'uWebSockets.js' )
5
-
6
- const startHttpRedirect = ( host, port) => {
7
- //redirect http to https
8
- uws.App().any( "/*",
9
- ( req, res ) => {
10
- try {
11
- res.writeHead( 301, { 'Location': `https://${req.headers.host}:${port}${req.url}` } )
12
- res.end()
13
- } catch( e ) {
14
- log.error( `Failed to handle http request on port ${port}`, req.url, e )
15
- }
16
- }
17
- ).listen( host || '0.0.0.0', port, ( token ) => {
18
- if( token ) {
19
- log.gne( `Http redirect server initialized at ${new Date().toISOString()} and listening on port ${port}` )
20
- } else {
21
- throw new Error( `Failed to start server on port ${port}` )
22
- }
23
- } )
24
- }
25
-
26
- let getHttpsApp = ({ key, cert }) => {
27
- if( !key || !cert ) throw 'You must set secure.key and secure.cert in the config to use https!'
28
- let keyPath = path.resolve( key )
29
- let certPath = path.resolve( cert )
30
- if( !fs.existsSync( keyPath ) ) throw `Can't find https key file: ${keyPath}`
31
- if( !fs.existsSync( certPath ) ) throw `Can't find https cert file: ${keyPath}`
32
- return uws.App( {
33
- key_file_name: keyPath,
34
- cert_file_name: certPath
35
- } )
36
- }
37
- module.exports = {
38
- getHttpsApp, startHttpRedirect
39
- }