@srfnstack/spliffy 1.2.3 → 1.2.5
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/package.json +3 -3
- package/src/decorator.mjs +29 -36
- package/src/handler.mjs +17 -15
- package/src/routes.mjs +4 -2
- package/src/server.mjs +8 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@srfnstack/spliffy",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.5",
|
|
4
4
|
"author": "snowbldr",
|
|
5
5
|
"private": false,
|
|
6
6
|
"homepage": "https://github.com/SRFNStack/spliffy",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"rest"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"cookie": "^0.
|
|
33
|
+
"cookie": "^1.0.2",
|
|
34
34
|
"etag": "^1.8.1",
|
|
35
35
|
"uuid": "^8.3.2",
|
|
36
|
-
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.
|
|
36
|
+
"uWebSockets.js": "github:uNetworking/uWebSockets.js#v20.51.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
39
|
"helmet": "^4.6.0",
|
package/src/decorator.mjs
CHANGED
|
@@ -92,21 +92,19 @@ export function decorateResponse (res, req, finalizeResponse, errorTransformer,
|
|
|
92
92
|
if (!res.statusCode) res.statusCode = httpStatusCodes.OK
|
|
93
93
|
if (!res.statusMessage) res.statusMessage = defaultStatusMessages[res.statusCode]
|
|
94
94
|
res.headersSent = true
|
|
95
|
-
res.
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
res.writeHeader(header, multiple.toString())
|
|
104
|
-
}
|
|
105
|
-
} else {
|
|
106
|
-
res.writeHeader(header, res.headers[header].toString())
|
|
95
|
+
res.writeStatus(`${res.statusCode} ${res.statusMessage}`)
|
|
96
|
+
if (typeof res.onFlushHeaders === 'function') {
|
|
97
|
+
res.onFlushHeaders(res)
|
|
98
|
+
}
|
|
99
|
+
for (const header of Object.keys(res.headers)) {
|
|
100
|
+
if (Array.isArray(res.headers[header])) {
|
|
101
|
+
for (const multiple of res.headers[header]) {
|
|
102
|
+
res.writeHeader(header, multiple.toString())
|
|
107
103
|
}
|
|
104
|
+
} else {
|
|
105
|
+
res.writeHeader(header, res.headers[header].toString())
|
|
108
106
|
}
|
|
109
|
-
}
|
|
107
|
+
}
|
|
110
108
|
}
|
|
111
109
|
res.writeHead = (status, headers) => {
|
|
112
110
|
res.statusCode = status
|
|
@@ -128,23 +126,20 @@ export function decorateResponse (res, req, finalizeResponse, errorTransformer,
|
|
|
128
126
|
res.uwsWrite = res.write
|
|
129
127
|
res.write = (chunk, encoding, cb) => {
|
|
130
128
|
try {
|
|
131
|
-
|
|
132
|
-
res.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
cb()
|
|
146
|
-
}
|
|
147
|
-
})
|
|
129
|
+
res.streaming = true
|
|
130
|
+
res.flushHeaders()
|
|
131
|
+
let data
|
|
132
|
+
if (chunk instanceof Buffer) {
|
|
133
|
+
data = toArrayBuffer(chunk)
|
|
134
|
+
} else if (typeof chunk === 'string') {
|
|
135
|
+
data = toArrayBuffer(Buffer.from(chunk, encoding || 'utf8'))
|
|
136
|
+
} else {
|
|
137
|
+
data = toArrayBuffer(Buffer.from(JSON.stringify(chunk), encoding || 'utf8'))
|
|
138
|
+
}
|
|
139
|
+
const result = res.uwsWrite(data)
|
|
140
|
+
if (typeof cb === 'function') {
|
|
141
|
+
cb()
|
|
142
|
+
}
|
|
148
143
|
return result
|
|
149
144
|
} catch (e) {
|
|
150
145
|
if (typeof cb === 'function') {
|
|
@@ -182,12 +177,10 @@ export function decorateResponse (res, req, finalizeResponse, errorTransformer,
|
|
|
182
177
|
}
|
|
183
178
|
// provide writableEnded like node does, with slightly different behavior
|
|
184
179
|
if (!res.writableEnded) {
|
|
185
|
-
res.
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
res.ended = true
|
|
190
|
-
})
|
|
180
|
+
res.flushHeaders()
|
|
181
|
+
uwsEnd.call(res, body)
|
|
182
|
+
res.writableEnded = true
|
|
183
|
+
res.ended = true
|
|
191
184
|
}
|
|
192
185
|
if (typeof res.onEnd === 'function') {
|
|
193
186
|
res.onEnd()
|
package/src/handler.mjs
CHANGED
|
@@ -185,30 +185,32 @@ const handleRequest = async (req, res, handler, middleware, errorTransformer) =>
|
|
|
185
185
|
}
|
|
186
186
|
}
|
|
187
187
|
|
|
188
|
-
export const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD', 'CONNECT', 'TRACE']
|
|
188
|
+
export const HTTP_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD', 'CONNECT', 'TRACE', 'WEBSOCKET']
|
|
189
189
|
|
|
190
190
|
let currentDate = new Date().toISOString()
|
|
191
191
|
setInterval(() => { currentDate = new Date().toISOString() }, 1000)
|
|
192
192
|
|
|
193
193
|
export const createHandler = (handler, middleware, pathParameters, config) => function (res, req) {
|
|
194
194
|
try {
|
|
195
|
-
|
|
196
|
-
|
|
195
|
+
res.cork(() => {
|
|
196
|
+
req = decorateRequest(req, pathParameters, res, config)
|
|
197
|
+
res = decorateResponse(res, req, finalizeResponse, config.errorTransformer, endError, config)
|
|
197
198
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
199
|
+
if (config.logAccess) {
|
|
200
|
+
res.onEnd = writeAccess(req, res)
|
|
201
|
+
}
|
|
201
202
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
203
|
+
if (config.writeDateHeader) {
|
|
204
|
+
res.headers.date = currentDate
|
|
205
|
+
}
|
|
205
206
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
207
|
+
handleRequest(req, res, handler, middleware, config.errorTransformer)
|
|
208
|
+
.catch(e => {
|
|
209
|
+
log.error('Failed handling request', e)
|
|
210
|
+
res.statusCode = 500
|
|
211
|
+
res.end()
|
|
212
|
+
})
|
|
213
|
+
})
|
|
212
214
|
} catch (e) {
|
|
213
215
|
log.error('Failed handling request', e)
|
|
214
216
|
res.statusCode = 500
|
package/src/routes.mjs
CHANGED
|
@@ -140,8 +140,10 @@ const buildJSHandlerRoute = async (name, filePath, urlPath, inheritedMiddleware,
|
|
|
140
140
|
if (typeof loadedHandler.handler === 'function') {
|
|
141
141
|
handler = loadedHandler.handler
|
|
142
142
|
}
|
|
143
|
-
if (typeof handler !== 'function') {
|
|
144
|
-
throw new Error(`Request method ${method} in file ${filePath} must be a function. Got: ${handlers[method]}`)
|
|
143
|
+
if (typeof handler !== 'function' && method !== 'WEBSOCKET') {
|
|
144
|
+
throw new Error(`Request method ${method} in file ${filePath} must be a function. Got: ${typeof handlers[method]}`)
|
|
145
|
+
} else if (method === 'WEBSOCKET' && typeof handler !== 'object') {
|
|
146
|
+
throw new Error(`Websocket in file ${filePath} must be an object. Got: ${typeof handlers[method]}`)
|
|
145
147
|
}
|
|
146
148
|
if (!('streamRequestBody' in loadedHandler)) {
|
|
147
149
|
handler.streamRequestBody = handlers.streamRequestBody
|
package/src/server.mjs
CHANGED
|
@@ -19,7 +19,8 @@ const appMethods = {
|
|
|
19
19
|
OPTIONS: 'options',
|
|
20
20
|
HEAD: 'head',
|
|
21
21
|
CONNECT: 'connect',
|
|
22
|
-
TRACE: 'trace'
|
|
22
|
+
TRACE: 'trace',
|
|
23
|
+
WEBSOCKET: 'ws'
|
|
23
24
|
}
|
|
24
25
|
const optionsHandler = (config, middleware, methods) => {
|
|
25
26
|
return createHandler(() => ({
|
|
@@ -97,7 +98,12 @@ export async function startServer (config) {
|
|
|
97
98
|
route.urlPath = route.urlPath.substring(0, route.urlPath.length - 1)
|
|
98
99
|
}
|
|
99
100
|
for (const method in route.handlers) {
|
|
100
|
-
|
|
101
|
+
let theHandler = null
|
|
102
|
+
if (method === 'WEBSOCKET') {
|
|
103
|
+
theHandler = route.handlers[method]
|
|
104
|
+
} else {
|
|
105
|
+
theHandler = createHandler(route.handlers[method], route.middleware, route.pathParameters, config)
|
|
106
|
+
}
|
|
101
107
|
app[appMethods[method]](route.urlPath, theHandler)
|
|
102
108
|
if (hadSlash && config.serveRoutesWithSlash) {
|
|
103
109
|
app[appMethods[method]](route.urlPath + '/', theHandler)
|