@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.
Files changed (124) hide show
  1. package/README.md +26 -10
  2. package/dist/auth/cookies.d.ts +11 -0
  3. package/dist/auth/cookies.js +38 -0
  4. package/dist/auth/cookies.js.map +1 -0
  5. package/dist/auth/hash.d.ts +2 -0
  6. package/dist/auth/hash.js +36 -0
  7. package/dist/auth/hash.js.map +1 -0
  8. package/dist/auth/oauth.d.ts +5 -0
  9. package/dist/auth/oauth.js +215 -0
  10. package/dist/auth/oauth.js.map +1 -0
  11. package/dist/auth/runtime.d.ts +28 -0
  12. package/dist/auth/runtime.js +539 -0
  13. package/dist/auth/runtime.js.map +1 -0
  14. package/dist/auth/store.d.ts +43 -0
  15. package/dist/auth/store.js +68 -0
  16. package/dist/auth/store.js.map +1 -0
  17. package/dist/auth/types.d.ts +40 -0
  18. package/dist/auth/types.js +2 -0
  19. package/dist/auth/types.js.map +1 -0
  20. package/dist/auth/validation.d.ts +21 -0
  21. package/dist/auth/validation.js +97 -0
  22. package/dist/auth/validation.js.map +1 -0
  23. package/dist/dev/admin/assets.d.ts +2 -0
  24. package/dist/dev/admin/assets.js +30 -0
  25. package/dist/dev/admin/assets.js.map +1 -0
  26. package/dist/dev/admin/i18n.d.ts +2 -0
  27. package/dist/dev/admin/i18n.js +63 -0
  28. package/dist/dev/admin/i18n.js.map +1 -0
  29. package/dist/dev/admin/index.d.ts +3 -0
  30. package/dist/dev/admin/index.js +4 -0
  31. package/dist/dev/admin/index.js.map +1 -0
  32. package/dist/dev/admin/request.d.ts +14 -0
  33. package/dist/dev/admin/request.js +77 -0
  34. package/dist/dev/admin/request.js.map +1 -0
  35. package/dist/dev/admin/routing.d.ts +5 -0
  36. package/dist/dev/admin/routing.js +31 -0
  37. package/dist/dev/admin/routing.js.map +1 -0
  38. package/dist/dev/admin-assets.d.ts +2 -0
  39. package/dist/dev/admin-assets.js +30 -0
  40. package/dist/dev/admin-assets.js.map +1 -0
  41. package/dist/dev/admin.d.ts +2 -0
  42. package/dist/dev/admin.js +30 -0
  43. package/dist/dev/admin.js.map +1 -0
  44. package/dist/dev/constants.d.ts +12 -0
  45. package/dist/dev/constants.js +23 -0
  46. package/dist/dev/constants.js.map +1 -0
  47. package/dist/dev/health/index.d.ts +2 -0
  48. package/dist/dev/health/index.js +3 -0
  49. package/dist/dev/health/index.js.map +1 -0
  50. package/dist/dev/health/request.d.ts +14 -0
  51. package/dist/dev/health/request.js +22 -0
  52. package/dist/dev/health/request.js.map +1 -0
  53. package/dist/dev/health/state.d.ts +9 -0
  54. package/dist/dev/health/state.js +52 -0
  55. package/dist/dev/health/state.js.map +1 -0
  56. package/dist/dev/health.d.ts +9 -0
  57. package/dist/dev/health.js +52 -0
  58. package/dist/dev/health.js.map +1 -0
  59. package/dist/dev/http/errors.d.ts +3 -0
  60. package/dist/dev/http/errors.js +10 -0
  61. package/dist/dev/http/errors.js.map +1 -0
  62. package/dist/dev/http/routing.d.ts +3 -0
  63. package/dist/dev/http/routing.js +26 -0
  64. package/dist/dev/http/routing.js.map +1 -0
  65. package/dist/dev/i18n.d.ts +2 -0
  66. package/dist/dev/i18n.js +63 -0
  67. package/dist/dev/i18n.js.map +1 -0
  68. package/dist/dev/lifecycle.d.ts +2 -0
  69. package/dist/dev/lifecycle.js +10 -0
  70. package/dist/dev/lifecycle.js.map +1 -0
  71. package/dist/dev/public/index.d.ts +1 -0
  72. package/dist/dev/public/index.js +2 -0
  73. package/dist/dev/public/index.js.map +1 -0
  74. package/dist/dev/public/request.d.ts +9 -0
  75. package/dist/dev/public/request.js +29 -0
  76. package/dist/dev/public/request.js.map +1 -0
  77. package/dist/dev/public/responses.d.ts +3 -0
  78. package/dist/dev/public/responses.js +25 -0
  79. package/dist/dev/public/responses.js.map +1 -0
  80. package/dist/dev/public/routing.d.ts +1 -0
  81. package/dist/dev/public/routing.js +5 -0
  82. package/dist/dev/public/routing.js.map +1 -0
  83. package/dist/dev/responses.d.ts +2 -0
  84. package/dist/dev/responses.js +3 -0
  85. package/dist/dev/responses.js.map +1 -0
  86. package/dist/dev/routing.d.ts +3 -0
  87. package/dist/dev/routing.js +4 -0
  88. package/dist/dev/routing.js.map +1 -0
  89. package/dist/dev/setup/index.d.ts +2 -0
  90. package/dist/dev/setup/index.js +2 -0
  91. package/dist/dev/setup/index.js.map +1 -0
  92. package/dist/dev/setup/request.d.ts +5 -0
  93. package/dist/dev/setup/request.js +20 -0
  94. package/dist/dev/setup/request.js.map +1 -0
  95. package/dist/dev/setup/types.d.ts +5 -0
  96. package/dist/dev/setup/types.js +2 -0
  97. package/dist/dev/setup/types.js.map +1 -0
  98. package/dist/dev/static/files.d.ts +6 -0
  99. package/dist/dev/static/files.js +74 -0
  100. package/dist/dev/static/files.js.map +1 -0
  101. package/dist/dev/static/index.d.ts +4 -0
  102. package/dist/dev/static/index.js +5 -0
  103. package/dist/dev/static/index.js.map +1 -0
  104. package/dist/dev/static/paths.d.ts +1 -0
  105. package/dist/dev/static/paths.js +6 -0
  106. package/dist/dev/static/paths.js.map +1 -0
  107. package/dist/dev/static/publish.d.ts +1 -0
  108. package/dist/dev/static/publish.js +13 -0
  109. package/dist/dev/static/publish.js.map +1 -0
  110. package/dist/dev/static/resolver.d.ts +2 -0
  111. package/dist/dev/static/resolver.js +53 -0
  112. package/dist/dev/static/resolver.js.map +1 -0
  113. package/dist/dev/static/sender.d.ts +2 -0
  114. package/dist/dev/static/sender.js +26 -0
  115. package/dist/dev/static/sender.js.map +1 -0
  116. package/dist/dev/static-files.d.ts +6 -0
  117. package/dist/dev/static-files.js +74 -0
  118. package/dist/dev/static-files.js.map +1 -0
  119. package/dist/dev/types.d.ts +10 -0
  120. package/dist/dev/types.js +2 -0
  121. package/dist/dev/types.js.map +1 -0
  122. package/dist/server.js +74 -191
  123. package/dist/server.js.map +1 -1
  124. 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,4 @@
