@atria/server 0.0.10 → 0.0.13
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/README.md +26 -10
- package/dist/auth/cookies.d.ts +11 -0
- package/dist/auth/cookies.js +38 -0
- package/dist/auth/cookies.js.map +1 -0
- package/dist/auth/hash.d.ts +2 -0
- package/dist/auth/hash.js +36 -0
- package/dist/auth/hash.js.map +1 -0
- package/dist/auth/oauth.d.ts +5 -0
- package/dist/auth/oauth.js +215 -0
- package/dist/auth/oauth.js.map +1 -0
- package/dist/auth/runtime.d.ts +28 -0
- package/dist/auth/runtime.js +539 -0
- package/dist/auth/runtime.js.map +1 -0
- package/dist/auth/store.d.ts +43 -0
- package/dist/auth/store.js +68 -0
- package/dist/auth/store.js.map +1 -0
- package/dist/auth/types.d.ts +40 -0
- package/dist/auth/types.js +2 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/auth/validation.d.ts +21 -0
- package/dist/auth/validation.js +97 -0
- package/dist/auth/validation.js.map +1 -0
- package/dist/dev/admin/assets.d.ts +2 -0
- package/dist/dev/admin/assets.js +30 -0
- package/dist/dev/admin/assets.js.map +1 -0
- package/dist/dev/admin/i18n.d.ts +2 -0
- package/dist/dev/admin/i18n.js +63 -0
- package/dist/dev/admin/i18n.js.map +1 -0
- package/dist/dev/admin/index.d.ts +3 -0
- package/dist/dev/admin/index.js +4 -0
- package/dist/dev/admin/index.js.map +1 -0
- package/dist/dev/admin/request.d.ts +14 -0
- package/dist/dev/admin/request.js +77 -0
- package/dist/dev/admin/request.js.map +1 -0
- package/dist/dev/admin/routing.d.ts +5 -0
- package/dist/dev/admin/routing.js +31 -0
- package/dist/dev/admin/routing.js.map +1 -0
- package/dist/dev/admin-assets.d.ts +2 -0
- package/dist/dev/admin-assets.js +30 -0
- package/dist/dev/admin-assets.js.map +1 -0
- package/dist/dev/admin.d.ts +2 -0
- package/dist/dev/admin.js +30 -0
- package/dist/dev/admin.js.map +1 -0
- package/dist/dev/constants.d.ts +12 -0
- package/dist/dev/constants.js +23 -0
- package/dist/dev/constants.js.map +1 -0
- package/dist/dev/health/index.d.ts +2 -0
- package/dist/dev/health/index.js +3 -0
- package/dist/dev/health/index.js.map +1 -0
- package/dist/dev/health/request.d.ts +14 -0
- package/dist/dev/health/request.js +22 -0
- package/dist/dev/health/request.js.map +1 -0
- package/dist/dev/health/state.d.ts +9 -0
- package/dist/dev/health/state.js +52 -0
- package/dist/dev/health/state.js.map +1 -0
- package/dist/dev/health.d.ts +9 -0
- package/dist/dev/health.js +52 -0
- package/dist/dev/health.js.map +1 -0
- package/dist/dev/http/errors.d.ts +3 -0
- package/dist/dev/http/errors.js +10 -0
- package/dist/dev/http/errors.js.map +1 -0
- package/dist/dev/http/routing.d.ts +3 -0
- package/dist/dev/http/routing.js +26 -0
- package/dist/dev/http/routing.js.map +1 -0
- package/dist/dev/i18n.d.ts +2 -0
- package/dist/dev/i18n.js +63 -0
- package/dist/dev/i18n.js.map +1 -0
- package/dist/dev/lifecycle.d.ts +2 -0
- package/dist/dev/lifecycle.js +10 -0
- package/dist/dev/lifecycle.js.map +1 -0
- package/dist/dev/public/index.d.ts +1 -0
- package/dist/dev/public/index.js +2 -0
- package/dist/dev/public/index.js.map +1 -0
- package/dist/dev/public/request.d.ts +9 -0
- package/dist/dev/public/request.js +29 -0
- package/dist/dev/public/request.js.map +1 -0
- package/dist/dev/public/responses.d.ts +3 -0
- package/dist/dev/public/responses.js +25 -0
- package/dist/dev/public/responses.js.map +1 -0
- package/dist/dev/public/routing.d.ts +1 -0
- package/dist/dev/public/routing.js +5 -0
- package/dist/dev/public/routing.js.map +1 -0
- package/dist/dev/responses.d.ts +2 -0
- package/dist/dev/responses.js +3 -0
- package/dist/dev/responses.js.map +1 -0
- package/dist/dev/routing.d.ts +3 -0
- package/dist/dev/routing.js +4 -0
- package/dist/dev/routing.js.map +1 -0
- package/dist/dev/setup/index.d.ts +2 -0
- package/dist/dev/setup/index.js +2 -0
- package/dist/dev/setup/index.js.map +1 -0
- package/dist/dev/setup/request.d.ts +5 -0
- package/dist/dev/setup/request.js +20 -0
- package/dist/dev/setup/request.js.map +1 -0
- package/dist/dev/setup/types.d.ts +5 -0
- package/dist/dev/setup/types.js +2 -0
- package/dist/dev/setup/types.js.map +1 -0
- package/dist/dev/static/files.d.ts +6 -0
- package/dist/dev/static/files.js +74 -0
- package/dist/dev/static/files.js.map +1 -0
- package/dist/dev/static/index.d.ts +4 -0
- package/dist/dev/static/index.js +5 -0
- package/dist/dev/static/index.js.map +1 -0
- package/dist/dev/static/paths.d.ts +1 -0
- package/dist/dev/static/paths.js +6 -0
- package/dist/dev/static/paths.js.map +1 -0
- package/dist/dev/static/publish.d.ts +1 -0
- package/dist/dev/static/publish.js +13 -0
- package/dist/dev/static/publish.js.map +1 -0
- package/dist/dev/static/resolver.d.ts +2 -0
- package/dist/dev/static/resolver.js +53 -0
- package/dist/dev/static/resolver.js.map +1 -0
- package/dist/dev/static/sender.d.ts +2 -0
- package/dist/dev/static/sender.js +26 -0
- package/dist/dev/static/sender.js.map +1 -0
- package/dist/dev/static-files.d.ts +6 -0
- package/dist/dev/static-files.js +74 -0
- package/dist/dev/static-files.js.map +1 -0
- package/dist/dev/types.d.ts +10 -0
- package/dist/dev/types.js +2 -0
- package/dist/dev/types.js.map +1 -0
- package/dist/server.js +74 -191
- package/dist/server.js.map +1 -1
- package/package.json +4 -2
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { MIME_TYPES } from "../constants.js";
|
|
4
|
+
export const isInsideDirectory = (basePath, targetPath) => {
|
|
5
|
+
const relativePath = path.relative(basePath, targetPath);
|
|
6
|
+
return relativePath !== "" && !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
|
|
7
|
+
};
|
|
8
|
+
export const isPublicOutputPublished = async (publicDir) => {
|
|
9
|
+
const publicIndexPath = path.join(publicDir, "index.html");
|
|
10
|
+
try {
|
|
11
|
+
const indexStats = await fs.stat(publicIndexPath);
|
|
12
|
+
return indexStats.isFile() || indexStats.isSymbolicLink();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const resolveRootIndexFile = async (rootDir) => {
|
|
19
|
+
const rootIndexPath = path.join(rootDir, "index.html");
|
|
20
|
+
try {
|
|
21
|
+
const rootIndexStats = await fs.stat(rootIndexPath);
|
|
22
|
+
if (rootIndexStats.isFile()) {
|
|
23
|
+
return { type: "file", filePath: rootIndexPath };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// fall through to not found
|
|
28
|
+
}
|
|
29
|
+
return { type: "not-found" };
|
|
30
|
+
};
|
|
31
|
+
export const resolveRequestFile = async (rootDir, requestPath, mode) => {
|
|
32
|
+
const normalizedPath = requestPath === "/" ? "index.html" : requestPath.replace(/^\/+/, "");
|
|
33
|
+
const filePath = path.join(rootDir, normalizedPath);
|
|
34
|
+
if (!isInsideDirectory(rootDir, filePath)) {
|
|
35
|
+
return { type: "forbidden" };
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const fileStats = await fs.stat(filePath);
|
|
39
|
+
if (fileStats.isDirectory()) {
|
|
40
|
+
const directoryIndexPath = path.join(filePath, "index.html");
|
|
41
|
+
if (!isInsideDirectory(rootDir, directoryIndexPath)) {
|
|
42
|
+
return { type: "forbidden" };
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const directoryIndexStats = await fs.stat(directoryIndexPath);
|
|
46
|
+
if (directoryIndexStats.isFile()) {
|
|
47
|
+
return { type: "file", filePath: directoryIndexPath };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// fall through to not found/fallback response
|
|
52
|
+
}
|
|
53
|
+
return mode === "spa-fallback" ? resolveRootIndexFile(rootDir) : { type: "not-found" };
|
|
54
|
+
}
|
|
55
|
+
if (fileStats.isFile()) {
|
|
56
|
+
return { type: "file", filePath };
|
|
57
|
+
}
|
|
58
|
+
return { type: "not-found" };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
if (mode === "spa-fallback" && !path.extname(normalizedPath)) {
|
|
62
|
+
return resolveRootIndexFile(rootDir);
|
|
63
|
+
}
|
|
64
|
+
return { type: "not-found" };
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
export const sendFileResponse = async (response, filePath) => {
|
|
68
|
+
const fileBuffer = await fs.readFile(filePath);
|
|
69
|
+
const extension = path.extname(filePath);
|
|
70
|
+
const contentType = MIME_TYPES[extension] ?? "application/octet-stream";
|
|
71
|
+
response.writeHead(200, { "content-type": contentType });
|
|
72
|
+
response.end(fileBuffer);
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"files.js","sourceRoot":"","sources":["../../../src/dev/static/files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/dev/static/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isInsideDirectory: (basePath: string, targetPath: string) => boolean;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
export const isInsideDirectory = (basePath, targetPath) => {
|
|
3
|
+
const relativePath = path.relative(basePath, targetPath);
|
|
4
|
+
return relativePath !== "" && !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
|
|
5
|
+
};
|
|
6
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/dev/static/paths.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,QAAgB,EAAE,UAAkB,EAAW,EAAE;IACjF,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IACzD,OAAO,YAAY,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;AACjG,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isPublicOutputPublished: (publicDir: string) => Promise<boolean>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
export const isPublicOutputPublished = async (publicDir) => {
|
|
4
|
+
const publicIndexPath = path.join(publicDir, "index.html");
|
|
5
|
+
try {
|
|
6
|
+
const indexStats = await fs.stat(publicIndexPath);
|
|
7
|
+
return indexStats.isFile() || indexStats.isSymbolicLink();
|
|
8
|
+
}
|
|
9
|
+
catch {
|
|
10
|
+
return false;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/dev/static/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,MAAM,CAAC,MAAM,uBAAuB,GAAG,KAAK,EAAE,SAAiB,EAAoB,EAAE;IACnF,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAC3D,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAClD,OAAO,UAAU,CAAC,MAAM,EAAE,IAAI,UAAU,CAAC,cAAc,EAAE,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { isInsideDirectory } from "./paths.js";
|
|
4
|
+
const resolveRootIndexFile = async (rootDir) => {
|
|
5
|
+
const rootIndexPath = path.join(rootDir, "index.html");
|
|
6
|
+
try {
|
|
7
|
+
const rootIndexStats = await fs.stat(rootIndexPath);
|
|
8
|
+
if (rootIndexStats.isFile()) {
|
|
9
|
+
return { type: "file", filePath: rootIndexPath };
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
catch {
|
|
13
|
+
// fall through to not found
|
|
14
|
+
}
|
|
15
|
+
return { type: "not-found" };
|
|
16
|
+
};
|
|
17
|
+
export const resolveRequestFile = async (rootDir, requestPath, mode) => {
|
|
18
|
+
const normalizedPath = requestPath === "/" ? "index.html" : requestPath.replace(/^\/+/, "");
|
|
19
|
+
const filePath = path.join(rootDir, normalizedPath);
|
|
20
|
+
if (!isInsideDirectory(rootDir, filePath)) {
|
|
21
|
+
return { type: "forbidden" };
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const fileStats = await fs.stat(filePath);
|
|
25
|
+
if (fileStats.isDirectory()) {
|
|
26
|
+
const directoryIndexPath = path.join(filePath, "index.html");
|
|
27
|
+
if (!isInsideDirectory(rootDir, directoryIndexPath)) {
|
|
28
|
+
return { type: "forbidden" };
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
const directoryIndexStats = await fs.stat(directoryIndexPath);
|
|
32
|
+
if (directoryIndexStats.isFile()) {
|
|
33
|
+
return { type: "file", filePath: directoryIndexPath };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// fall through to not found/fallback response
|
|
38
|
+
}
|
|
39
|
+
return mode === "spa-fallback" ? resolveRootIndexFile(rootDir) : { type: "not-found" };
|
|
40
|
+
}
|
|
41
|
+
if (fileStats.isFile()) {
|
|
42
|
+
return { type: "file", filePath };
|
|
43
|
+
}
|
|
44
|
+
return { type: "not-found" };
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
if (mode === "spa-fallback" && !path.extname(normalizedPath)) {
|
|
48
|
+
return resolveRootIndexFile(rootDir);
|
|
49
|
+
}
|
|
50
|
+
return { type: "not-found" };
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../../src/dev/static/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE/C,MAAM,oBAAoB,GAAG,KAAK,EAAE,OAAe,EAAiC,EAAE;IACpF,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IACvD,IAAI,CAAC;QACH,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACpD,IAAI,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;YAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,4BAA4B;IAC9B,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;AAC/B,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EACrC,OAAe,EACf,WAAmB,EACnB,IAAwB,EACO,EAAE;IACjC,MAAM,cAAc,GAAG,WAAW,KAAK,GAAG,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5F,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAEpD,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;QAC1C,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC;IAED,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC1C,IAAI,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC;YAC5B,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;YAC7D,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,CAAC,EAAE,CAAC;gBACpD,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;YAC/B,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,mBAAmB,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;gBAC9D,IAAI,mBAAmB,CAAC,MAAM,EAAE,EAAE,CAAC;oBACjC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;gBACxD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,8CAA8C;YAChD,CAAC;YAED,OAAO,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;QACzF,CAAC;QAED,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;YACvB,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACpC,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,IAAI,KAAK,cAAc,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;YAC7D,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IAC/B,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { createReadStream, promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { pipeline } from "node:stream/promises";
|
|
4
|
+
import { MIME_TYPES } from "../constants.js";
|
|
5
|
+
export const sendFileResponse = async (response, filePath) => {
|
|
6
|
+
const fileStats = await fs.stat(filePath);
|
|
7
|
+
const extension = path.extname(filePath);
|
|
8
|
+
const contentType = MIME_TYPES[extension] ?? "application/octet-stream";
|
|
9
|
+
response.writeHead(200, {
|
|
10
|
+
"content-type": contentType,
|
|
11
|
+
"content-length": String(fileStats.size)
|
|
12
|
+
});
|
|
13
|
+
try {
|
|
14
|
+
await pipeline(createReadStream(filePath), response);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
const errorCode = typeof error === "object" && error !== null && "code" in error
|
|
18
|
+
? String(error.code)
|
|
19
|
+
: null;
|
|
20
|
+
if (errorCode === "ERR_STREAM_PREMATURE_CLOSE" || errorCode === "ECONNRESET") {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
throw error;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=sender.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sender.js","sourceRoot":"","sources":["../../../src/dev/static/sender.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,QAAwB,EAAE,QAAgB,EAAiB,EAAE;IAClG,MAAM,SAAS,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,IAAI,0BAA0B,CAAC;IAExE,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE;QACtB,cAAc,EAAE,WAAW;QAC3B,gBAAgB,EAAE,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC;KACzC,CAAC,CAAC;IAEH,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,gBAAgB,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,SAAS,GACb,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,KAAK;YAC5D,CAAC,CAAC,MAAM,CAAE,KAA4B,CAAC,IAAI,CAAC;YAC5C,CAAC,CAAC,IAAI,CAAC;QAEX,IAAI,SAAS,KAAK,4BAA4B,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;YAC7E,OAAO;QACT,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ServerResponse } from "node:http";
|
|
2
|
+
import type { ResolveRequestMode, ResolveRequestResult } from "./types.js";
|
|
3
|
+
export declare const isInsideDirectory: (basePath: string, targetPath: string) => boolean;
|
|
4
|
+
export declare const isPublicOutputPublished: (publicDir: string) => Promise<boolean>;
|
|
5
|
+
export declare const resolveRequestFile: (rootDir: string, requestPath: string, mode: ResolveRequestMode) => Promise<ResolveRequestResult>;
|
|
6
|
+
export declare const sendFileResponse: (response: ServerResponse, filePath: string) => Promise<void>;
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { promises as fs } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { MIME_TYPES } from "./constants.js";
|
|
4
|
+
export const isInsideDirectory = (basePath, targetPath) => {
|
|
5
|
+
const relativePath = path.relative(basePath, targetPath);
|
|
6
|
+
return relativePath !== "" && !relativePath.startsWith("..") && !path.isAbsolute(relativePath);
|
|
7
|
+
};
|
|
8
|
+
export const isPublicOutputPublished = async (publicDir) => {
|
|
9
|
+
const publicIndexPath = path.join(publicDir, "index.html");
|
|
10
|
+
try {
|
|
11
|
+
const indexStats = await fs.stat(publicIndexPath);
|
|
12
|
+
return indexStats.isFile() || indexStats.isSymbolicLink();
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
const resolveRootIndexFile = async (rootDir) => {
|
|
19
|
+
const rootIndexPath = path.join(rootDir, "index.html");
|
|
20
|
+
try {
|
|
21
|
+
const rootIndexStats = await fs.stat(rootIndexPath);
|
|
22
|
+
if (rootIndexStats.isFile()) {
|
|
23
|
+
return { type: "file", filePath: rootIndexPath };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// fall through to not found
|
|
28
|
+
}
|
|
29
|
+
return { type: "not-found" };
|
|
30
|
+
};
|
|
31
|
+
export const resolveRequestFile = async (rootDir, requestPath, mode) => {
|
|
32
|
+
const normalizedPath = requestPath === "/" ? "index.html" : requestPath.replace(/^\/+/, "");
|
|
33
|
+
const filePath = path.join(rootDir, normalizedPath);
|
|
34
|
+
if (!isInsideDirectory(rootDir, filePath)) {
|
|
35
|
+
return { type: "forbidden" };
|
|
36
|
+
}
|
|
37
|
+
try {
|
|
38
|
+
const fileStats = await fs.stat(filePath);
|
|
39
|
+
if (fileStats.isDirectory()) {
|
|
40
|
+
const directoryIndexPath = path.join(filePath, "index.html");
|
|
41
|
+
if (!isInsideDirectory(rootDir, directoryIndexPath)) {
|
|
42
|
+
return { type: "forbidden" };
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const directoryIndexStats = await fs.stat(directoryIndexPath);
|
|
46
|
+
if (directoryIndexStats.isFile()) {
|
|
47
|
+
return { type: "file", filePath: directoryIndexPath };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// fall through to not found/fallback response
|
|
52
|
+
}
|
|
53
|
+
return mode === "spa-fallback" ? resolveRootIndexFile(rootDir) : { type: "not-found" };
|
|
54
|
+
}
|
|
55
|
+
if (fileStats.isFile()) {
|
|
56
|
+
return { type: "file", filePath };
|
|
57
|
+
}
|
|
58
|
+
return { type: "not-found" };
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
if (mode === "spa-fallback" && !path.extname(normalizedPath)) {
|
|
62
|
+
return resolveRootIndexFile(rootDir);
|
|
63
|
+
}
|
|
64
|
+
return { type: "not-found" };
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
export const sendFileResponse = async (response, filePath) => {
|
|
68
|
+
const fileBuffer = await fs.readFile(filePath);
|
|
69
|
+
const extension = path.extname(filePath);
|
|
70
|
+
const contentType = MIME_TYPES[extension] ?? "application/octet-stream";
|
|
71
|
+
response.writeHead(200, { "content-type": contentType });
|
|
72
|
+
response.end(fileBuffer);
|
|
73
|
+
};
|
|
74
|
+
//# sourceMappingURL=static-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"static-files.js","sourceRoot":"","sources":["../../src/dev/static-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dev/types.ts"],"names":[],"mappings":""}
|