@srfnstack/spliffy 0.9.0 → 0.9.3

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@srfnstack/spliffy",
3
- "version": "0.9.0",
3
+ "version": "0.9.3",
4
4
  "author": "snowbldr",
5
5
  "private": false,
6
6
  "homepage": "https://github.com/narcolepticsnowman/spliffy",
@@ -39,6 +39,6 @@
39
39
  "standard": "^16.0.4",
40
40
  "helmet": "^4.6.0",
41
41
  "jest": "^27.3.1",
42
- "node-fetch": "^2.6.6"
42
+ "node-fetch": "^2.6.7"
43
43
  }
44
44
  }
package/src/errors.mjs ADDED
@@ -0,0 +1,254 @@
1
+ export class HttpError extends Error {
2
+ constructor (statusCode, statusMessage, body) {
3
+ super()
4
+ this.statusCode = statusCode
5
+ this.statusMessage = statusMessage
6
+ this.body = body
7
+ }
8
+ }
9
+
10
+ export class BadRequestError extends HttpError {
11
+ constructor (body) {
12
+ super(400, 'Bad Request', body)
13
+ }
14
+ }
15
+
16
+ export class UnauthorizedError extends HttpError {
17
+ constructor (body) {
18
+ super(401, 'Unauthorized', body)
19
+ }
20
+ }
21
+
22
+ export class PaymentRequiredError extends HttpError {
23
+ constructor (body) {
24
+ super(402, 'Payment Required', body)
25
+ }
26
+ }
27
+
28
+ export class ForbiddenError extends HttpError {
29
+ constructor (body) {
30
+ super(403, 'Forbidden', body)
31
+ }
32
+ }
33
+
34
+ export class NotFoundError extends HttpError {
35
+ constructor (body) {
36
+ super(404, 'Not Found', body)
37
+ }
38
+ }
39
+
40
+ export class MethodNotAllowedError extends HttpError {
41
+ constructor (body) {
42
+ super(405, 'Method Not Allowed', body)
43
+ }
44
+ }
45
+
46
+ export class NotAcceptableError extends HttpError {
47
+ constructor (body) {
48
+ super(406, 'Not Acceptable', body)
49
+ }
50
+ }
51
+
52
+ export class ProxyAuthenticationRequiredError extends HttpError {
53
+ constructor (body) {
54
+ super(407, 'Proxy Authentication Required', body)
55
+ }
56
+ }
57
+
58
+ export class RequestTimeoutError extends HttpError {
59
+ constructor (body) {
60
+ super(408, 'Request Timeout', body)
61
+ }
62
+ }
63
+
64
+ export class ConflictError extends HttpError {
65
+ constructor (body) {
66
+ super(409, 'Conflict', body)
67
+ }
68
+ }
69
+
70
+ export class GoneError extends HttpError {
71
+ constructor (body) {
72
+ super(410, 'Gone', body)
73
+ }
74
+ }
75
+
76
+ export class LengthRequiredError extends HttpError {
77
+ constructor (body) {
78
+ super(411, 'Length Required', body)
79
+ }
80
+ }
81
+
82
+ export class PreconditionFailedError extends HttpError {
83
+ constructor (body) {
84
+ super(412, 'Precondition Failed', body)
85
+ }
86
+ }
87
+
88
+ export class PayloadTooLargeError extends HttpError {
89
+ constructor (body) {
90
+ super(413, 'Payload Too Large', body)
91
+ }
92
+ }
93
+
94
+ export class URITooLongError extends HttpError {
95
+ constructor (body) {
96
+ super(414, 'URI Too Long', body)
97
+ }
98
+ }
99
+
100
+ export class UnsupportedMediaTypeError extends HttpError {
101
+ constructor (body) {
102
+ super(415, 'Unsupported Media Type', body)
103
+ }
104
+ }
105
+
106
+ export class RangeNotSatisfiableError extends HttpError {
107
+ constructor (body) {
108
+ super(416, 'Bad Request', body)
109
+ }
110
+ }
111
+
112
+ export class ExpectationFailedError extends HttpError {
113
+ constructor (body) {
114
+ super(417, 'Expectation Failed', body)
115
+ }
116
+ }
117
+
118
+ export class ImATeapotError extends HttpError {
119
+ constructor (body) {
120
+ super(418, 'I can\'t brew coffee', body)
121
+ }
122
+ }
123
+
124
+ export class EnhanceYourCalmError extends HttpError {
125
+ constructor (body) {
126
+ super(420, 'Enhance Your Calm', body)
127
+ }
128
+ }
129
+
130
+ export class MisdirectedRequestError extends HttpError {
131
+ constructor (body) {
132
+ super(421, 'Misdirected Request', body)
133
+ }
134
+ }
135
+
136
+ export class UnprocessableEntityError extends HttpError {
137
+ constructor (body) {
138
+ super(422, 'Unprocessable Entity', body)
139
+ }
140
+ }
141
+
142
+ export class LockedError extends HttpError {
143
+ constructor (body) {
144
+ super(423, 'Locked', body)
145
+ }
146
+ }
147
+
148
+ export class FailedDependencyError extends HttpError {
149
+ constructor (body) {
150
+ super(424, 'Failed Dependency', body)
151
+ }
152
+ }
153
+
154
+ export class TooEarlyError extends HttpError {
155
+ constructor (body) {
156
+ super(425, 'Too Early', body)
157
+ }
158
+ }
159
+
160
+ export class UpgradeRequiredError extends HttpError {
161
+ constructor (body) {
162
+ super(426, 'Upgrade Required', body)
163
+ }
164
+ }
165
+
166
+ export class PreconditionRequiredError extends HttpError {
167
+ constructor (body) {
168
+ super(428, 'Precondition Required', body)
169
+ }
170
+ }
171
+
172
+ export class TooManyRequestsError extends HttpError {
173
+ constructor (body) {
174
+ super(429, 'Too Many Requests', body)
175
+ }
176
+ }
177
+
178
+ export class RequestHeaderFieldsTooLargeError extends HttpError {
179
+ constructor (body) {
180
+ super(431, 'Request Header Fields Too Large', body)
181
+ }
182
+ }
183
+
184
+ export class UnavailableForLegalReasonsError extends HttpError {
185
+ constructor (body) {
186
+ super(451, 'Unavailable For Legal Reasons', body)
187
+ }
188
+ }
189
+
190
+ export class InternalServerError extends HttpError {
191
+ constructor (body) {
192
+ super(500, 'Internal Server Error', body)
193
+ }
194
+ }
195
+
196
+ export class NotImplementedError extends HttpError {
197
+ constructor (body) {
198
+ super(501, 'Not Implemented', body)
199
+ }
200
+ }
201
+
202
+ export class BadGatewayError extends HttpError {
203
+ constructor (body) {
204
+ super(502, 'Bad Gateway', body)
205
+ }
206
+ }
207
+
208
+ export class ServiceUnavailableError extends HttpError {
209
+ constructor (body) {
210
+ super(503, 'Service Unavailable', body)
211
+ }
212
+ }
213
+
214
+ export class GatewayTimeoutError extends HttpError {
215
+ constructor (body) {
216
+ super(504, 'Gateway Timeout', body)
217
+ }
218
+ }
219
+
220
+ export class HTTPVersionNotSupportedError extends HttpError {
221
+ constructor (body) {
222
+ super(505, 'HTTP Version Not Supported', body)
223
+ }
224
+ }
225
+
226
+ export class VariantAlsoNegotiatesError extends HttpError {
227
+ constructor (body) {
228
+ super(506, 'Variant Also Negotiates', body)
229
+ }
230
+ }
231
+
232
+ export class InsufficientStorageError extends HttpError {
233
+ constructor (body) {
234
+ super(507, 'Insufficient Storage', body)
235
+ }
236
+ }
237
+
238
+ export class LoopDetectedError extends HttpError {
239
+ constructor (body) {
240
+ super(508, 'Loop Detected', body)
241
+ }
242
+ }
243
+
244
+ export class NotExtendedError extends HttpError {
245
+ constructor (body) {
246
+ super(510, 'Not Extended', body)
247
+ }
248
+ }
249
+
250
+ export class NetworkAuthenticationRequiredError extends HttpError {
251
+ constructor (body) {
252
+ super(511, 'Network Authentication Required', body)
253
+ }
254
+ }
@@ -37,9 +37,7 @@ export const cloneMiddleware = (middleware) => {
37
37
  * @param middleware
38
38
  */
39
39
  export const validateMiddleware = (middleware) => {
40
- if (Array.isArray(middleware)) {
41
- validateMiddlewareArray(middleware)
42
- } else if (typeof middleware === 'object') {
40
+ if (!Array.isArray(middleware) && typeof middleware === 'object') {
43
41
  for (const method in middleware) {
44
42
  // ensure methods are always available as uppercase
45
43
  const upMethod = method.toUpperCase()
@@ -47,7 +45,7 @@ export const validateMiddleware = (middleware) => {
47
45
  validateMiddlewareArray(middleware[upMethod])
48
46
  }
49
47
  } else {
50
- throw new Error('Invalid middleware definition: ' + middleware)
48
+ validateMiddlewareArray(middleware)
51
49
  }
52
50
  }
53
51
 
package/src/routes.mjs CHANGED
@@ -44,6 +44,16 @@ const doFindRoutes = async (config, currentFile, filePath, urlPath, pathParamete
44
44
  return routes
45
45
  }
46
46
 
47
+ const wrapSyntaxError = (e, path) => {
48
+ // Hack to workaround https://github.com/nodejs/modules/issues/471
49
+ if (e instanceof SyntaxError) {
50
+ const newError = new SyntaxError(`${e.message}. In file: ${path}`)
51
+ newError.stack += `\nCaused By: ${e.stack}`
52
+ throw newError
53
+ }
54
+ throw e
55
+ }
56
+
47
57
  const importModules = async (config, dirPath, files) => Promise.all(
48
58
  files
49
59
  .filter(filterTestFiles(config))
@@ -51,6 +61,7 @@ const importModules = async (config, dirPath, files) => Promise.all(
51
61
  .map(f => path.join(dirPath, f.name))
52
62
  .map(mwPath => import(`file://${mwPath}`)
53
63
  .then(module => ({ module, mwPath }))
64
+ .catch(e => wrapSyntaxError(e, mwPath))
54
65
  ))
55
66
 
56
67
  const findRoutesInDir = async (name, filePath, urlPath, inheritedMiddleware, pathParameters, config) => {
@@ -106,10 +117,20 @@ const buildJSHandlerRoute = async (name, filePath, urlPath, inheritedMiddleware,
106
117
  filePath,
107
118
  handlers: {}
108
119
  }
109
- const module = await import(`file://${filePath}`)
120
+ let module
121
+ try {
122
+ module = await import(`file://${filePath}`)
123
+ } catch (e) {
124
+ wrapSyntaxError(e, filePath)
125
+ }
110
126
  const handlers = module.default
111
-
112
- route.middleware = mergeMiddleware(handlers.middleware || [], inheritedMiddleware)
127
+ try {
128
+ route.middleware = mergeMiddleware(handlers.middleware || [], inheritedMiddleware)
129
+ } catch (e) {
130
+ const err = new Error(`Failed to load middleware for route: ${filePath}`)
131
+ err.stack += `\nCaused By: ${e.stack}`
132
+ throw err
133
+ }
113
134
  for (const method of Object.keys(handlers).filter(k => !ignoreHandlerFields[k])) {
114
135
  if (HTTP_METHODS.indexOf(method) === -1) {
115
136
  throw new Error(`Method: ${method} in file ${filePath} is not a valid http method. It must be one of: ${HTTP_METHODS}. Method names must be all uppercase.`)