@kaliber/build 0.0.152 → 0.0.153

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. package/lib/serve.js +60 -30
  2. package/package.json +1 -1
package/lib/serve.js CHANGED
@@ -29,6 +29,8 @@ const internalServerError = '500.html'
29
29
  const port = process.env.PORT
30
30
  const isProduction = process.env.NODE_ENV === 'production'
31
31
 
32
+ const envRequire = isProduction ? require : require('import-fresh')
33
+
32
34
  const notCached = ['html', 'txt', 'json', 'xml']
33
35
 
34
36
  if (isProduction) app.use(morgan('combined'))
@@ -66,15 +68,8 @@ app.use((err, req, res, next) => {
66
68
  if (err.status && err.status >= 400 && err.status < 500)
67
69
  return res.status(err.status).send()
68
70
 
69
- console.error(err)
70
- if (reportError) reportError(err, req)
71
-
72
- const response = res.status(500)
73
- if (isProduction) {
74
- findFile(req.path, internalServerError)
75
- .then(file => file ? response.sendFile(file) : next())
76
- .catch(next)
77
- } else response.send(`<pre><title style='display: block;'>${err.stack || err.toString()}</title><pre>`)
71
+ reportServerError(err, req)
72
+ serveInternalServerError(err, { req, res, next })
78
73
  })
79
74
 
80
75
  app.listen(port, () => console.log(`Server listening at port ${port}`))
@@ -84,7 +79,7 @@ async function resolveFile(req, res, next) {
84
79
  const { path } = req
85
80
  /** @type {Array<[string, (file:any) => any]>} */
86
81
  const combinations = [
87
- [indexWithRouting, file => serveIndexWithRouting(req, res, file)],
82
+ [indexWithRouting, file => serveIndexWithRouting(file, req, res, next)],
88
83
  [notFound, file => res.status(404).sendFile(file)],
89
84
  [index, file => res.status(200).sendFile(file)],
90
85
  ]
@@ -112,7 +107,7 @@ async function findFile(path, file) {
112
107
  return null
113
108
  }
114
109
 
115
- async function fileExists(path) {
110
+ function fileExists(path) {
116
111
  return isProduction
117
112
  ? (!fileExists.cache || fileExists.cache[path] === undefined)
118
113
  ? accessFile(path).then(exists => (addPathToCache(path, exists), exists))
@@ -124,7 +119,7 @@ async function fileExists(path) {
124
119
  }
125
120
  }
126
121
 
127
- async function accessFile(path) {
122
+ function accessFile(path) {
128
123
  return new Promise(resolve => access(path, err => resolve(!err)))
129
124
  }
130
125
 
@@ -138,26 +133,61 @@ function possibleDirectories(path) {
138
133
  return possibleDirectories
139
134
  }
140
135
 
141
- function serveIndexWithRouting(req, res, file) {
142
- const envRequire = isProduction ? require : require('import-fresh')
136
+ function serveIndexWithRouting(file, req, res, next) {
143
137
  const routeTemplate = envRequire(file)
144
138
 
145
- const routes = routeTemplate.routes
146
139
  const location = parsePath(req.url)
147
140
 
148
- return Promise.resolve(routes)
149
- .then(routes => (routes && routes.match(location, req)) || { status: 200, data: null })
150
- .then(data => {
151
- if (!routes || !routes.resolveIndex) return [data, routeTemplate]
152
-
153
- const indexLocation = routes.resolveIndex(location, req)
154
- if (!indexLocation) return [data, routeTemplate]
155
-
156
- const indexPath = resolve(target, publicPathDir, indexLocation, indexWithRouting)
157
- return [data, envRequire(indexPath)]
158
- })
159
- .then(([{ status, headers, data }, template]) =>
160
- Promise.resolve(template({ location, data })).then(html => [status, headers, html])
161
- )
162
- .then(([ status, headers, html ]) => res.status(status).set(headers).send(html))
141
+ const [dataOrPromise, template] = getDataAndRouteTemplate(routeTemplate, location, req)
142
+
143
+ if (dataOrPromise.then)
144
+ dataOrPromise
145
+ .then(({ status, headers, data }) => {
146
+ const html = template({ location, data })
147
+ res.status(status).set(headers).send(html)
148
+ })
149
+ .catch(error => {
150
+ reportServerError(error, req)
151
+ serveInternalServerError(error, req, res, next)
152
+ })
153
+ else {
154
+ try {
155
+ const { data, status, headers } = dataOrPromise
156
+ const html = template({ location, data })
157
+ res.status(status).set(headers).send(html)
158
+ } catch (error) {
159
+ reportServerError(error, req)
160
+ serveInternalServerError(error, req, res, next)
161
+ }
162
+ }
163
+ }
164
+
165
+ function getDataAndRouteTemplate(routeTemplate, location, req) {
166
+
167
+ const routes = routeTemplate.routes
168
+ const dataOrPromise = (routes && routes.match(location, req)) || { status: 200, data: null }
169
+
170
+ if (!routes || !routes.resolveIndex)
171
+ return [dataOrPromise, routeTemplate]
172
+
173
+ const indexLocation = routes.resolveIndex(location, req)
174
+ if (!indexLocation)
175
+ return [dataOrPromise, routeTemplate]
176
+
177
+ const indexPath = resolve(target, publicPathDir, indexLocation, indexWithRouting)
178
+ return [dataOrPromise, envRequire(indexPath)]
179
+ }
180
+
181
+ function serveInternalServerError(error, res, req, next) {
182
+ const response = res.status(500)
183
+ if (isProduction) {
184
+ findFile(req.path, internalServerError)
185
+ .then(file => file ? response.sendFile(file) : next())
186
+ .catch(next)
187
+ } else response.send(`<pre><title style='display: block;'>${error.stack || error.toString()}</title><pre>`)
188
+ }
189
+
190
+ function reportServerError(error, req) {
191
+ console.error(error)
192
+ if (reportError) reportError(error, req)
163
193
  }
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.0.152",
2
+ "version": "0.0.153",
3
3
  "name": "@kaliber/build",
4
4
  "description": "Zero configuration, opinionated webpack / react build setup",
5
5
  "scripts": {