@jsenv/server 12.6.0 → 12.6.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 +2 -2
- package/src/fetch_filesystem.js +21 -7
- package/src/fetch_url.js +1 -2
- package/src/serve_directory.js +1 -2
- package/src/startServer.js +26 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/server",
|
|
3
|
-
"version": "12.6.
|
|
3
|
+
"version": "12.6.3",
|
|
4
4
|
"description": "Write your Node.js server using pure functions",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
45
|
"@jsenv/abort": "4.1.2",
|
|
46
|
-
"@jsenv/logger": "4.
|
|
46
|
+
"@jsenv/logger": "4.1.1",
|
|
47
47
|
"@jsenv/url-meta": "6.2.0",
|
|
48
48
|
"node-fetch": "2.6.7",
|
|
49
49
|
"path-to-regexp": "6.2.0"
|
package/src/fetch_filesystem.js
CHANGED
|
@@ -39,20 +39,37 @@ export const fetchFileSystem = async (
|
|
|
39
39
|
? "private,max-age=0,must-revalidate"
|
|
40
40
|
: "no-store",
|
|
41
41
|
canReadDirectory = false,
|
|
42
|
-
rootDirectoryUrl,
|
|
42
|
+
rootDirectoryUrl, // = `${pathToFileURL(process.cwd())}/`,
|
|
43
43
|
} = {},
|
|
44
44
|
) => {
|
|
45
45
|
const urlString = asUrlString(filesystemUrl)
|
|
46
46
|
if (!urlString) {
|
|
47
|
-
return
|
|
47
|
+
return create500Response(
|
|
48
48
|
`fetchFileSystem first parameter must be a file url, got ${filesystemUrl}`,
|
|
49
49
|
)
|
|
50
50
|
}
|
|
51
51
|
if (!urlString.startsWith("file://")) {
|
|
52
|
-
return
|
|
52
|
+
return create500Response(
|
|
53
53
|
`fetchFileSystem url must use "file://" scheme, got ${filesystemUrl}`,
|
|
54
54
|
)
|
|
55
55
|
}
|
|
56
|
+
if (rootDirectoryUrl) {
|
|
57
|
+
let rootDirectoryUrlString = asUrlString(rootDirectoryUrl)
|
|
58
|
+
if (!rootDirectoryUrlString) {
|
|
59
|
+
return create500Response(
|
|
60
|
+
`rootDirectoryUrl must be a string or an url, got ${rootDirectoryUrl}`,
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
if (!rootDirectoryUrlString.endsWith("/")) {
|
|
64
|
+
rootDirectoryUrlString = `${rootDirectoryUrlString}/`
|
|
65
|
+
}
|
|
66
|
+
if (!urlString.startsWith(rootDirectoryUrlString)) {
|
|
67
|
+
return create500Response(
|
|
68
|
+
`fetchFileSystem url must be inside root directory, got ${urlString}`,
|
|
69
|
+
)
|
|
70
|
+
}
|
|
71
|
+
rootDirectoryUrl = rootDirectoryUrlString
|
|
72
|
+
}
|
|
56
73
|
|
|
57
74
|
// here you might be tempted to add || cacheControl === 'no-cache'
|
|
58
75
|
// but no-cache means ressource can be cache but must be revalidated (yeah naming is strange)
|
|
@@ -180,7 +197,7 @@ export const fetchFileSystem = async (
|
|
|
180
197
|
}
|
|
181
198
|
}
|
|
182
199
|
|
|
183
|
-
const
|
|
200
|
+
const create500Response = (message) => {
|
|
184
201
|
return {
|
|
185
202
|
status: 500,
|
|
186
203
|
headers: {
|
|
@@ -419,12 +436,10 @@ const asUrlString = (value) => {
|
|
|
419
436
|
if (value instanceof URL) {
|
|
420
437
|
return value.href
|
|
421
438
|
}
|
|
422
|
-
|
|
423
439
|
if (typeof value === "string") {
|
|
424
440
|
if (isFileSystemPath(value)) {
|
|
425
441
|
return fileSystemPathToUrl(value)
|
|
426
442
|
}
|
|
427
|
-
|
|
428
443
|
try {
|
|
429
444
|
const urlObject = new URL(value)
|
|
430
445
|
return String(urlObject)
|
|
@@ -432,6 +447,5 @@ const asUrlString = (value) => {
|
|
|
432
447
|
return null
|
|
433
448
|
}
|
|
434
449
|
}
|
|
435
|
-
|
|
436
450
|
return null
|
|
437
451
|
}
|
package/src/fetch_url.js
CHANGED
|
@@ -28,12 +28,11 @@ export const fetchUrl = async (
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
if (url.startsWith("file://")) {
|
|
31
|
-
const origin = new URL(url).origin
|
|
32
31
|
const responseProperties = await fetchFileSystem(url, {
|
|
33
32
|
signal,
|
|
34
33
|
method,
|
|
35
34
|
headers,
|
|
36
|
-
rootDirectoryUrl:
|
|
35
|
+
rootDirectoryUrl: "file://",
|
|
37
36
|
cacheStrategy,
|
|
38
37
|
canReadDirectory,
|
|
39
38
|
contentTypeMap,
|
package/src/serve_directory.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { readdirSync } from "node:fs"
|
|
2
|
-
import { pathToFileURL } from "node:url"
|
|
3
2
|
|
|
4
3
|
import { negotiateContentType } from "./content_negotiation/negotiateContentType.js"
|
|
5
4
|
|
|
6
5
|
export const serveDirectory = (
|
|
7
6
|
url,
|
|
8
|
-
{ headers = {}, rootDirectoryUrl
|
|
7
|
+
{ headers = {}, rootDirectoryUrl } = {},
|
|
9
8
|
) => {
|
|
10
9
|
url = String(url)
|
|
11
10
|
url = url[url.length - 1] === "/" ? url : `${url}/`
|
package/src/startServer.js
CHANGED
|
@@ -299,25 +299,47 @@ export const startServer = async ({
|
|
|
299
299
|
const prefixLines = (string, prefix) => {
|
|
300
300
|
return string.replace(/^(?!\s*$)/gm, prefix)
|
|
301
301
|
}
|
|
302
|
-
const writeLog = (
|
|
302
|
+
const writeLog = (
|
|
303
|
+
{ type, value },
|
|
304
|
+
{ someLogIsError, someLogIsWarn, depth },
|
|
305
|
+
) => {
|
|
303
306
|
if (depth > 0) {
|
|
304
307
|
value = prefixLines(value, " ".repeat(depth))
|
|
305
308
|
}
|
|
309
|
+
if (type === "info") {
|
|
310
|
+
if (someLogIsError) {
|
|
311
|
+
type = "error"
|
|
312
|
+
} else if (someLogIsWarn) {
|
|
313
|
+
type = "warn"
|
|
314
|
+
}
|
|
315
|
+
}
|
|
306
316
|
logger[type](value)
|
|
307
317
|
}
|
|
308
318
|
const visitRequestNodeToLog = (requestNode, depth) => {
|
|
319
|
+
let someLogIsError = false
|
|
320
|
+
let someLogIsWarn = false
|
|
321
|
+
requestNode.logs.forEach((log) => {
|
|
322
|
+
if (log.type === "error") {
|
|
323
|
+
someLogIsError = true
|
|
324
|
+
}
|
|
325
|
+
if (log.type === "warn") {
|
|
326
|
+
someLogIsWarn = true
|
|
327
|
+
}
|
|
328
|
+
})
|
|
329
|
+
|
|
309
330
|
const firstLog = requestNode.logs.shift()
|
|
310
331
|
const lastLog = requestNode.logs.pop()
|
|
311
332
|
const middleLogs = requestNode.logs
|
|
312
|
-
|
|
333
|
+
|
|
334
|
+
writeLog(firstLog, { someLogIsError, someLogIsWarn, depth })
|
|
313
335
|
middleLogs.forEach((log) => {
|
|
314
|
-
writeLog(log, depth)
|
|
336
|
+
writeLog(log, { someLogIsError, someLogIsWarn, depth })
|
|
315
337
|
})
|
|
316
338
|
requestNode.children.forEach((child) => {
|
|
317
339
|
visitRequestNodeToLog(child, depth + 1)
|
|
318
340
|
})
|
|
319
341
|
if (lastLog) {
|
|
320
|
-
writeLog(lastLog, depth + 1)
|
|
342
|
+
writeLog(lastLog, { someLogIsError, someLogIsWarn, depth: depth + 1 })
|
|
321
343
|
}
|
|
322
344
|
}
|
|
323
345
|
visitRequestNodeToLog(rootRequestNode, 0)
|