@void/edge 1.3.0 → 1.5.0
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/index.d.mts +3 -14
- package/dist/index.mjs +28 -13
- package/package.json +4 -4
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { AssetConfig, AssetConfig as AssetConfig$1, HeaderRule, HeaderRule as HeaderRule$1, RedirectRule, RedirectRule as RedirectRule$1 } from "@void/deploy-core";
|
|
2
|
-
//#region src/access.d.ts
|
|
3
2
|
type ProjectZeroTrustRouting = Readonly<{
|
|
4
3
|
teamDomain: string;
|
|
5
4
|
audiences: ReadonlyArray<Readonly<{
|
|
@@ -7,8 +6,8 @@ type ProjectZeroTrustRouting = Readonly<{
|
|
|
7
6
|
audience: string;
|
|
8
7
|
}>>;
|
|
9
8
|
}>;
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
/** Upgrade public HTTP requests without involving assets or application code. */
|
|
10
|
+
export declare function redirectToHttps(request: Request): Response | undefined;
|
|
12
11
|
type HeaderRulePolicy = Readonly<{
|
|
13
12
|
/**
|
|
14
13
|
* Protect unrelated tenants that share one registrable domain. Direct
|
|
@@ -54,8 +53,6 @@ export declare function sanitizeClearSiteData(value: string): string | null;
|
|
|
54
53
|
* Returns the original response unchanged when no rules or no matches.
|
|
55
54
|
*/
|
|
56
55
|
export declare function applyHeaderRules(response: Response, pathname: string, rules?: ReadonlyArray<HeaderRule$1>, policy?: HeaderRulePolicy): Response;
|
|
57
|
-
//#endregion
|
|
58
|
-
//#region src/pattern.d.ts
|
|
59
56
|
type CompiledPattern = Readonly<{
|
|
60
57
|
/**
|
|
61
58
|
* @deprecated Built on first read for older callers; Void does not use it.
|
|
@@ -108,8 +105,6 @@ export declare function matchSegmentPattern(pattern: string, pathname: string):
|
|
|
108
105
|
* because `compilePattern` captures anonymous `*` as `splat`.
|
|
109
106
|
*/
|
|
110
107
|
export declare function substituteParams(destination: string, params: Record<string, string>): string;
|
|
111
|
-
//#endregion
|
|
112
|
-
//#region src/routing-rules.d.ts
|
|
113
108
|
type RoutingRuleResult = {
|
|
114
109
|
type: "redirect";
|
|
115
110
|
destination: string;
|
|
@@ -147,8 +142,6 @@ export declare function applyRoutingRules(pathname: string, rules?: ReadonlyArra
|
|
|
147
142
|
* rather than `/new#faq?utm=x` (which browsers treat as fragment text).
|
|
148
143
|
*/
|
|
149
144
|
export declare function mergeQueryIntoLocation(destination: string, requestSearch: string): string;
|
|
150
|
-
//#endregion
|
|
151
|
-
//#region src/runtime.d.ts
|
|
152
145
|
type EdgeAssetFetcher = Readonly<{
|
|
153
146
|
fetch(request: Request): Promise<Response>;
|
|
154
147
|
}>;
|
|
@@ -156,6 +149,7 @@ type StaticEdgeEnv = Readonly<{
|
|
|
156
149
|
ASSETS: EdgeAssetFetcher;
|
|
157
150
|
}>;
|
|
158
151
|
type StaticEdgeConfig = Readonly<{
|
|
152
|
+
alwaysUseHttps?: boolean;
|
|
159
153
|
/** Optional native Worker self-metadata used to identify the served version. */
|
|
160
154
|
versionMetadataBinding?: string;
|
|
161
155
|
/**
|
|
@@ -178,8 +172,6 @@ type StaticEdgeHandler = Readonly<{
|
|
|
178
172
|
* miss, and response-header rules apply to the effective pathname.
|
|
179
173
|
*/
|
|
180
174
|
export declare function createStaticEdgeHandler(config: StaticEdgeConfig): StaticEdgeHandler;
|
|
181
|
-
//#endregion
|
|
182
|
-
//#region src/static.d.ts
|
|
183
175
|
type ResolvedAsset = Readonly<{
|
|
184
176
|
path: string;
|
|
185
177
|
hash: string;
|
|
@@ -242,8 +234,6 @@ export declare function getContentType(path: string): string;
|
|
|
242
234
|
* Any other stored value is authoritative and honored as-is.
|
|
243
235
|
*/
|
|
244
236
|
export declare function resolveAssetContentType(stored: string | null | undefined, path: string): string | undefined;
|
|
245
|
-
//#endregion
|
|
246
|
-
//#region src/limits.d.ts
|
|
247
237
|
/** Shared between the SDK, edge admission and Pages clients. */
|
|
248
238
|
type UsageLimitData = {
|
|
249
239
|
code: "usage_limit";
|
|
@@ -254,5 +244,4 @@ type UsageLimitData = {
|
|
|
254
244
|
};
|
|
255
245
|
export declare function readUsageLimit(value: unknown): UsageLimitData | null;
|
|
256
246
|
export declare function usageLimitResponse(limit: UsageLimitData): Response;
|
|
257
|
-
//#endregion
|
|
258
247
|
export type { AssetConfig, ClearSiteDataMember, CompiledPattern, EdgeAssetFetcher, HeaderRule, HeaderRulePolicy, ProjectZeroTrustRouting, RedirectRule, ResolvedAsset, RoutingRuleResult, StaticEdgeConfig, StaticEdgeEnv, StaticEdgeHandler, UsageLimitData };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
// src/https.ts
|
|
2
|
+
/** Upgrade public HTTP requests without involving assets or application code. */
|
|
3
|
+
function redirectToHttps(request) {
|
|
4
|
+
const url = new URL(request.url);
|
|
5
|
+
if (url.protocol !== "http:" || url.hostname === "localhost" || url.hostname.endsWith(".localhost") || isIpv4Loopback(url.hostname) || url.hostname === "[::1]" || url.pathname.startsWith("/.well-known/acme-challenge/") || url.pathname.startsWith("/.well-known/pki-validation/")) return;
|
|
6
|
+
url.protocol = "https:";
|
|
7
|
+
url.port = "";
|
|
8
|
+
return Response.redirect(url.href, 308);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* `URL` already rewrites every IPv4 form (`127.1`, `0x7f.0.0.1`) to four
|
|
12
|
+
* decimal parts and rejects parts above 255, so only the shape is checked.
|
|
13
|
+
*/
|
|
14
|
+
function isIpv4Loopback(hostname) {
|
|
15
|
+
const parts = hostname.split(".");
|
|
16
|
+
return parts.length === 4 && parts[0] === "127" && parts.every((part) => part !== "" && [...part].every((char) => char >= "0" && char <= "9"));
|
|
17
|
+
}
|
|
18
|
+
// src/pattern.ts
|
|
2
19
|
/**
|
|
3
20
|
* Path-pattern matchers shared by routing, header, and revalidate rules.
|
|
4
21
|
*
|
|
@@ -366,8 +383,7 @@ function substituteParams(destination, params) {
|
|
|
366
383
|
if (/^[/\\]{2}/.test(result) && !/^[/\\]{2}/.test(destination)) return "/" + result.replace(/^[/\\]+/, "");
|
|
367
384
|
return result;
|
|
368
385
|
}
|
|
369
|
-
|
|
370
|
-
//#region src/headers.ts
|
|
386
|
+
// src/headers.ts
|
|
371
387
|
/**
|
|
372
388
|
* Headers that rules may never set on a shared domain. void.app is not on the
|
|
373
389
|
* Public Suffix List, so a `Set-Cookie` with `Domain=.void.app` reaches every
|
|
@@ -478,8 +494,7 @@ function applyHeaderRules(response, pathname, rules, policy) {
|
|
|
478
494
|
}
|
|
479
495
|
return newResponse;
|
|
480
496
|
}
|
|
481
|
-
|
|
482
|
-
//#region src/routing-rules.ts
|
|
497
|
+
// src/routing-rules.ts
|
|
483
498
|
/**
|
|
484
499
|
* Check routing rules (redirects + rewrites) against a request pathname.
|
|
485
500
|
*
|
|
@@ -545,8 +560,7 @@ function mergeQueryIntoLocation(destination, requestSearch) {
|
|
|
545
560
|
for (const [key, value] of reqParams) if (!destParams.has(key)) destParams.append(key, value);
|
|
546
561
|
return base.slice(0, destQueryIdx) + "?" + destParams.toString() + fragment;
|
|
547
562
|
}
|
|
548
|
-
|
|
549
|
-
//#region src/runtime.ts
|
|
563
|
+
// src/runtime.ts
|
|
550
564
|
/**
|
|
551
565
|
* Create the thin Worker used by direct static, SPA, and SSG deployments.
|
|
552
566
|
* Routing semantics intentionally match the hosted dispatch Worker: redirects
|
|
@@ -564,6 +578,10 @@ function createStaticEdgeHandler(config) {
|
|
|
564
578
|
versionId: metadata?.id
|
|
565
579
|
}, { headers: { "cache-control": "no-store" } });
|
|
566
580
|
}
|
|
581
|
+
if (config.alwaysUseHttps) {
|
|
582
|
+
const redirect = redirectToHttps(request);
|
|
583
|
+
if (redirect) return redirect;
|
|
584
|
+
}
|
|
567
585
|
let effectiveUrl = new URL(originalUrl);
|
|
568
586
|
let effectiveRequest = request;
|
|
569
587
|
const route = applyRoutingRules(effectiveUrl.pathname, config.redirectRules, effectiveUrl.hostname);
|
|
@@ -599,8 +617,7 @@ function rewriteRequest(request, url, originalUrl) {
|
|
|
599
617
|
rewritten.headers.set("X-Void-Original-URL", originalUrl);
|
|
600
618
|
return rewritten;
|
|
601
619
|
}
|
|
602
|
-
|
|
603
|
-
//#region src/static.ts
|
|
620
|
+
// src/static.ts
|
|
604
621
|
/**
|
|
605
622
|
* Percent-decode a request pathname for a manifest lookup, honoring required
|
|
606
623
|
* URL encodings and encoded square brackets. Returns the raw value unchanged
|
|
@@ -830,8 +847,7 @@ function resolveAssetContentType(stored, path) {
|
|
|
830
847
|
if (!stored || stored === "application/octet-stream") return getContentType(path);
|
|
831
848
|
return stored;
|
|
832
849
|
}
|
|
833
|
-
|
|
834
|
-
//#region src/limits.ts
|
|
850
|
+
// src/limits.ts
|
|
835
851
|
function readUsageLimit(value) {
|
|
836
852
|
if (!value || typeof value !== "object") return null;
|
|
837
853
|
const v = value;
|
|
@@ -863,5 +879,4 @@ function usageLimitResponse(limit) {
|
|
|
863
879
|
headers
|
|
864
880
|
});
|
|
865
881
|
}
|
|
866
|
-
|
|
867
|
-
export { applyHeaderRules, applyRoutingRules, compilePattern, createStaticEdgeHandler, getContentType, matchLiteralPattern, matchPattern, matchPatternCaptures, matchSegmentPattern, mergeQueryIntoLocation, parseClearSiteData, readUsageLimit, resolveAssetContentType, resolveStaticPath, safeDecodePathname, sanitizeClearSiteData, substituteParams, usageLimitResponse };
|
|
882
|
+
export { applyHeaderRules, applyRoutingRules, compilePattern, createStaticEdgeHandler, getContentType, matchLiteralPattern, matchPattern, matchPatternCaptures, matchSegmentPattern, mergeQueryIntoLocation, parseClearSiteData, readUsageLimit, redirectToHttps, resolveAssetContentType, resolveStaticPath, safeDecodePathname, sanitizeClearSiteData, substituteParams, usageLimitResponse };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@void/edge",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Routing, headers, and static asset helpers for Void runtimes.",
|
|
5
5
|
"homepage": "https://void.cloud",
|
|
6
6
|
"bugs": {
|
|
@@ -26,12 +26,12 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@void/deploy-core": "1.
|
|
29
|
+
"@void/deploy-core": "1.5.0"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
|
-
"@cloudflare/workers-types": "^5.
|
|
32
|
+
"@cloudflare/workers-types": "^5.20261102.1",
|
|
33
33
|
"typescript": "7.0.2",
|
|
34
|
-
"vite-plus": "1.
|
|
34
|
+
"vite-plus": "1.4.0"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "vp pack",
|