heliumts 0.7.4 → 0.7.6
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/dist/bin/helium.js +0 -0
- package/dist/client/staleRecovery.d.ts.map +1 -1
- package/dist/client/staleRecovery.js +31 -2
- package/dist/client/staleRecovery.js.map +1 -1
- package/dist/vite/virtualServerModule.d.ts.map +1 -1
- package/dist/vite/virtualServerModule.js +14 -27
- package/dist/vite/virtualServerModule.js.map +1 -1
- package/package.json +1 -1
- package/dist/server/ipExtractor.d.ts +0 -48
- package/dist/server/ipExtractor.d.ts.map +0 -1
- package/dist/server/ipExtractor.js +0 -96
- package/dist/server/ipExtractor.js.map +0 -1
- package/dist/server/requestRouting.d.ts +0 -4
- package/dist/server/requestRouting.d.ts.map +0 -1
- package/dist/server/requestRouting.js +0 -67
- package/dist/server/requestRouting.js.map +0 -1
- package/dist/utils/deepEqual.d.ts +0 -1
- package/dist/utils/deepEqual.d.ts.map +0 -1
- package/dist/utils/deepEqual.js +0 -2
- package/dist/utils/deepEqual.js.map +0 -1
- package/dist/utils/formatError.d.ts +0 -2
- package/dist/utils/formatError.d.ts.map +0 -1
- package/dist/utils/formatError.js +0 -18
- package/dist/utils/formatError.js.map +0 -1
package/dist/bin/helium.js
CHANGED
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staleRecovery.d.ts","sourceRoot":"","sources":["../../src/client/staleRecovery.ts"],"names":[],"mappings":"AAeA,KAAK,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;AAEvE,KAAK,iCAAiC,GAAG;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;
|
|
1
|
+
{"version":3,"file":"staleRecovery.d.ts","sourceRoot":"","sources":["../../src/client/staleRecovery.ts"],"names":[],"mappings":"AAeA,KAAK,WAAW,GAAG,IAAI,CAAC,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC,CAAC;AAEvE,KAAK,iCAAiC,GAAG;IACrC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1B,OAAO,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC;AA2EF;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAWzD;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,iCAAsC,GAAG,IAAI,CA+HhG"}
|
|
@@ -10,6 +10,17 @@ const CHUNK_ERROR_PATTERNS = [
|
|
|
10
10
|
/Importing a module script failed/i,
|
|
11
11
|
/dynamically imported module/i,
|
|
12
12
|
];
|
|
13
|
+
function resolveStorage(windowObject, override) {
|
|
14
|
+
if (override !== undefined) {
|
|
15
|
+
return override;
|
|
16
|
+
}
|
|
17
|
+
try {
|
|
18
|
+
return windowObject.sessionStorage;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
13
24
|
function readStoredNumber(storage, key) {
|
|
14
25
|
if (!storage) {
|
|
15
26
|
return null;
|
|
@@ -90,12 +101,14 @@ export function installStaleClientRecovery(options = {}) {
|
|
|
90
101
|
}
|
|
91
102
|
trackedWindow[INSTALL_FLAG] = true;
|
|
92
103
|
const now = options.now ?? (() => Date.now());
|
|
93
|
-
const storage = options.storage
|
|
104
|
+
const storage = resolveStorage(windowObject, options.storage);
|
|
94
105
|
const staleThresholdMs = options.staleThresholdMs ?? STALE_RESUME_THRESHOLD_MS;
|
|
95
106
|
const reloadCooldownMs = options.reloadCooldownMs ?? RELOAD_COOLDOWN_MS;
|
|
96
107
|
const reload = options.reload ?? (() => windowObject.location.reload());
|
|
97
108
|
let isReloading = false;
|
|
109
|
+
let hasPendingReload = false;
|
|
98
110
|
let hiddenAt = readStoredNumber(storage, HIDDEN_AT_STORAGE_KEY);
|
|
111
|
+
const isVisible = () => !documentObject.hidden;
|
|
99
112
|
const markHidden = () => {
|
|
100
113
|
hiddenAt = now();
|
|
101
114
|
writeStoredNumber(storage, HIDDEN_AT_STORAGE_KEY, hiddenAt);
|
|
@@ -104,7 +117,11 @@ export function installStaleClientRecovery(options = {}) {
|
|
|
104
117
|
hiddenAt = null;
|
|
105
118
|
writeStoredNumber(storage, HIDDEN_AT_STORAGE_KEY, null);
|
|
106
119
|
};
|
|
107
|
-
const
|
|
120
|
+
const executeReload = () => {
|
|
121
|
+
if (!isVisible()) {
|
|
122
|
+
hasPendingReload = true;
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
108
125
|
if (isReloading) {
|
|
109
126
|
return;
|
|
110
127
|
}
|
|
@@ -114,9 +131,19 @@ export function installStaleClientRecovery(options = {}) {
|
|
|
114
131
|
return;
|
|
115
132
|
}
|
|
116
133
|
isReloading = true;
|
|
134
|
+
hasPendingReload = false;
|
|
117
135
|
writeStoredNumber(storage, LAST_RELOAD_STORAGE_KEY, current);
|
|
118
136
|
reload();
|
|
119
137
|
};
|
|
138
|
+
const flushPendingReload = () => {
|
|
139
|
+
if (!hasPendingReload) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
executeReload();
|
|
143
|
+
};
|
|
144
|
+
const attemptReload = () => {
|
|
145
|
+
executeReload();
|
|
146
|
+
};
|
|
120
147
|
const maybeRecoverFromStaleResume = () => {
|
|
121
148
|
const hiddenTimestamp = hiddenAt ?? readStoredNumber(storage, HIDDEN_AT_STORAGE_KEY);
|
|
122
149
|
if (hiddenTimestamp === null) {
|
|
@@ -133,6 +160,7 @@ export function installStaleClientRecovery(options = {}) {
|
|
|
133
160
|
markHidden();
|
|
134
161
|
return;
|
|
135
162
|
}
|
|
163
|
+
flushPendingReload();
|
|
136
164
|
maybeRecoverFromStaleResume();
|
|
137
165
|
}, { passive: true });
|
|
138
166
|
windowObject.addEventListener("pagehide", () => {
|
|
@@ -140,6 +168,7 @@ export function installStaleClientRecovery(options = {}) {
|
|
|
140
168
|
}, { passive: true });
|
|
141
169
|
windowObject.addEventListener("pageshow", (event) => {
|
|
142
170
|
if (event.persisted) {
|
|
171
|
+
flushPendingReload();
|
|
143
172
|
maybeRecoverFromStaleResume();
|
|
144
173
|
}
|
|
145
174
|
}, { passive: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"staleRecovery.js","sourceRoot":"","sources":["../../src/client/staleRecovery.ts"],"names":[],"mappings":"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","sourcesContent":["const STALE_RESUME_THRESHOLD_MS = 30 * 60 * 1000;\nconst RELOAD_COOLDOWN_MS = 30 * 1000;\n\nconst INSTALL_FLAG = \"__helium_stale_client_recovery_installed__\";\nconst HIDDEN_AT_STORAGE_KEY = \"__helium_stale_client_hidden_at__\";\nconst LAST_RELOAD_STORAGE_KEY = \"__helium_stale_client_last_reload_at__\";\n\nconst CHUNK_ERROR_PATTERNS: RegExp[] = [\n /ChunkLoadError/i,\n /Loading chunk\\s+\\d+\\s+failed/i,\n /Failed to fetch dynamically imported module/i,\n /Importing a module script failed/i,\n /dynamically imported module/i,\n];\n\ntype StorageLike = Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\n\ntype InstallStaleClientRecoveryOptions = {\n windowObject?: Window;\n documentObject?: Document;\n storage?: StorageLike | null;\n now?: () => number;\n reload?: () => void;\n staleThresholdMs?: number;\n reloadCooldownMs?: number;\n disableDedupe?: boolean;\n};\n\ntype WindowWithInstallFlag = Window & {\n [INSTALL_FLAG]?: boolean;\n};\n\nfunction readStoredNumber(storage: StorageLike | null, key: string): number | null {\n if (!storage) {\n return null;\n }\n\n try {\n const raw = storage.getItem(key);\n if (!raw) {\n return null;\n }\n const parsed = Number(raw);\n return Number.isFinite(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n\nfunction writeStoredNumber(storage: StorageLike | null, key: string, value: number | null): void {\n if (!storage) {\n return;\n }\n\n try {\n if (value === null) {\n storage.removeItem(key);\n return;\n }\n storage.setItem(key, String(value));\n } catch {\n // Ignore storage write failures (private mode, quota exceeded, etc.)\n }\n}\n\nfunction extractErrorText(reason: unknown): string {\n if (typeof reason === \"string\") {\n return reason;\n }\n\n if (reason instanceof Error) {\n return `${reason.name}: ${reason.message}`;\n }\n\n if (typeof reason === \"object\" && reason !== null) {\n const maybeMessage = Reflect.get(reason, \"message\");\n if (typeof maybeMessage === \"string\") {\n return maybeMessage;\n }\n\n const maybeName = Reflect.get(reason, \"name\");\n if (typeof maybeName === \"string\") {\n return maybeName;\n }\n }\n\n return \"\";\n}\n\n/**\n * @internal Exported for testing\n */\nexport function isChunkLoadError(reason: unknown): boolean {\n if (reason instanceof Error && reason.name === \"ChunkLoadError\") {\n return true;\n }\n\n const text = extractErrorText(reason);\n if (!text) {\n return false;\n }\n\n return CHUNK_ERROR_PATTERNS.some((pattern) => pattern.test(text));\n}\n\n/**\n * Installs default stale-client recovery for mobile suspend/resume and stale chunks.\n *\n * @internal Exported for testing\n */\nexport function installStaleClientRecovery(options: InstallStaleClientRecoveryOptions = {}): void {\n const windowObject = options.windowObject ?? (typeof window !== \"undefined\" ? window : undefined);\n const documentObject = options.documentObject ?? (typeof document !== \"undefined\" ? document : undefined);\n\n if (!windowObject || !documentObject) {\n return;\n }\n\n const trackedWindow = windowObject as WindowWithInstallFlag;\n if (!options.disableDedupe && trackedWindow[INSTALL_FLAG]) {\n return;\n }\n trackedWindow[INSTALL_FLAG] = true;\n\n const now = options.now ?? (() => Date.now());\n const storage = options.storage ?? windowObject.sessionStorage;\n const staleThresholdMs = options.staleThresholdMs ?? STALE_RESUME_THRESHOLD_MS;\n const reloadCooldownMs = options.reloadCooldownMs ?? RELOAD_COOLDOWN_MS;\n const reload = options.reload ?? (() => windowObject.location.reload());\n\n let isReloading = false;\n let hiddenAt = readStoredNumber(storage, HIDDEN_AT_STORAGE_KEY);\n\n const markHidden = () => {\n hiddenAt = now();\n writeStoredNumber(storage, HIDDEN_AT_STORAGE_KEY, hiddenAt);\n };\n\n const clearHidden = () => {\n hiddenAt = null;\n writeStoredNumber(storage, HIDDEN_AT_STORAGE_KEY, null);\n };\n\n const attemptReload = () => {\n if (isReloading) {\n return;\n }\n\n const current = now();\n const lastReloadAt = readStoredNumber(storage, LAST_RELOAD_STORAGE_KEY) ?? 0;\n if (current - lastReloadAt < reloadCooldownMs) {\n return;\n }\n\n isReloading = true;\n writeStoredNumber(storage, LAST_RELOAD_STORAGE_KEY, current);\n reload();\n };\n\n const maybeRecoverFromStaleResume = () => {\n const hiddenTimestamp = hiddenAt ?? readStoredNumber(storage, HIDDEN_AT_STORAGE_KEY);\n if (hiddenTimestamp === null) {\n return;\n }\n\n const hiddenDuration = now() - hiddenTimestamp;\n clearHidden();\n if (hiddenDuration >= staleThresholdMs) {\n attemptReload();\n }\n };\n\n documentObject.addEventListener(\n \"visibilitychange\",\n () => {\n if (documentObject.hidden) {\n markHidden();\n return;\n }\n maybeRecoverFromStaleResume();\n },\n { passive: true }\n );\n\n windowObject.addEventListener(\n \"pagehide\",\n () => {\n markHidden();\n },\n { passive: true }\n );\n\n windowObject.addEventListener(\n \"pageshow\",\n (event) => {\n if ((event as PageTransitionEvent).persisted) {\n maybeRecoverFromStaleResume();\n }\n },\n { passive: true }\n );\n\n windowObject.addEventListener(\"error\", (event) => {\n const errorEvent = event as ErrorEvent;\n if (isChunkLoadError(errorEvent.error ?? errorEvent.message)) {\n attemptReload();\n }\n });\n\n windowObject.addEventListener(\"unhandledrejection\", (event) => {\n const rejectionEvent = event as PromiseRejectionEvent;\n if (isChunkLoadError(rejectionEvent.reason)) {\n attemptReload();\n }\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"staleRecovery.js","sourceRoot":"","sources":["../../src/client/staleRecovery.ts"],"names":[],"mappings":"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","sourcesContent":["const STALE_RESUME_THRESHOLD_MS = 30 * 60 * 1000;\nconst RELOAD_COOLDOWN_MS = 30 * 1000;\n\nconst INSTALL_FLAG = \"__helium_stale_client_recovery_installed__\";\nconst HIDDEN_AT_STORAGE_KEY = \"__helium_stale_client_hidden_at__\";\nconst LAST_RELOAD_STORAGE_KEY = \"__helium_stale_client_last_reload_at__\";\n\nconst CHUNK_ERROR_PATTERNS: RegExp[] = [\n /ChunkLoadError/i,\n /Loading chunk\\s+\\d+\\s+failed/i,\n /Failed to fetch dynamically imported module/i,\n /Importing a module script failed/i,\n /dynamically imported module/i,\n];\n\ntype StorageLike = Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\n\ntype InstallStaleClientRecoveryOptions = {\n windowObject?: Window;\n documentObject?: Document;\n storage?: StorageLike | null;\n now?: () => number;\n reload?: () => void;\n staleThresholdMs?: number;\n reloadCooldownMs?: number;\n disableDedupe?: boolean;\n};\n\ntype WindowWithInstallFlag = Window & {\n [INSTALL_FLAG]?: boolean;\n};\n\nfunction resolveStorage(windowObject: Window, override?: StorageLike | null): StorageLike | null {\n if (override !== undefined) {\n return override;\n }\n\n try {\n return windowObject.sessionStorage;\n } catch {\n return null;\n }\n}\n\nfunction readStoredNumber(storage: StorageLike | null, key: string): number | null {\n if (!storage) {\n return null;\n }\n\n try {\n const raw = storage.getItem(key);\n if (!raw) {\n return null;\n }\n const parsed = Number(raw);\n return Number.isFinite(parsed) ? parsed : null;\n } catch {\n return null;\n }\n}\n\nfunction writeStoredNumber(storage: StorageLike | null, key: string, value: number | null): void {\n if (!storage) {\n return;\n }\n\n try {\n if (value === null) {\n storage.removeItem(key);\n return;\n }\n storage.setItem(key, String(value));\n } catch {\n // Ignore storage write failures (private mode, quota exceeded, etc.)\n }\n}\n\nfunction extractErrorText(reason: unknown): string {\n if (typeof reason === \"string\") {\n return reason;\n }\n\n if (reason instanceof Error) {\n return `${reason.name}: ${reason.message}`;\n }\n\n if (typeof reason === \"object\" && reason !== null) {\n const maybeMessage = Reflect.get(reason, \"message\");\n if (typeof maybeMessage === \"string\") {\n return maybeMessage;\n }\n\n const maybeName = Reflect.get(reason, \"name\");\n if (typeof maybeName === \"string\") {\n return maybeName;\n }\n }\n\n return \"\";\n}\n\n/**\n * @internal Exported for testing\n */\nexport function isChunkLoadError(reason: unknown): boolean {\n if (reason instanceof Error && reason.name === \"ChunkLoadError\") {\n return true;\n }\n\n const text = extractErrorText(reason);\n if (!text) {\n return false;\n }\n\n return CHUNK_ERROR_PATTERNS.some((pattern) => pattern.test(text));\n}\n\n/**\n * Installs default stale-client recovery for mobile suspend/resume and stale chunks.\n *\n * @internal Exported for testing\n */\nexport function installStaleClientRecovery(options: InstallStaleClientRecoveryOptions = {}): void {\n const windowObject = options.windowObject ?? (typeof window !== \"undefined\" ? window : undefined);\n const documentObject = options.documentObject ?? (typeof document !== \"undefined\" ? document : undefined);\n\n if (!windowObject || !documentObject) {\n return;\n }\n\n const trackedWindow = windowObject as WindowWithInstallFlag;\n if (!options.disableDedupe && trackedWindow[INSTALL_FLAG]) {\n return;\n }\n trackedWindow[INSTALL_FLAG] = true;\n\n const now = options.now ?? (() => Date.now());\n const storage = resolveStorage(windowObject, options.storage);\n const staleThresholdMs = options.staleThresholdMs ?? STALE_RESUME_THRESHOLD_MS;\n const reloadCooldownMs = options.reloadCooldownMs ?? RELOAD_COOLDOWN_MS;\n const reload = options.reload ?? (() => windowObject.location.reload());\n\n let isReloading = false;\n let hasPendingReload = false;\n let hiddenAt = readStoredNumber(storage, HIDDEN_AT_STORAGE_KEY);\n\n const isVisible = () => !documentObject.hidden;\n\n const markHidden = () => {\n hiddenAt = now();\n writeStoredNumber(storage, HIDDEN_AT_STORAGE_KEY, hiddenAt);\n };\n\n const clearHidden = () => {\n hiddenAt = null;\n writeStoredNumber(storage, HIDDEN_AT_STORAGE_KEY, null);\n };\n\n const executeReload = () => {\n if (!isVisible()) {\n hasPendingReload = true;\n return;\n }\n\n if (isReloading) {\n return;\n }\n\n const current = now();\n const lastReloadAt = readStoredNumber(storage, LAST_RELOAD_STORAGE_KEY) ?? 0;\n if (current - lastReloadAt < reloadCooldownMs) {\n return;\n }\n\n isReloading = true;\n hasPendingReload = false;\n writeStoredNumber(storage, LAST_RELOAD_STORAGE_KEY, current);\n reload();\n };\n\n const flushPendingReload = () => {\n if (!hasPendingReload) {\n return;\n }\n executeReload();\n };\n\n const attemptReload = () => {\n executeReload();\n };\n\n const maybeRecoverFromStaleResume = () => {\n const hiddenTimestamp = hiddenAt ?? readStoredNumber(storage, HIDDEN_AT_STORAGE_KEY);\n if (hiddenTimestamp === null) {\n return;\n }\n\n const hiddenDuration = now() - hiddenTimestamp;\n clearHidden();\n if (hiddenDuration >= staleThresholdMs) {\n attemptReload();\n }\n };\n\n documentObject.addEventListener(\n \"visibilitychange\",\n () => {\n if (documentObject.hidden) {\n markHidden();\n return;\n }\n flushPendingReload();\n maybeRecoverFromStaleResume();\n },\n { passive: true }\n );\n\n windowObject.addEventListener(\n \"pagehide\",\n () => {\n markHidden();\n },\n { passive: true }\n );\n\n windowObject.addEventListener(\n \"pageshow\",\n (event) => {\n if ((event as PageTransitionEvent).persisted) {\n flushPendingReload();\n maybeRecoverFromStaleResume();\n }\n },\n { passive: true }\n );\n\n windowObject.addEventListener(\"error\", (event) => {\n const errorEvent = event as ErrorEvent;\n if (isChunkLoadError(errorEvent.error ?? errorEvent.message)) {\n attemptReload();\n }\n });\n\n windowObject.addEventListener(\"unhandledrejection\", (event) => {\n const rejectionEvent = event as PromiseRejectionEvent;\n if (isChunkLoadError(rejectionEvent.reason)) {\n attemptReload();\n }\n });\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualServerModule.d.ts","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAElH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,YAAY,EAAE,EACvB,YAAY,EAAE,iBAAiB,EAAE,EACjC,WAAW,GAAE,iBAAiB,EAAO,EACrC,iBAAiB,GAAE,MAAM,EAAO,EAChC,UAAU,CAAC,EAAE,gBAAgB,EAC7B,OAAO,GAAE,YAAY,EAAO,GAC7B,MAAM,CAyCR;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAIpE;
|
|
1
|
+
{"version":3,"file":"virtualServerModule.d.ts","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAElH,wBAAgB,sBAAsB,CAClC,OAAO,EAAE,YAAY,EAAE,EACvB,YAAY,EAAE,iBAAiB,EAAE,EACjC,WAAW,GAAE,iBAAiB,EAAO,EACrC,iBAAiB,GAAE,MAAM,EAAO,EAChC,UAAU,CAAC,EAAE,gBAAgB,EAC7B,OAAO,GAAE,YAAY,EAAO,GAC7B,MAAM,CAyCR;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAIpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAiErF;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAkB5C"}
|
|
@@ -41,44 +41,31 @@ export function generateClientModule(methods) {
|
|
|
41
41
|
const exports = methods.map((m) => `export const ${m.name} = { __id: '${m.name}' };`).join("\n");
|
|
42
42
|
return exports;
|
|
43
43
|
}
|
|
44
|
-
/**
|
|
45
|
-
* Generate a deterministic suffix from a string.
|
|
46
|
-
* Uses only file path and method name (NOT index) so that adding/removing
|
|
47
|
-
* other methods does not change existing aliases.
|
|
48
|
-
*/
|
|
49
|
-
function stableAlias(filePath, name) {
|
|
50
|
-
const input = `${filePath}:${name}`;
|
|
51
|
-
let hash = 0;
|
|
52
|
-
for (let i = 0; i < input.length; i++) {
|
|
53
|
-
const char = input.charCodeAt(i);
|
|
54
|
-
hash = (hash << 5) - hash + char;
|
|
55
|
-
hash = hash & hash; // Convert to 32bit integer
|
|
56
|
-
}
|
|
57
|
-
return `${name}_${Math.abs(hash).toString(36)}`;
|
|
58
|
-
}
|
|
59
44
|
export function generateTypeDefinitions(methods, root) {
|
|
60
45
|
// Sort methods by name for a stable output regardless of file-system walk order
|
|
61
46
|
const sorted = [...methods].sort((a, b) => a.name.localeCompare(b.name));
|
|
62
|
-
const
|
|
63
|
-
...m,
|
|
64
|
-
alias: stableAlias(m.filePath, m.name),
|
|
65
|
-
}));
|
|
66
|
-
const imports = methodsWithAlias
|
|
67
|
-
.map((m) => {
|
|
47
|
+
const methodsWithRelativePath = sorted.map((m) => {
|
|
68
48
|
let relPath = path.relative(path.join(root, "src"), m.filePath);
|
|
69
49
|
if (!relPath.startsWith(".")) {
|
|
70
50
|
relPath = "../" + relPath;
|
|
71
51
|
}
|
|
72
52
|
// Normalize to posix separators for import paths
|
|
73
53
|
relPath = relPath.replace(/\\/g, "/").replace(/\.ts$/, "");
|
|
74
|
-
return
|
|
54
|
+
return {
|
|
55
|
+
...m,
|
|
56
|
+
relPath,
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
const imports = methodsWithRelativePath
|
|
60
|
+
.map((m, index) => {
|
|
61
|
+
return `import type { ${m.name} as __helium_method_${index} } from '${m.relPath}';`;
|
|
75
62
|
})
|
|
76
63
|
.join("\n");
|
|
77
|
-
const methodExports =
|
|
78
|
-
.map((m) => {
|
|
64
|
+
const methodExports = methodsWithRelativePath
|
|
65
|
+
.map((m, index) => {
|
|
79
66
|
return ` export const ${m.name}: import('heliumts/client').MethodStub<
|
|
80
|
-
Parameters<typeof ${
|
|
81
|
-
Awaited<ReturnType<typeof ${
|
|
67
|
+
Parameters<typeof __helium_method_${index}['handler']>[0],
|
|
68
|
+
Awaited<ReturnType<typeof __helium_method_${index}['handler']>>
|
|
82
69
|
>;`;
|
|
83
70
|
})
|
|
84
71
|
.join("\n");
|
|
@@ -98,7 +85,7 @@ export function generateTypeDefinitions(methods, root) {
|
|
|
98
85
|
export {};
|
|
99
86
|
`;
|
|
100
87
|
}
|
|
101
|
-
const methodSignature =
|
|
88
|
+
const methodSignature = methodsWithRelativePath.map((m) => m.name).join(", ");
|
|
102
89
|
return `/* eslint-disable */
|
|
103
90
|
/**
|
|
104
91
|
* Auto generated file - DO NOT EDIT!
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"virtualServerModule.js","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"virtualServerModule.js","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"path\";\n\nimport { HTTPHandlerExport, MethodExport, MiddlewareExport, SEOMetadataExport, WorkerExport } from \"./scanner.js\";\n\nexport function generateServerManifest(\n methods: MethodExport[],\n httpHandlers: HTTPHandlerExport[],\n seoMetadata: SEOMetadataExport[] = [],\n pageRoutePatterns: string[] = [],\n middleware?: MiddlewareExport,\n workers: WorkerExport[] = []\n): string {\n const methodImports = methods.map((m, i) => `import { ${m.name} as method_${i} } from '${m.filePath}';`).join(\"\\n\");\n const httpImports = httpHandlers.map((h, i) => `import { ${h.name} as http_${i} } from '${h.filePath}';`).join(\"\\n\");\n const seoImports = seoMetadata.map((s, i) => `import { ${s.name} as seo_${i} } from '${s.filePath}';`).join(\"\\n\");\n const workerImports = workers.map((w, i) => `import { ${w.name} as worker_${i} } from '${w.filePath}';`).join(\"\\n\");\n const middlewareImport = middleware ? `import ${middleware.name === \"default\" ? \"middleware\" : `{ ${middleware.name} as middleware }`} from '${middleware.filePath}';` : \"\";\n\n const methodRegistrations = methods.map((m, i) => ` registry.register('${m.name}', method_${i});`).join(\"\\n\");\n\n const httpExports = httpHandlers.map((h, i) => ` { name: '${h.name}', handler: http_${i} },`).join(\"\\n\");\n const seoExports = seoMetadata.map((s, i) => ` { name: '${s.name}', handler: seo_${i} },`).join(\"\\n\");\n\n const workerExports = workers.map((w, i) => ` { name: '${w.name}', worker: worker_${i} },`).join(\"\\n\");\n\n return `\n${methodImports}\n${httpImports}\n${seoImports}\n${workerImports}\n${middlewareImport}\n\nexport function registerAll(registry) {\n${methodRegistrations}\n}\n\nexport const httpHandlers = [\n${httpExports}\n];\n\nexport const seoMetadataHandlers = [\n${seoExports}\n];\n\nexport const pageRoutePatterns = ${JSON.stringify(pageRoutePatterns)};\n\nexport const workers = [\n${workerExports}\n];\n\nexport const middlewareHandler = ${middleware ? \"middleware\" : \"null\"};\n`;\n}\n\nexport function generateClientModule(methods: MethodExport[]): string {\n const exports = methods.map((m) => `export const ${m.name} = { __id: '${m.name}' };`).join(\"\\n\");\n\n return exports;\n}\n\nexport function generateTypeDefinitions(methods: MethodExport[], root: string): string {\n // Sort methods by name for a stable output regardless of file-system walk order\n const sorted = [...methods].sort((a, b) => a.name.localeCompare(b.name));\n\n const methodsWithRelativePath = sorted.map((m) => {\n let relPath = path.relative(path.join(root, \"src\"), m.filePath);\n if (!relPath.startsWith(\".\")) {\n relPath = \"../\" + relPath;\n }\n // Normalize to posix separators for import paths\n relPath = relPath.replace(/\\\\/g, \"/\").replace(/\\.ts$/, \"\");\n return {\n ...m,\n relPath,\n };\n });\n\n const imports = methodsWithRelativePath\n .map((m, index) => {\n return `import type { ${m.name} as __helium_method_${index} } from '${m.relPath}';`;\n })\n .join(\"\\n\");\n\n const methodExports = methodsWithRelativePath\n .map((m, index) => {\n return ` export const ${m.name}: import('heliumts/client').MethodStub<\n Parameters<typeof __helium_method_${index}['handler']>[0],\n Awaited<ReturnType<typeof __helium_method_${index}['handler']>>\n >;`;\n })\n .join(\"\\n\");\n\n // If there are no methods, we don't need to generate any augmentation\n // This prevents shadowing the actual heliumts/server exports\n if (methods.length === 0) {\n return `/* eslint-disable */\n/**\n* Auto generated file - DO NOT EDIT!\n* # Helium Server Type Definitions\n* \n* This file is empty because no methods have been defined yet.\n* Once you create a method using defineMethod(), type stubs will be generated here.\n*\n* @helium-methods (none)\n**/\nexport {};\n`;\n }\n\n const methodSignature = methodsWithRelativePath.map((m) => m.name).join(\", \");\n\n return `/* eslint-disable */\n/**\n* Auto generated file - DO NOT EDIT!\n* # Helium Server Type Definitions\n*\n* @helium-methods ${methodSignature}\n**/\n${imports}\n\ndeclare module 'heliumts/server' {\n // Method stubs for client-side type inference\n${methodExports}\n}\n`;\n}\n\nexport function generateEntryModule(): string {\n return `\nimport React from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { AppRouter } from 'heliumts/client';\nimport App from '/src/App';\n\nconst rootEl = document.getElementById('root');\nif (!rootEl) {\n throw new Error('Root element not found. Helium requires a <div id=\\\"root\\\"></div> in your HTML.');\n}\n\ncreateRoot(rootEl).render(\n <React.StrictMode>\n <AppRouter AppShell={App} />\n </React.StrictMode>\n);\n`;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import type http from "http";
|
|
2
|
-
/**
|
|
3
|
-
* Extracts the client IP address from an HTTP request, taking into account proxy configurations.
|
|
4
|
-
*
|
|
5
|
-
* When behind proxies (like Vercel, Cloudflare, AWS ALB, etc.), the X-Forwarded-For header
|
|
6
|
-
* contains a chain of IP addresses. The format is: "client, proxy1, proxy2, ..."
|
|
7
|
-
*
|
|
8
|
-
* @param req - The HTTP request object
|
|
9
|
-
* @param trustProxyDepth - Number of proxy levels to trust
|
|
10
|
-
* - 0: Only use req.socket.remoteAddress (no proxy trust)
|
|
11
|
-
* - 1: Trust 1 proxy level (get the last IP before your server)
|
|
12
|
-
* - 2+: Trust multiple proxy levels (for complex setups)
|
|
13
|
-
*
|
|
14
|
-
* Examples:
|
|
15
|
-
* - trustProxyDepth=0: Direct connection, no proxies
|
|
16
|
-
* X-Forwarded-For: ignored
|
|
17
|
-
* Result: req.socket.remoteAddress
|
|
18
|
-
*
|
|
19
|
-
* - trustProxyDepth=1: Behind one proxy (e.g., Vercel, Netlify)
|
|
20
|
-
* X-Forwarded-For: "203.0.113.1, 198.51.100.1"
|
|
21
|
-
* Result: "203.0.113.1" (client IP)
|
|
22
|
-
*
|
|
23
|
-
* - trustProxyDepth=2: Behind two proxies (e.g., Cloudflare -> Load Balancer)
|
|
24
|
-
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
25
|
-
* Result: "203.0.113.1" (client IP)
|
|
26
|
-
*
|
|
27
|
-
* Common configurations:
|
|
28
|
-
* - Vercel/Netlify/Railway: trustProxyDepth=1
|
|
29
|
-
* - Cloudflare -> Origin: trustProxyDepth=1 or 2 (depending on your setup)
|
|
30
|
-
* - AWS ALB -> EC2: trustProxyDepth=1
|
|
31
|
-
* - Nginx -> Node: trustProxyDepth=1
|
|
32
|
-
* - Cloudflare -> Nginx -> Node: trustProxyDepth=2
|
|
33
|
-
*/
|
|
34
|
-
export declare function extractClientIP(req: http.IncomingMessage, trustProxyDepth?: number): string;
|
|
35
|
-
/**
|
|
36
|
-
* Alternative extraction method that works from the right (trusts the rightmost IPs).
|
|
37
|
-
* This is useful when you want to trust the last N proxies in the chain.
|
|
38
|
-
*
|
|
39
|
-
* @param req - The HTTP request object
|
|
40
|
-
* @param trustProxyDepth - Number of proxy levels to trust from the right
|
|
41
|
-
*
|
|
42
|
-
* Example:
|
|
43
|
-
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
44
|
-
* trustProxyDepth=1: Result is "198.51.100.1" (skip the last trusted proxy)
|
|
45
|
-
* trustProxyDepth=2: Result is "203.0.113.1" (skip the last 2 trusted proxies)
|
|
46
|
-
*/
|
|
47
|
-
export declare function extractClientIPFromRight(req: http.IncomingMessage, trustProxyDepth?: number): string;
|
|
48
|
-
//# sourceMappingURL=ipExtractor.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ipExtractor.d.ts","sourceRoot":"","sources":["../../src/server/ipExtractor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,eAAe,GAAE,MAAU,GAAG,MAAM,CAqC9F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,eAAe,GAAE,MAAU,GAAG,MAAM,CAsBvG"}
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Extracts the client IP address from an HTTP request, taking into account proxy configurations.
|
|
3
|
-
*
|
|
4
|
-
* When behind proxies (like Vercel, Cloudflare, AWS ALB, etc.), the X-Forwarded-For header
|
|
5
|
-
* contains a chain of IP addresses. The format is: "client, proxy1, proxy2, ..."
|
|
6
|
-
*
|
|
7
|
-
* @param req - The HTTP request object
|
|
8
|
-
* @param trustProxyDepth - Number of proxy levels to trust
|
|
9
|
-
* - 0: Only use req.socket.remoteAddress (no proxy trust)
|
|
10
|
-
* - 1: Trust 1 proxy level (get the last IP before your server)
|
|
11
|
-
* - 2+: Trust multiple proxy levels (for complex setups)
|
|
12
|
-
*
|
|
13
|
-
* Examples:
|
|
14
|
-
* - trustProxyDepth=0: Direct connection, no proxies
|
|
15
|
-
* X-Forwarded-For: ignored
|
|
16
|
-
* Result: req.socket.remoteAddress
|
|
17
|
-
*
|
|
18
|
-
* - trustProxyDepth=1: Behind one proxy (e.g., Vercel, Netlify)
|
|
19
|
-
* X-Forwarded-For: "203.0.113.1, 198.51.100.1"
|
|
20
|
-
* Result: "203.0.113.1" (client IP)
|
|
21
|
-
*
|
|
22
|
-
* - trustProxyDepth=2: Behind two proxies (e.g., Cloudflare -> Load Balancer)
|
|
23
|
-
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
24
|
-
* Result: "203.0.113.1" (client IP)
|
|
25
|
-
*
|
|
26
|
-
* Common configurations:
|
|
27
|
-
* - Vercel/Netlify/Railway: trustProxyDepth=1
|
|
28
|
-
* - Cloudflare -> Origin: trustProxyDepth=1 or 2 (depending on your setup)
|
|
29
|
-
* - AWS ALB -> EC2: trustProxyDepth=1
|
|
30
|
-
* - Nginx -> Node: trustProxyDepth=1
|
|
31
|
-
* - Cloudflare -> Nginx -> Node: trustProxyDepth=2
|
|
32
|
-
*/
|
|
33
|
-
export function extractClientIP(req, trustProxyDepth = 0) {
|
|
34
|
-
// If not trusting any proxies, return the direct connection IP
|
|
35
|
-
if (trustProxyDepth === 0) {
|
|
36
|
-
return req.socket.remoteAddress || "unknown";
|
|
37
|
-
}
|
|
38
|
-
// Get X-Forwarded-For header
|
|
39
|
-
const forwardedFor = req.headers["x-forwarded-for"];
|
|
40
|
-
if (!forwardedFor) {
|
|
41
|
-
// No X-Forwarded-For header, fall back to direct connection
|
|
42
|
-
return req.socket.remoteAddress || "unknown";
|
|
43
|
-
}
|
|
44
|
-
// Parse X-Forwarded-For header (can be a string or array of strings)
|
|
45
|
-
const forwardedIPs = (Array.isArray(forwardedFor) ? forwardedFor.join(",") : forwardedFor)
|
|
46
|
-
.split(",")
|
|
47
|
-
.map((ip) => ip.trim())
|
|
48
|
-
.filter((ip) => ip.length > 0);
|
|
49
|
-
if (forwardedIPs.length === 0) {
|
|
50
|
-
// Empty X-Forwarded-For, fall back to direct connection
|
|
51
|
-
return req.socket.remoteAddress || "unknown";
|
|
52
|
-
}
|
|
53
|
-
// The client IP is at the beginning of the chain
|
|
54
|
-
// We trust the chain up to trustProxyDepth levels
|
|
55
|
-
// Format: [clientIP, proxy1, proxy2, ..., lastProxy]
|
|
56
|
-
// We want the clientIP, but we need to verify we have enough trusted proxies
|
|
57
|
-
if (forwardedIPs.length < trustProxyDepth) {
|
|
58
|
-
// Not enough IPs in the chain, the chain might be incomplete or spoofed
|
|
59
|
-
// Fall back to direct connection for safety
|
|
60
|
-
return req.socket.remoteAddress || "unknown";
|
|
61
|
-
}
|
|
62
|
-
// Return the client IP (first in the chain)
|
|
63
|
-
return forwardedIPs[0];
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Alternative extraction method that works from the right (trusts the rightmost IPs).
|
|
67
|
-
* This is useful when you want to trust the last N proxies in the chain.
|
|
68
|
-
*
|
|
69
|
-
* @param req - The HTTP request object
|
|
70
|
-
* @param trustProxyDepth - Number of proxy levels to trust from the right
|
|
71
|
-
*
|
|
72
|
-
* Example:
|
|
73
|
-
* X-Forwarded-For: "203.0.113.1, 198.51.100.1, 192.0.2.1"
|
|
74
|
-
* trustProxyDepth=1: Result is "198.51.100.1" (skip the last trusted proxy)
|
|
75
|
-
* trustProxyDepth=2: Result is "203.0.113.1" (skip the last 2 trusted proxies)
|
|
76
|
-
*/
|
|
77
|
-
export function extractClientIPFromRight(req, trustProxyDepth = 0) {
|
|
78
|
-
if (trustProxyDepth === 0) {
|
|
79
|
-
return req.socket.remoteAddress || "unknown";
|
|
80
|
-
}
|
|
81
|
-
const forwardedFor = req.headers["x-forwarded-for"];
|
|
82
|
-
if (!forwardedFor) {
|
|
83
|
-
return req.socket.remoteAddress || "unknown";
|
|
84
|
-
}
|
|
85
|
-
const forwardedIPs = (Array.isArray(forwardedFor) ? forwardedFor.join(",") : forwardedFor)
|
|
86
|
-
.split(",")
|
|
87
|
-
.map((ip) => ip.trim())
|
|
88
|
-
.filter((ip) => ip.length > 0);
|
|
89
|
-
if (forwardedIPs.length === 0) {
|
|
90
|
-
return req.socket.remoteAddress || "unknown";
|
|
91
|
-
}
|
|
92
|
-
// Calculate which IP to trust by skipping the rightmost N trusted proxies
|
|
93
|
-
const clientIPIndex = Math.max(0, forwardedIPs.length - trustProxyDepth - 1);
|
|
94
|
-
return forwardedIPs[clientIPIndex];
|
|
95
|
-
}
|
|
96
|
-
//# sourceMappingURL=ipExtractor.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ipExtractor.js","sourceRoot":"","sources":["../../src/server/ipExtractor.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,eAAe,CAAC,GAAyB,EAAE,kBAA0B,CAAC;IAClF,+DAA+D;IAC/D,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,6BAA6B;IAC7B,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,4DAA4D;QAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,qEAAqE;IACrE,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;SACrF,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;SACtB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,wDAAwD;QACxD,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,iDAAiD;IACjD,kDAAkD;IAClD,qDAAqD;IACrD,6EAA6E;IAE7E,IAAI,YAAY,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;QACxC,wEAAwE;QACxE,4CAA4C;QAC5C,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,4CAA4C;IAC5C,OAAO,YAAY,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,wBAAwB,CAAC,GAAyB,EAAE,kBAA0B,CAAC;IAC3F,IAAI,eAAe,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;IACpD,IAAI,CAAC,YAAY,EAAE,CAAC;QAChB,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,MAAM,YAAY,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC;SACrF,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;SACtB,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEnC,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAC;IACjD,CAAC;IAED,0EAA0E;IAC1E,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,CAAC,MAAM,GAAG,eAAe,GAAG,CAAC,CAAC,CAAC;IAC7E,OAAO,YAAY,CAAC,aAAa,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function getRequestPath(url: string | undefined): string;
|
|
2
|
-
export declare function isDevInternalOrAssetRequest(url: string | undefined): boolean;
|
|
3
|
-
export declare function resolveDirectStaticAssetPath(staticDir: string, url: string | undefined): string | null;
|
|
4
|
-
//# sourceMappingURL=requestRouting.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"requestRouting.d.ts","sourceRoot":"","sources":["../../src/server/requestRouting.ts"],"names":[],"mappings":"AAsCA,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAE9D;AAED,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAS5E;AAED,wBAAgB,4BAA4B,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAwBtG"}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
import fs from "fs";
|
|
2
|
-
import path from "path";
|
|
3
|
-
const STATIC_ASSET_EXTENSIONS = new Set([
|
|
4
|
-
".js",
|
|
5
|
-
".mjs",
|
|
6
|
-
".cjs",
|
|
7
|
-
".ts",
|
|
8
|
-
".tsx",
|
|
9
|
-
".jsx",
|
|
10
|
-
".css",
|
|
11
|
-
".map",
|
|
12
|
-
".json",
|
|
13
|
-
".png",
|
|
14
|
-
".jpg",
|
|
15
|
-
".jpeg",
|
|
16
|
-
".gif",
|
|
17
|
-
".svg",
|
|
18
|
-
".ico",
|
|
19
|
-
".webp",
|
|
20
|
-
".avif",
|
|
21
|
-
".woff",
|
|
22
|
-
".woff2",
|
|
23
|
-
".ttf",
|
|
24
|
-
".eot",
|
|
25
|
-
".otf",
|
|
26
|
-
".mp4",
|
|
27
|
-
".webm",
|
|
28
|
-
".ogg",
|
|
29
|
-
".mp3",
|
|
30
|
-
".wav",
|
|
31
|
-
".txt",
|
|
32
|
-
".xml",
|
|
33
|
-
".wasm",
|
|
34
|
-
]);
|
|
35
|
-
const DEV_INTERNAL_PREFIXES = ["/@vite", "/@fs/", "/@id/", "/__vite", "/src/", "/node_modules/"];
|
|
36
|
-
export function getRequestPath(url) {
|
|
37
|
-
return (url || "/").split("?")[0] || "/";
|
|
38
|
-
}
|
|
39
|
-
export function isDevInternalOrAssetRequest(url) {
|
|
40
|
-
const requestPath = getRequestPath(url);
|
|
41
|
-
if (DEV_INTERNAL_PREFIXES.some((prefix) => requestPath.startsWith(prefix))) {
|
|
42
|
-
return true;
|
|
43
|
-
}
|
|
44
|
-
const extension = path.extname(requestPath).toLowerCase();
|
|
45
|
-
return extension.length > 0 && STATIC_ASSET_EXTENSIONS.has(extension);
|
|
46
|
-
}
|
|
47
|
-
export function resolveDirectStaticAssetPath(staticDir, url) {
|
|
48
|
-
const requestPath = getRequestPath(url);
|
|
49
|
-
const extension = path.extname(requestPath).toLowerCase();
|
|
50
|
-
if (!extension) {
|
|
51
|
-
return null;
|
|
52
|
-
}
|
|
53
|
-
const resolvedStaticDir = path.resolve(staticDir);
|
|
54
|
-
const candidatePath = path.resolve(staticDir, "." + requestPath);
|
|
55
|
-
if (!candidatePath.startsWith(resolvedStaticDir + path.sep) && candidatePath !== resolvedStaticDir) {
|
|
56
|
-
return null;
|
|
57
|
-
}
|
|
58
|
-
if (!fs.existsSync(candidatePath)) {
|
|
59
|
-
return null;
|
|
60
|
-
}
|
|
61
|
-
const stat = fs.statSync(candidatePath);
|
|
62
|
-
if (!stat.isFile()) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
return candidatePath;
|
|
66
|
-
}
|
|
67
|
-
//# sourceMappingURL=requestRouting.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"requestRouting.js","sourceRoot":"","sources":["../../src/server/requestRouting.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACpC,KAAK;IACL,MAAM;IACN,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;IACP,OAAO;IACP,QAAQ;IACR,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;IACP,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,OAAO;CACV,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC;AAEjG,MAAM,UAAU,cAAc,CAAC,GAAuB;IAClD,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,2BAA2B,CAAC,GAAuB;IAC/D,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IAExC,IAAI,qBAAqB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;QACzE,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IAC1D,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,uBAAuB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,SAAiB,EAAE,GAAuB;IACnF,MAAM,WAAW,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;IAE1D,IAAI,CAAC,SAAS,EAAE,CAAC;QACb,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClD,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,GAAG,WAAW,CAAC,CAAC;IACjE,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,aAAa,KAAK,iBAAiB,EAAE,CAAC;QACjG,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAChC,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QACjB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,OAAO,aAAa,CAAC;AACzB,CAAC","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\n\nconst STATIC_ASSET_EXTENSIONS = new Set([\n \".js\",\n \".mjs\",\n \".cjs\",\n \".ts\",\n \".tsx\",\n \".jsx\",\n \".css\",\n \".map\",\n \".json\",\n \".png\",\n \".jpg\",\n \".jpeg\",\n \".gif\",\n \".svg\",\n \".ico\",\n \".webp\",\n \".avif\",\n \".woff\",\n \".woff2\",\n \".ttf\",\n \".eot\",\n \".otf\",\n \".mp4\",\n \".webm\",\n \".ogg\",\n \".mp3\",\n \".wav\",\n \".txt\",\n \".xml\",\n \".wasm\",\n]);\n\nconst DEV_INTERNAL_PREFIXES = [\"/@vite\", \"/@fs/\", \"/@id/\", \"/__vite\", \"/src/\", \"/node_modules/\"];\n\nexport function getRequestPath(url: string | undefined): string {\n return (url || \"/\").split(\"?\")[0] || \"/\";\n}\n\nexport function isDevInternalOrAssetRequest(url: string | undefined): boolean {\n const requestPath = getRequestPath(url);\n\n if (DEV_INTERNAL_PREFIXES.some((prefix) => requestPath.startsWith(prefix))) {\n return true;\n }\n\n const extension = path.extname(requestPath).toLowerCase();\n return extension.length > 0 && STATIC_ASSET_EXTENSIONS.has(extension);\n}\n\nexport function resolveDirectStaticAssetPath(staticDir: string, url: string | undefined): string | null {\n const requestPath = getRequestPath(url);\n const extension = path.extname(requestPath).toLowerCase();\n\n if (!extension) {\n return null;\n }\n\n const resolvedStaticDir = path.resolve(staticDir);\n const candidatePath = path.resolve(staticDir, \".\" + requestPath);\n if (!candidatePath.startsWith(resolvedStaticDir + path.sep) && candidatePath !== resolvedStaticDir) {\n return null;\n }\n\n if (!fs.existsSync(candidatePath)) {\n return null;\n }\n\n const stat = fs.statSync(candidatePath);\n if (!stat.isFile()) {\n return null;\n }\n\n return candidatePath;\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=deepEqual.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deepEqual.d.ts","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":""}
|
package/dist/utils/deepEqual.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deepEqual.js","sourceRoot":"","sources":["../../src/utils/deepEqual.ts"],"names":[],"mappings":""}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatError.d.ts","sourceRoot":"","sources":["../../src/utils/formatError.ts"],"names":[],"mappings":"AAAA,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAgBhD"}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export function formatError(err) {
|
|
2
|
-
console.log("🚀 ~ formatError ~ err:", err);
|
|
3
|
-
if (err instanceof Error) {
|
|
4
|
-
return err.message;
|
|
5
|
-
}
|
|
6
|
-
if (typeof err === "object" && err !== null) {
|
|
7
|
-
if ("message" in err) {
|
|
8
|
-
return String(err.message);
|
|
9
|
-
}
|
|
10
|
-
// Format Record<string, string> errors
|
|
11
|
-
return JSON.stringify(err, null, 2);
|
|
12
|
-
}
|
|
13
|
-
if (typeof err === "string") {
|
|
14
|
-
return err;
|
|
15
|
-
}
|
|
16
|
-
return String(err);
|
|
17
|
-
}
|
|
18
|
-
//# sourceMappingURL=formatError.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatError.js","sourceRoot":"","sources":["../../src/utils/formatError.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,WAAW,CAAC,GAAY;IACpC,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,GAAG,CAAC,CAAC;IAC5C,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACvB,OAAO,GAAG,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAC1C,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;QACD,uCAAuC;QACvC,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC1B,OAAO,GAAG,CAAC;IACf,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;AACvB,CAAC"}
|