@srfnstack/spliffy 0.6.1 → 0.8.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/LICENSE.txt +0 -0
- package/README.md +0 -0
- package/package.json +16 -7
- package/src/content-types.mjs +75 -0
- package/src/content.mjs +95 -0
- package/src/decorator.mjs +205 -0
- package/src/handler.mjs +240 -0
- package/src/httpStatusCodes.mjs +103 -0
- package/src/index.mjs +31 -0
- package/src/log.mjs +59 -0
- package/src/middleware.mjs +90 -0
- package/src/nodeModuleHandler.mjs +61 -0
- package/src/routes.mjs +180 -0
- package/src/server.mjs +126 -0
- package/src/serverConfig.mjs +84 -0
- package/src/start.mjs +25 -0
- package/src/staticHandler.mjs +74 -0
- package/src/url.mjs +24 -0
- package/src/content-types.js +0 -75
- package/src/content.js +0 -82
- package/src/expressShim.js +0 -151
- package/src/handler.js +0 -275
- package/src/index.js +0 -25
- package/src/log.js +0 -43
- package/src/middleware.js +0 -116
- package/src/nodeModuleHandler.js +0 -61
- package/src/routes.js +0 -125
- package/src/secure.js +0 -42
- package/src/server.js +0 -83
- package/src/serverConfig.js +0 -69
- package/src/start.js +0 -22
- package/src/staticHandler.js +0 -79
- package/src/url.js +0 -48
package/src/server.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
const serverConfig = require( './serverConfig' )
|
|
2
|
-
const log = require( './log' )
|
|
3
|
-
const { getNodeModuleRoutes } = require( "./nodeModuleHandler" );
|
|
4
|
-
const uws = require( 'uWebSockets.js' )
|
|
5
|
-
const handler = require( './handler' )
|
|
6
|
-
const { findRoutes } = require( './routes' )
|
|
7
|
-
const { getHttpsApp, startHttpRedirect } = require( './secure' )
|
|
8
|
-
|
|
9
|
-
const state = {
|
|
10
|
-
routes: {},
|
|
11
|
-
initialized: false
|
|
12
|
-
}
|
|
13
|
-
const appMethods = {
|
|
14
|
-
GET: 'get',
|
|
15
|
-
POST: 'post',
|
|
16
|
-
PUT: 'put',
|
|
17
|
-
PATCH: 'patch',
|
|
18
|
-
DELETE: 'del',
|
|
19
|
-
OPTIONS: 'options',
|
|
20
|
-
HEAD: 'head',
|
|
21
|
-
CONNECT: 'connect',
|
|
22
|
-
TRACE: 'trace'
|
|
23
|
-
}
|
|
24
|
-
const optionsHandler = methods => {
|
|
25
|
-
return ( res ) => {
|
|
26
|
-
res.headers['allow'] = methods
|
|
27
|
-
res.writeStatus( '204' )
|
|
28
|
-
res.end()
|
|
29
|
-
}
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
/**
|
|
33
|
-
* Load the routes
|
|
34
|
-
*/
|
|
35
|
-
const start = () => {
|
|
36
|
-
if( !state.initialized ) {
|
|
37
|
-
state.initialized = true
|
|
38
|
-
const routes = [...findRoutes(), ...getNodeModuleRoutes()]
|
|
39
|
-
let app, port
|
|
40
|
-
if( serverConfig.current.secure ) {
|
|
41
|
-
app = getHttpsApp()
|
|
42
|
-
port = serverConfig.current.secure.port || 14420
|
|
43
|
-
startHttpRedirect()
|
|
44
|
-
} else {
|
|
45
|
-
app = uws.App()
|
|
46
|
-
port = serverConfig.current.port
|
|
47
|
-
}
|
|
48
|
-
for( let route of routes ) {
|
|
49
|
-
if( serverConfig.current.printRoutes ) {
|
|
50
|
-
log.info( 'Configured Route: ', route )
|
|
51
|
-
}
|
|
52
|
-
let routePattern = `^${route.urlPath.replace(/:[^/]+/g, "[^/]+").replace(/\*/g, ".*")}$`
|
|
53
|
-
if(serverConfig.current.notFoundRoute && serverConfig.current.notFoundRoute.match(routePattern)){
|
|
54
|
-
serverConfig.current.defaultRoute = route
|
|
55
|
-
}
|
|
56
|
-
for( let method in route.handlers ) {
|
|
57
|
-
let theHandler = handler.create( route.handlers[method], route.middleware, route.pathParameters );
|
|
58
|
-
app[appMethods[method]]( route.urlPath, theHandler )
|
|
59
|
-
if( route.urlPath.endsWith( '/' ) && route.urlPath.length > 1 ) {
|
|
60
|
-
app[appMethods[method]]( route.urlPath.substr(0,route.urlPath.length-1), theHandler )
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
if( !route.handlers.OPTIONS ) {
|
|
64
|
-
app.options( route.urlPath, optionsHandler( Object.keys( route.handlers ).join( ', ' ) ) )
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if(serverConfig.current.notFoundRoute && !serverConfig.current.defaultRoute) {
|
|
69
|
-
log.warn('No route matched default route: '+serverConfig.current.notFoundRoute)
|
|
70
|
-
}
|
|
71
|
-
app.any( '/*', handler.notFound )
|
|
72
|
-
app.listen( serverConfig.current.host || '0.0.0.0', serverConfig.current.port, ( token ) => {
|
|
73
|
-
if( token ) {
|
|
74
|
-
log.gne( `Server initialized at ${new Date().toISOString()} and listening on port ${port}` )
|
|
75
|
-
} else {
|
|
76
|
-
throw new Error( `Failed to start server on port ${port}` )
|
|
77
|
-
}
|
|
78
|
-
} )
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
module.exports = {
|
|
82
|
-
start
|
|
83
|
-
}
|
package/src/serverConfig.js
DELETED
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
const content = require( './content' )
|
|
2
|
-
const { validateMiddleware } = require( './middleware.js' )
|
|
3
|
-
const log = require( './log' )
|
|
4
|
-
let current = {}
|
|
5
|
-
const defaultHeaders = {
|
|
6
|
-
acceptsDefault: '*/*',
|
|
7
|
-
defaultContentType: '*/*'
|
|
8
|
-
}
|
|
9
|
-
//this is mainly for performance reason
|
|
10
|
-
const nonsense = [
|
|
11
|
-
'Is it getting hot in here?',
|
|
12
|
-
'Ouch...',
|
|
13
|
-
'Not feeling so good',
|
|
14
|
-
'Look a squirrel!',
|
|
15
|
-
'I swear I only had 3',
|
|
16
|
-
'I see a light...',
|
|
17
|
-
'Totally zooted',
|
|
18
|
-
'Where are my pants?',
|
|
19
|
-
'Somebody, anyone, help!',
|
|
20
|
-
'What was I doing again?',
|
|
21
|
-
'Burninating the codeessss',
|
|
22
|
-
'Leeeeerrrooooyyy Jeeenkins',
|
|
23
|
-
'At least I have chicken'
|
|
24
|
-
]
|
|
25
|
-
|
|
26
|
-
module.exports = {
|
|
27
|
-
current,
|
|
28
|
-
randomNonsense: () => `~[OHNO]{${nonsense[Math.floor( Math.random() * nonsense.length )]}}~`,
|
|
29
|
-
init( config ) {
|
|
30
|
-
Object.assign( current, config )
|
|
31
|
-
|
|
32
|
-
if( !config.hasOwnProperty( 'decodePathParameters' ) ) {
|
|
33
|
-
current.decodePathParameters = true
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
if( !config.hasOwnProperty( 'parseCookie' ) ) {
|
|
37
|
-
current.parseCookie = true
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
current.acceptsDefault = config.acceptsDefault || defaultHeaders.acceptsDefault
|
|
41
|
-
current.defaultContentType = config.defaultContentType || defaultHeaders.defaultContentType
|
|
42
|
-
|
|
43
|
-
content.initContentHandlers(config.contentHandlers||{}, current.acceptsDefault)
|
|
44
|
-
current.resolveWithoutExtension = current.resolveWithoutExtension || []
|
|
45
|
-
if( !Array.isArray( current.resolveWithoutExtension ) ) {
|
|
46
|
-
current.resolveWithoutExtension = [current.resolveWithoutExtension]
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if( current.resolveWithoutExtension.indexOf( '.htm' ) === -1 ) {
|
|
50
|
-
current.resolveWithoutExtension.push( '.htm' )
|
|
51
|
-
}
|
|
52
|
-
if( current.resolveWithoutExtension.indexOf( '.html' ) === -1 ) {
|
|
53
|
-
current.resolveWithoutExtension.push( '.html' )
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
if( current.middleware ) {
|
|
57
|
-
validateMiddleware( current.middleware )
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
if( !current.hasOwnProperty( 'logAccess' ) ) {
|
|
61
|
-
current.logAccess = true
|
|
62
|
-
}
|
|
63
|
-
log.setLogAccess( current.logAccess )
|
|
64
|
-
if( current.hasOwnProperty( 'logLevel' ) ) {
|
|
65
|
-
log.setLogLevel( current.logLevel )
|
|
66
|
-
}
|
|
67
|
-
current.port = config.port || 10420
|
|
68
|
-
}
|
|
69
|
-
}
|
package/src/start.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
const serverConfig = require( './serverConfig' )
|
|
2
|
-
const log = require( './log' )
|
|
3
|
-
const server = require('./server')
|
|
4
|
-
const { randomNonsense } = require( "./serverConfig" );
|
|
5
|
-
|
|
6
|
-
module.exports = async function( config ) {
|
|
7
|
-
if( !config || !config.routeDir ) {
|
|
8
|
-
throw 'You must supply a config object with at least a routeDir property. routeDir should be a full path.'
|
|
9
|
-
}
|
|
10
|
-
process
|
|
11
|
-
.on( 'unhandledRejection', ( reason, p ) => {
|
|
12
|
-
log.error( randomNonsense(), reason, 'Unhandled Rejection at Promise', p )
|
|
13
|
-
} )
|
|
14
|
-
.on( 'uncaughtException', ( err, origin ) => {
|
|
15
|
-
log.error( randomNonsense(), `Caught unhandled exception: ${err}\n` +
|
|
16
|
-
`Exception origin: ${origin}` )
|
|
17
|
-
} )
|
|
18
|
-
|
|
19
|
-
serverConfig.init( config )
|
|
20
|
-
log.gne( 'Starting Spliffy!' )
|
|
21
|
-
server.start()
|
|
22
|
-
}
|
package/src/staticHandler.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
const fs = require( 'fs' )
|
|
2
|
-
const etag = require( 'etag' )
|
|
3
|
-
const serverConfig = require( './serverConfig' )
|
|
4
|
-
|
|
5
|
-
const readFile = async ( fullPath ) => await new Promise(
|
|
6
|
-
( resolve, reject ) =>
|
|
7
|
-
fs.readFile( fullPath, ( err, data ) => {
|
|
8
|
-
if( err ) reject( err )
|
|
9
|
-
else resolve( data )
|
|
10
|
-
}
|
|
11
|
-
)
|
|
12
|
-
)
|
|
13
|
-
|
|
14
|
-
const writeHeaders = ( req, res, tag, stat, contentType ) => {
|
|
15
|
-
if( req.headers['if-none-match'] === tag ) {
|
|
16
|
-
res.statusCode = 304
|
|
17
|
-
res.statusMessage = 'Not Modified'
|
|
18
|
-
return
|
|
19
|
-
}
|
|
20
|
-
res.writeHead( 200, {
|
|
21
|
-
'Content-Type': contentType,
|
|
22
|
-
'Content-Length': stat.size,
|
|
23
|
-
'Cache-Control': serverConfig.current.staticCacheControl || 'max-age=600',
|
|
24
|
-
'ETag': tag
|
|
25
|
-
} )
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
const readStat = async path => new Promise( ( resolve, reject ) =>
|
|
29
|
-
fs.stat( path, ( err, stats ) =>
|
|
30
|
-
err ? reject( err ) : resolve( stats )
|
|
31
|
-
) )
|
|
32
|
-
|
|
33
|
-
module.exports = {
|
|
34
|
-
create: ( fullPath, contentType ) => {
|
|
35
|
-
const cache = {}
|
|
36
|
-
return {
|
|
37
|
-
GET: async ( { req, res } ) => {
|
|
38
|
-
if( serverConfig.current.cacheStatic ) {
|
|
39
|
-
if( !cache.exists || !cache.stat ) {
|
|
40
|
-
cache.exists = fs.existsSync( fullPath )
|
|
41
|
-
if( cache.exists ) {
|
|
42
|
-
cache.stat = await readStat( fullPath )
|
|
43
|
-
cache.content = await readFile( fullPath )
|
|
44
|
-
cache.etag = etag( cache.content )
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
if( !cache.exists ) {
|
|
48
|
-
return {
|
|
49
|
-
statusCode: 404,
|
|
50
|
-
statusMessage: 'Not Found'
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
writeHeaders( req, res, cache.etag, cache.stat, contentType )
|
|
54
|
-
if( res.statusCode === 304 ) {
|
|
55
|
-
return
|
|
56
|
-
}
|
|
57
|
-
return cache.content
|
|
58
|
-
} else {
|
|
59
|
-
if( !fs.existsSync( fullPath ) ) {
|
|
60
|
-
return {
|
|
61
|
-
statusCode: 404,
|
|
62
|
-
statusMessage: 'Not Found'
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
let stat = await readStat( fullPath )
|
|
66
|
-
writeHeaders( req, res, etag( stat ), stat, contentType )
|
|
67
|
-
if( res.statusCode === 304 ) {
|
|
68
|
-
return
|
|
69
|
-
}
|
|
70
|
-
res.flushHeaders()
|
|
71
|
-
if( stat.size === 0 ) {
|
|
72
|
-
return ""
|
|
73
|
-
}
|
|
74
|
-
return fs.createReadStream( fullPath )
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
package/src/url.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const serverConfig = require( './serverConfig' )
|
|
2
|
-
|
|
3
|
-
module.exports = {
|
|
4
|
-
parse: ( path, query ) => {
|
|
5
|
-
let parsed = { path: path, query: {} }
|
|
6
|
-
if( query ) {
|
|
7
|
-
if( serverConfig.current.decodeQueryParameters ) {
|
|
8
|
-
query = decodeURIComponent( query.replace( /\+/g, '%20' ) )
|
|
9
|
-
}
|
|
10
|
-
let key = ''
|
|
11
|
-
let value = ''
|
|
12
|
-
let isKey = true
|
|
13
|
-
|
|
14
|
-
for( let i = 0; i <= query.length; i++ ) {
|
|
15
|
-
if( i === query.length || query[i] === '&' ) {
|
|
16
|
-
//trailing or consecutive &
|
|
17
|
-
if( key === '' && value === '' ) continue
|
|
18
|
-
|
|
19
|
-
module.exports.setMultiValueKey( parsed.query, key, value )
|
|
20
|
-
|
|
21
|
-
key = ''
|
|
22
|
-
value = ''
|
|
23
|
-
isKey = true
|
|
24
|
-
} else if( query[i] === '=' ) {
|
|
25
|
-
isKey = false
|
|
26
|
-
} else {
|
|
27
|
-
if( isKey ) {
|
|
28
|
-
key += query[i]
|
|
29
|
-
} else {
|
|
30
|
-
value += query[i]
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return parsed
|
|
37
|
-
},
|
|
38
|
-
setMultiValueKey: ( obj, key, value ) => {
|
|
39
|
-
if( obj[key] ) {
|
|
40
|
-
if( !Array.isArray( obj[key] ) ) {
|
|
41
|
-
obj[key] = [obj[key]]
|
|
42
|
-
}
|
|
43
|
-
obj[key].push( value )
|
|
44
|
-
} else {
|
|
45
|
-
obj[key] = value
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|