1
+ export { isInsideDirectory } from "./paths.js";
2
+ export { isPublicOutputPublished } from "./publish.js";
3
+ export { resolveRequestFile } from "./resolver.js";
4
+ export { sendFileResponse } from "./sender.js";
@@ -0,0 +1,5 @@
1
+ export { isInsideDirectory } from "./paths.js";
2
+ export { isPublicOutputPublished } from "./publish.js";
3
+ export { resolveRequestFile } from "./resolver.js";
4
+ export { sendFileResponse } from "./sender.js";
5
+ //# sourceMappingURL=index.js.map
@@ -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,2 @@
1
+ import type { ResolveRequestMode, ResolveRequestResult } from "../types.js";
2
+ export declare const resolveRequestFile: (rootDir: string, requestPath: string, mode: ResolveRequestMode) => Promise<ResolveRequestResult>;
@@ -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,2 @@
1
+ import type { ServerResponse } from "node:http";
2
+ export declare const sendFileResponse: (response: ServerResponse, filePath: string) => Promise<void>;
@@ -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,10 @@
1
+ export type SiteTarget = "public" | "admin";
2
+ export type ResolveRequestMode = "strict" | "spa-fallback";
3
+ export type ResolveRequestResult = {
4
+ type: "file";
5
+ filePath: string;
6
+ } | {
7
+ type: "not-found";
8
+ } | {
9
+ type: "forbidden";
10
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/dev/types.ts"],"names":[],"mappings":""}