@void/platform 0.26.0 → 0.26.1
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 +23 -3
- package/dist/browser-page.d.mts +19 -0
- package/dist/browser-page.mjs +90 -0
- package/dist/email-protocol.mjs +47 -53
- package/dist/index.mjs +7 -23
- package/dist/installer.mjs +3 -1
- package/dist/runtime/api/assets/admin/client.js +85 -24
- package/dist/runtime/api/assets/admin/style.css +1 -1
- package/dist/runtime/api/index.js +401 -301
- package/dist/runtime/dispatch/index.js +8 -8
- package/dist/runtime/drizzle/0058_project_proxy_token_gen.sql +2 -0
- package/dist/runtime/drizzle/compatibility.json +8 -0
- package/dist/runtime/drizzle/meta/_journal.json +7 -0
- package/dist/runtime/emailGateway/index.js +5 -5
- package/dist/runtime/manifest.json +30 -16
- package/dist/runtime/proxy/index.js +6 -3
- package/package.json +13 -3
package/README.md
CHANGED
|
@@ -1,12 +1,32 @@
|
|
|
1
1
|
# @void/platform
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Packaged runtime for [Void Platform](https://void.cloud/guide/self-hosted-platform), a shared deployment environment for your team or customers in your Cloudflare account. The Void CLI uses this package to install and maintain the platform.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Your users can build and deploy apps without setting up separate Cloudflare accounts. Administrators control access, set resource limits, and inspect deployments and usage.
|
|
6
|
+
|
|
7
|
+
## Getting Started
|
|
8
|
+
|
|
9
|
+
Install the `void` CLI and start the guided platform setup:
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install -D void
|
|
13
|
+
npx void platform install
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Once the platform is installed, developers connect and deploy:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
npx void connect https://api.example.com
|
|
20
|
+
npx void deploy
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The platform is open source. Use it as provided, contribute improvements, or fork it to integrate your systems and customize deployment workflows.
|
|
6
24
|
|
|
7
25
|
## Documentation
|
|
8
26
|
|
|
9
|
-
- [Installation](https://void.cloud/guide/self-hosted-platform)
|
|
27
|
+
- [Installation and prerequisites](https://void.cloud/guide/self-hosted-platform)
|
|
10
28
|
- [Administration](https://void.cloud/guide/platform-administration)
|
|
11
29
|
- [Maintenance and recovery](https://void.cloud/guide/platform/installation/maintenance)
|
|
12
30
|
- [Platform development](https://void.cloud/guide/platform-development)
|
|
31
|
+
|
|
32
|
+
Read the [Void documentation](https://void.cloud) online or use the Markdown guides and references in `node_modules/void/docs/`, included with the `void` package.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/browser-page.d.ts
|
|
2
|
+
/** Shared, dependency-free presentation for browser onboarding and authentication pages. */
|
|
3
|
+
export declare const browserPageLogo: string;
|
|
4
|
+
export declare const browserPageStyles: string;
|
|
5
|
+
export declare function escapeBrowserHtml(value: string): string;
|
|
6
|
+
export declare function browserPageIdentity(identity: {
|
|
7
|
+
login: string;
|
|
8
|
+
issuer: string;
|
|
9
|
+
subject: string;
|
|
10
|
+
}): string;
|
|
11
|
+
export declare function browserPageStatus(status: "success" | "error"): string;
|
|
12
|
+
/** content is trusted markup; escape every dynamic value before composing it. */
|
|
13
|
+
export declare function renderBrowserPage({ title, platformName, content }: {
|
|
14
|
+
title: string;
|
|
15
|
+
platformName?: string;
|
|
16
|
+
content: string;
|
|
17
|
+
}): string;
|
|
18
|
+
export declare function browserPageLead(title: string, description: string): string;
|
|
19
|
+
//#endregion
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
//#region src/browser-page.ts
|
|
2
|
+
/** Shared, dependency-free presentation for browser onboarding and authentication pages. */
|
|
3
|
+
const browserPageLogo = "<svg role=\"img\" aria-label=\"Void\" viewBox=\"0 0 270 58\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<circle cx=\"262\" cy=\"48.96\" r=\"8\" fill=\"currentColor\"/>\n<path d=\"M20.72 0.959999L35.52 41.28L50.08 0.959999H70L47.92 56.96H22.32L0.24 0.959999H20.72ZM106.542 57.92C82.9419 57.92 70.6219 48 70.6219 28.96C70.6219 9.92 82.9419 1.90735e-06 106.542 1.90735e-06C130.142 1.90735e-06 142.542 9.92 142.542 28.96C142.542 48 130.142 57.92 106.542 57.92ZM106.542 44.08C117.662 44.08 122.862 39.36 122.862 28.96C122.862 18.48 117.662 13.76 106.542 13.76C95.4219 13.76 90.2219 18.48 90.2219 28.96C90.2219 39.36 95.4219 44.08 106.542 44.08ZM152.265 56.96V0.959999H171.465V56.96H152.265ZM184.687 56.96V0.959999H219.887C239.327 0.959999 250.447 9.84 250.447 28.96C250.447 48.16 239.247 56.96 219.807 56.96H184.687ZM230.767 28.96C230.767 18.48 226.287 14.56 217.167 14.56H203.887V43.36H217.167C226.287 43.36 230.767 39.44 230.767 28.96Z\" fill=\"currentColor\"/>\n</svg>";
|
|
4
|
+
const browserPageStyles = `
|
|
5
|
+
:root { color-scheme: light dark; }
|
|
6
|
+
html[data-theme="light"] { color-scheme: light; }
|
|
7
|
+
html[data-theme="dark"] { color-scheme: dark; }
|
|
8
|
+
.void-auth-page {
|
|
9
|
+
--auth-radius-inner: .375rem; --auth-radius-element: .625rem; --auth-radius-container: .75rem;
|
|
10
|
+
--auth-body: light-dark(#f1f1f1, #1b1b1b); --auth-card: light-dark(#fff, #1b1b1b);
|
|
11
|
+
--auth-text: light-dark(#000, #fff); --auth-secondary: light-dark(#474747, #9e9e9e);
|
|
12
|
+
--auth-border: light-dark(#0000000f, #ffffff1a); --auth-accent: light-dark(#1b1b1b, #f1f1f1); --auth-on-accent: light-dark(#fff, #1b1b1b);
|
|
13
|
+
--auth-success: light-dark(#176e45, #79dba9); --auth-success-bg: light-dark(#e7f4ec, #173a29);
|
|
14
|
+
--auth-error: light-dark(#b42332, #ff9aab); --auth-error-bg: light-dark(#fcebed, #421d26);
|
|
15
|
+
box-sizing: border-box; min-height: 100svh; margin: 0;
|
|
16
|
+
padding: clamp(40px, 10vh, 100px) 16px 48px; background: var(--auth-body); color: var(--auth-text);
|
|
17
|
+
font: 14px/1.55 Figtree, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
18
|
+
}
|
|
19
|
+
@supports (color: AccentColor) { .void-auth-page { --auth-accent: AccentColor; --auth-on-accent: AccentColorText; } }
|
|
20
|
+
/* Match the neutral administrator dashboard's radii, including its rounded fallback. */
|
|
21
|
+
@supports (corner-shape: squircle) {
|
|
22
|
+
.void-auth-page { --auth-radius-inner: .75rem; --auth-radius-element: 1.25rem; --auth-radius-container: 1.5rem; }
|
|
23
|
+
.void-auth-page, .void-auth-page *, .void-auth-page *::before, .void-auth-page *::after { corner-shape: squircle; }
|
|
24
|
+
.void-auth-page .void-auth-status { corner-shape: round; }
|
|
25
|
+
}
|
|
26
|
+
.void-auth-page *, .void-auth-page *::before, .void-auth-page *::after { box-sizing: border-box; }
|
|
27
|
+
.void-auth-page .void-auth-container { width: 100%; max-width: 448px; margin: 0 auto; }
|
|
28
|
+
.void-auth-page .void-auth-brand { display: flex; align-items: center; gap: 12px; margin: 0 4px 24px; color: var(--auth-secondary); overflow-wrap: anywhere; }
|
|
29
|
+
.void-auth-page .void-auth-logo { display: flex; flex: 0 0 70px; color: var(--auth-text); }
|
|
30
|
+
.void-auth-page .void-auth-logo svg { display: block; width: 70px; height: auto; }
|
|
31
|
+
.void-auth-page .void-auth-divider { width: 1px; height: 18px; background: var(--auth-border); flex-shrink: 0; }
|
|
32
|
+
.void-auth-page .void-auth-card { display: grid; gap: 24px; min-width: 0; padding: 24px; border: 1px solid var(--auth-border); border-radius: var(--auth-radius-container); background: var(--auth-card); }
|
|
33
|
+
.void-auth-page .void-auth-lead { display: grid; gap: 10px; }
|
|
34
|
+
.void-auth-page .void-auth-section { display: grid; gap: 12px; min-width: 0; }
|
|
35
|
+
.void-auth-page h1 { margin: 0; font-family: inherit; font-size: 26px; font-weight: 600; line-height: 1.2; letter-spacing: -.5px; color: var(--auth-text); overflow-wrap: anywhere; }
|
|
36
|
+
.void-auth-page h2 { margin: 0; font-family: inherit; font-size: 18px; font-weight: 600; line-height: 1.3; color: var(--auth-text); overflow-wrap: anywhere; }
|
|
37
|
+
.void-auth-page p { margin: 0; font: inherit; color: var(--auth-secondary); overflow-wrap: anywhere; }
|
|
38
|
+
.void-auth-page strong { font-weight: 600; color: var(--auth-text); }
|
|
39
|
+
.void-auth-page a:not(.void-auth-button) { color: var(--auth-text); text-underline-offset: 3px; }
|
|
40
|
+
.void-auth-page .void-auth-actions { display: grid; gap: 12px; }
|
|
41
|
+
.void-auth-page .void-auth-button { display: flex; align-items: center; justify-content: center; width: 100%; min-height: 44px; padding: 10px 16px; border: 1px solid var(--auth-border); border-radius: var(--auth-radius-element); background: var(--auth-body); color: var(--auth-text); font: inherit; font-weight: 550; line-height: 1.4; text-align: center; text-decoration: none; overflow-wrap: anywhere; cursor: pointer; }
|
|
42
|
+
.void-auth-page .void-auth-button-primary { background: var(--auth-accent); color: var(--auth-on-accent); border-color: var(--auth-accent); }
|
|
43
|
+
.void-auth-page .void-auth-button:hover { filter: brightness(.92); }
|
|
44
|
+
.void-auth-page :is(a, button, input):focus-visible { outline: 2px solid var(--auth-accent); outline-offset: 3px; }
|
|
45
|
+
.void-auth-page .void-auth-form { display: grid; gap: 10px; }
|
|
46
|
+
.void-auth-page label { font-weight: 550; }
|
|
47
|
+
.void-auth-page input:not([type=hidden]) { width: 100%; min-width: 0; height: 44px; padding: 0 12px; border: 1px solid var(--auth-border); border-radius: var(--auth-radius-element); background: var(--auth-body); color: var(--auth-text); font: inherit; }
|
|
48
|
+
.void-auth-page .void-auth-form button { margin-top: 8px; }
|
|
49
|
+
.void-auth-page .void-auth-identity { margin: 0; padding: 8px 14px; border: 1px solid var(--auth-border); border-radius: var(--auth-radius-inner); background: var(--auth-body); }
|
|
50
|
+
.void-auth-page .void-auth-identity > div { display: grid; grid-template-columns: 80px minmax(0, 1fr); gap: 16px; padding: 10px 0; }
|
|
51
|
+
.void-auth-page .void-auth-identity > div + div { border-top: 1px solid var(--auth-border); }
|
|
52
|
+
.void-auth-page dt { color: var(--auth-secondary); font-size: 13px; }
|
|
53
|
+
.void-auth-page dd { margin: 0; overflow-wrap: anywhere; }
|
|
54
|
+
.void-auth-page .void-auth-note { font-size: 13px; color: var(--auth-secondary); }
|
|
55
|
+
.void-auth-page pre { margin: 0; padding: 14px; border: 1px solid var(--auth-border); border-radius: var(--auth-radius-container); background: var(--auth-body); white-space: pre-wrap; overflow-wrap: anywhere; }
|
|
56
|
+
.void-auth-page code { font: 13px/1.6 ui-monospace, "SF Mono", Monaco, Consolas, monospace; }
|
|
57
|
+
.void-auth-page p code { padding: 2px 7px; background: light-dark(#e5e5e5, #343434); color: var(--auth-text); border-radius: 24px; corner-shape: squircle; white-space: nowrap; }
|
|
58
|
+
.void-auth-page .void-auth-status { display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; font-size: 22px; font-weight: 650; }
|
|
59
|
+
.void-auth-page .void-auth-status-success { color: var(--auth-success); background: var(--auth-success-bg); }
|
|
60
|
+
.void-auth-page .void-auth-status-error { color: var(--auth-error); background: var(--auth-error-bg); }
|
|
61
|
+
@media (max-width: 500px) { .void-auth-page h1 { font-size: 24px; } }
|
|
62
|
+
`;
|
|
63
|
+
function escapeBrowserHtml(value) {
|
|
64
|
+
return value.replace(/[&<>"']/g, (character) => ({
|
|
65
|
+
"&": "&",
|
|
66
|
+
"<": "<",
|
|
67
|
+
">": ">",
|
|
68
|
+
"\"": """,
|
|
69
|
+
"'": "'"
|
|
70
|
+
})[character]);
|
|
71
|
+
}
|
|
72
|
+
function browserPageIdentity(identity) {
|
|
73
|
+
return "<dl class=\"void-auth-identity\">" + [
|
|
74
|
+
["Account", identity.login],
|
|
75
|
+
["Provider", identity.issuer],
|
|
76
|
+
["Identity", identity.subject]
|
|
77
|
+
].map(([label, value]) => "<div><dt>" + label + "</dt><dd>" + escapeBrowserHtml(value) + "</dd></div>").join("") + "</dl>";
|
|
78
|
+
}
|
|
79
|
+
function browserPageStatus(status) {
|
|
80
|
+
return "<div class=\"void-auth-status void-auth-status-" + status + "\" aria-label=\"" + (status === "success" ? "Success" : "Error") + "\">" + (status === "success" ? "✓" : "!") + "</div>";
|
|
81
|
+
}
|
|
82
|
+
/** content is trusted markup; escape every dynamic value before composing it. */
|
|
83
|
+
function renderBrowserPage({ title, platformName = "Void", content }) {
|
|
84
|
+
return "<!doctype html><html lang=\"en\"><head><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><meta name=\"color-scheme\" content=\"light dark\"><title>" + escapeBrowserHtml(title + " · " + platformName + (/\bvoid\b/i.test(platformName) ? "" : " · Void")) + "</title><style>body{margin:0}" + browserPageStyles + "</style></head><body><main class=\"void-auth-page\"><div class=\"void-auth-container\"><div class=\"void-auth-brand\"><span class=\"void-auth-logo\"><svg role=\"img\" aria-label=\"Void\" viewBox=\"0 0 270 58\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n<circle cx=\"262\" cy=\"48.96\" r=\"8\" fill=\"currentColor\"/>\n<path d=\"M20.72 0.959999L35.52 41.28L50.08 0.959999H70L47.92 56.96H22.32L0.24 0.959999H20.72ZM106.542 57.92C82.9419 57.92 70.6219 48 70.6219 28.96C70.6219 9.92 82.9419 1.90735e-06 106.542 1.90735e-06C130.142 1.90735e-06 142.542 9.92 142.542 28.96C142.542 48 130.142 57.92 106.542 57.92ZM106.542 44.08C117.662 44.08 122.862 39.36 122.862 28.96C122.862 18.48 117.662 13.76 106.542 13.76C95.4219 13.76 90.2219 18.48 90.2219 28.96C90.2219 39.36 95.4219 44.08 106.542 44.08ZM152.265 56.96V0.959999H171.465V56.96H152.265ZM184.687 56.96V0.959999H219.887C239.327 0.959999 250.447 9.84 250.447 28.96C250.447 48.16 239.247 56.96 219.807 56.96H184.687ZM230.767 28.96C230.767 18.48 226.287 14.56 217.167 14.56H203.887V43.36H217.167C226.287 43.36 230.767 39.44 230.767 28.96Z\" fill=\"currentColor\"/>\n</svg></span><span class=\"void-auth-divider\" aria-hidden=\"true\"></span><span>" + escapeBrowserHtml(platformName) + "</span></div><section class=\"void-auth-card\" aria-labelledby=\"void-auth-title\">" + content + "</section></div></main></body></html>";
|
|
85
|
+
}
|
|
86
|
+
function browserPageLead(title, description) {
|
|
87
|
+
return "<div class=\"void-auth-lead\"><h1 id=\"void-auth-title\">" + escapeBrowserHtml(title) + "</h1><p>" + escapeBrowserHtml(description) + "</p></div>";
|
|
88
|
+
}
|
|
89
|
+
//#endregion
|
|
90
|
+
export { browserPageIdentity, browserPageLead, browserPageLogo, browserPageStatus, browserPageStyles, escapeBrowserHtml, renderBrowserPage };
|
package/dist/email-protocol.mjs
CHANGED
|
@@ -45,22 +45,17 @@ function encodeEmailEnvelope(envelope) {
|
|
|
45
45
|
}
|
|
46
46
|
async function readEmailEnvelope(stream, deadlineMs = 15e3) {
|
|
47
47
|
if (!stream) throw new Error("missing email envelope");
|
|
48
|
-
const reader = stream.getReader();
|
|
49
48
|
const limit = 10616836;
|
|
50
|
-
let bytes = /* @__PURE__ */ new Uint8Array(1024);
|
|
51
|
-
let total = 0;
|
|
52
49
|
const deadline = Date.now() + deadlineMs;
|
|
53
|
-
|
|
50
|
+
const { bytes, total } = await withReader(stream, async (reader) => {
|
|
51
|
+
let bytes = /* @__PURE__ */ new Uint8Array(1024);
|
|
52
|
+
let total = 0;
|
|
54
53
|
for (;;) {
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
})]).finally(() => {
|
|
61
|
-
if (timer !== void 0) clearTimeout(timer);
|
|
62
|
-
});
|
|
63
|
-
if (chunk.done) break;
|
|
54
|
+
const chunk = await readBeforeDeadline(reader, deadline, "email envelope timeout");
|
|
55
|
+
if (chunk.done) return {
|
|
56
|
+
bytes,
|
|
57
|
+
total
|
|
58
|
+
};
|
|
64
59
|
const nextTotal = total + chunk.value.byteLength;
|
|
65
60
|
if (nextTotal > limit) throw new Error("email envelope too large");
|
|
66
61
|
if (nextTotal > bytes.byteLength) {
|
|
@@ -73,14 +68,7 @@ async function readEmailEnvelope(stream, deadlineMs = 15e3) {
|
|
|
73
68
|
bytes.set(chunk.value, total);
|
|
74
69
|
total = nextTotal;
|
|
75
70
|
}
|
|
76
|
-
}
|
|
77
|
-
reader.cancel().catch(() => {});
|
|
78
|
-
throw error;
|
|
79
|
-
} finally {
|
|
80
|
-
try {
|
|
81
|
-
reader.releaseLock();
|
|
82
|
-
} catch {}
|
|
83
|
-
}
|
|
71
|
+
});
|
|
84
72
|
if (total < 4) throw new Error("truncated email envelope");
|
|
85
73
|
const metadataLength = new DataView(bytes.buffer).getUint32(0);
|
|
86
74
|
if (metadataLength > 131072 || total < 4 + metadataLength) throw new Error("invalid email envelope");
|
|
@@ -187,40 +175,30 @@ function encodeEmailActions(actions) {
|
|
|
187
175
|
}
|
|
188
176
|
/** Read each frame with fixed ceilings before parsing metadata or allocating a reply. */
|
|
189
177
|
async function readEmailActions(stream, deadlineMs = 15e3) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
if (chunk.done) throw new Error("truncated email response");
|
|
212
|
-
total += chunk.value.byteLength;
|
|
213
|
-
if (total > 8388608) throw new Error("email response too large");
|
|
214
|
-
stash = chunk.value;
|
|
178
|
+
return withReader(stream, async (reader) => {
|
|
179
|
+
const actions = [];
|
|
180
|
+
let stash = /* @__PURE__ */ new Uint8Array(0);
|
|
181
|
+
let total = 0;
|
|
182
|
+
const deadline = Date.now() + deadlineMs;
|
|
183
|
+
const readChunk = () => readBeforeDeadline(reader, deadline, "email response timeout");
|
|
184
|
+
async function exact(length) {
|
|
185
|
+
const result = new Uint8Array(length);
|
|
186
|
+
let offset = 0;
|
|
187
|
+
while (offset < length) {
|
|
188
|
+
if (stash.byteLength === 0) {
|
|
189
|
+
const chunk = await readChunk();
|
|
190
|
+
if (chunk.done) throw new Error("truncated email response");
|
|
191
|
+
total += chunk.value.byteLength;
|
|
192
|
+
if (total > 8388608) throw new Error("email response too large");
|
|
193
|
+
stash = chunk.value;
|
|
194
|
+
}
|
|
195
|
+
const used = Math.min(stash.byteLength, length - offset);
|
|
196
|
+
result.set(stash.subarray(0, used), offset);
|
|
197
|
+
stash = stash.subarray(used);
|
|
198
|
+
offset += used;
|
|
215
199
|
}
|
|
216
|
-
|
|
217
|
-
result.set(stash.subarray(0, used), offset);
|
|
218
|
-
stash = stash.subarray(used);
|
|
219
|
-
offset += used;
|
|
200
|
+
return result;
|
|
220
201
|
}
|
|
221
|
-
return result;
|
|
222
|
-
}
|
|
223
|
-
try {
|
|
224
202
|
for (;;) {
|
|
225
203
|
const head = await exact(5);
|
|
226
204
|
const length = new DataView(head.buffer).getUint32(0);
|
|
@@ -265,6 +243,22 @@ async function readEmailActions(stream, deadlineMs = 15e3) {
|
|
|
265
243
|
});
|
|
266
244
|
} else throw new Error("unknown email action");
|
|
267
245
|
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
async function readBeforeDeadline(reader, deadline, timeoutMessage) {
|
|
249
|
+
const remaining = deadline - Date.now();
|
|
250
|
+
if (remaining <= 0) throw new Error(timeoutMessage);
|
|
251
|
+
let timer;
|
|
252
|
+
return Promise.race([reader.read(), new Promise((_, reject) => {
|
|
253
|
+
timer = setTimeout(() => reject(new Error(timeoutMessage)), remaining);
|
|
254
|
+
})]).finally(() => {
|
|
255
|
+
if (timer !== void 0) clearTimeout(timer);
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
async function withReader(stream, read) {
|
|
259
|
+
const reader = stream.getReader();
|
|
260
|
+
try {
|
|
261
|
+
return await read(reader);
|
|
268
262
|
} catch (error) {
|
|
269
263
|
reader.cancel().catch(() => {});
|
|
270
264
|
throw error;
|
package/dist/index.mjs
CHANGED
|
@@ -411,7 +411,6 @@ function createPlatformDeploymentManifest(input) {
|
|
|
411
411
|
for (const [key, value] of Object.entries(manifest.controlPlane)) {
|
|
412
412
|
if (key === "dashboardUrl") continue;
|
|
413
413
|
if (value !== null) normalizeApplicationDomain(value);
|
|
414
|
-
if (value === "") throw new Error(`controlPlane.${key} must be a hostname or null.`);
|
|
415
414
|
}
|
|
416
415
|
if (manifest.controlPlane.dashboardUrl) {
|
|
417
416
|
const hostname = new URL(manifest.controlPlane.dashboardUrl).hostname;
|
|
@@ -480,7 +479,7 @@ function parsePlatformDeploymentManifest(value) {
|
|
|
480
479
|
},
|
|
481
480
|
capabilities,
|
|
482
481
|
...value.emailSharedZoneId !== void 0 ? { emailSharedZoneId: requiredString$1(value.emailSharedZoneId, "emailSharedZoneId") } : {},
|
|
483
|
-
...value.emailSenderDomain !== void 0 ? { emailSenderDomain:
|
|
482
|
+
...value.emailSenderDomain !== void 0 ? { emailSenderDomain: requiredString$1(value.emailSenderDomain, "emailSenderDomain") } : {},
|
|
484
483
|
controlPlane: {
|
|
485
484
|
apiHostname: readHostname("apiHostname"),
|
|
486
485
|
dashboardHostname: readHostname("dashboardHostname"),
|
|
@@ -649,16 +648,7 @@ function createPlatformResourceOwnershipMarker(input) {
|
|
|
649
648
|
function parsePlatformResourceOwnershipMarker(value) {
|
|
650
649
|
assertRecord(value, "Platform resource ownership marker");
|
|
651
650
|
if (value.schemaVersion !== 1) throw new Error(`Unsupported platform resource ownership schema version: ${String(value.schemaVersion)}.`);
|
|
652
|
-
|
|
653
|
-
return createPlatformResourceOwnershipMarker({
|
|
654
|
-
accountId: requiredString(value.accountId, "ownership accountId"),
|
|
655
|
-
installationId: requiredString(value.installationId, "ownership installationId"),
|
|
656
|
-
ownershipNonce: requiredString(value.ownershipNonce, "ownership ownershipNonce"),
|
|
657
|
-
resourceId: requiredString(value.resourceId, "ownership resourceId"),
|
|
658
|
-
resourceKey: requiredString(value.resourceKey, "ownership resourceKey"),
|
|
659
|
-
resourceKind: value.resourceKind,
|
|
660
|
-
resourceName: requiredString(value.resourceName, "ownership resourceName")
|
|
661
|
-
});
|
|
651
|
+
return createPlatformResourceOwnershipMarker(value);
|
|
662
652
|
}
|
|
663
653
|
function createPlatformInstallationManifest(input) {
|
|
664
654
|
const createdAt = assertTimestamp(input.createdAt, "createdAt");
|
|
@@ -782,7 +772,7 @@ function parsePlatformInstallationManifest(value) {
|
|
|
782
772
|
ownershipNonce: requiredString(value.ownershipNonce, "ownershipNonce"),
|
|
783
773
|
platformVersion: requiredString(value.platformVersion, "platformVersion"),
|
|
784
774
|
safetyProtocols: parseSafetyProtocols(value.safetyProtocols),
|
|
785
|
-
usageProtocolVersion: parseUsageProtocolVersion
|
|
775
|
+
usageProtocolVersion: parseUsageProtocolVersion(value.usageProtocolVersion)
|
|
786
776
|
});
|
|
787
777
|
const runtime = parsePlatformRuntimeProvenance(value.runtime);
|
|
788
778
|
let pendingDomain;
|
|
@@ -856,7 +846,7 @@ function parseAuthenticationResources(value) {
|
|
|
856
846
|
if (new Set(resources.map((resource) => `${resource.accountId}:${resource.kind}:${resource.id}`)).size !== resources.length) throw new Error("Duplicate authentication resource identity.");
|
|
857
847
|
return resources;
|
|
858
848
|
}
|
|
859
|
-
function parseUsageProtocolVersion
|
|
849
|
+
function parseUsageProtocolVersion(value) {
|
|
860
850
|
if (value === void 0 || value === 0) return 0;
|
|
861
851
|
if (value === 1) return 1;
|
|
862
852
|
if (value === 2) return 2;
|
|
@@ -977,7 +967,7 @@ function createPlatformDiscoveryDocument(input) {
|
|
|
977
967
|
const application = readPlatformApplication({ PLATFORM_APPLICATION: JSON.stringify(input.applicationRouting) });
|
|
978
968
|
if (!application.workersDev || application.baseDomain !== input.applicationDomain || application.workersDev.installationId !== input.installationId) throw new Error("Application routing must match the discovery domain and installation identity.");
|
|
979
969
|
}
|
|
980
|
-
|
|
970
|
+
const usageProtocolVersion = parseUsageProtocolVersion(input.usageProtocolVersion);
|
|
981
971
|
const authentication = input.authentication ? parseAuthentication(input.authentication) : void 0;
|
|
982
972
|
if (!authentication && input.authenticationProviders.some((provider) => provider !== "github" && provider !== "google")) throw new Error("Named login methods require authentication discovery descriptors.");
|
|
983
973
|
if (new Set(input.authenticationProviders).size !== input.authenticationProviders.length) throw new Error("Authentication provider IDs must be unique.");
|
|
@@ -996,7 +986,7 @@ function createPlatformDiscoveryDocument(input) {
|
|
|
996
986
|
platformVersion: input.platformVersion.trim(),
|
|
997
987
|
proxyUrl: normalizeOrigin(input.proxyUrl, "proxyUrl"),
|
|
998
988
|
schemaVersion: authentication ? 3 : input.applicationRouting?.workersDev ? 2 : 1,
|
|
999
|
-
usageProtocolVersion
|
|
989
|
+
usageProtocolVersion
|
|
1000
990
|
};
|
|
1001
991
|
}
|
|
1002
992
|
function parsePlatformDiscoveryDocument(value) {
|
|
@@ -1038,7 +1028,7 @@ function parsePlatformDiscoveryDocument(value) {
|
|
|
1038
1028
|
return createPlatformDiscoveryDocument({
|
|
1039
1029
|
apiUrl,
|
|
1040
1030
|
applicationDomain: string("applicationDomain"),
|
|
1041
|
-
...document.applicationRouting !== void 0 ? { applicationRouting: readPlatformApplication({ PLATFORM_APPLICATION: JSON.stringify(document.applicationRouting
|
|
1031
|
+
...document.applicationRouting !== void 0 ? { applicationRouting: readPlatformApplication({ PLATFORM_APPLICATION: JSON.stringify(document.applicationRouting) }) } : {},
|
|
1042
1032
|
authenticationProviders: providers,
|
|
1043
1033
|
...authentication ? { authentication } : {},
|
|
1044
1034
|
capabilities: parsedCapabilities,
|
|
@@ -1062,12 +1052,6 @@ function parseAuthentication(value) {
|
|
|
1062
1052
|
...authentication.setupPending === true ? { setupPending: true } : {}
|
|
1063
1053
|
};
|
|
1064
1054
|
}
|
|
1065
|
-
function parseUsageProtocolVersion(value) {
|
|
1066
|
-
if (value === void 0 || value === 0) return 0;
|
|
1067
|
-
if (value === 1) return 1;
|
|
1068
|
-
if (value === 2) return 2;
|
|
1069
|
-
throw new Error("usageProtocolVersion must be 0, 1, or 2.");
|
|
1070
|
-
}
|
|
1071
1055
|
//#endregion
|
|
1072
1056
|
//#region src/worker-config.ts
|
|
1073
1057
|
function createPlatformWorkerConfigs(input) {
|
package/dist/installer.mjs
CHANGED
|
@@ -138,14 +138,16 @@ function resolvePlatformRuntime(customRuntimeDirectory, baseDirectory = process.
|
|
|
138
138
|
}
|
|
139
139
|
const manifestPath = join(directory, "manifest.json");
|
|
140
140
|
let manifestContents;
|
|
141
|
+
let manifest;
|
|
141
142
|
try {
|
|
142
143
|
manifestContents = readFileSync(manifestPath);
|
|
144
|
+
manifest = parsePlatformRuntimeManifest(JSON.parse(manifestContents.toString("utf8")));
|
|
143
145
|
} catch (error) {
|
|
144
146
|
throw new Error(`Void Platform deployment artifacts are missing or invalid at ${manifestPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
145
147
|
}
|
|
146
148
|
return {
|
|
147
149
|
directory,
|
|
148
|
-
manifest
|
|
150
|
+
manifest,
|
|
149
151
|
manifestSha256: createHash("sha256").update(manifestContents).digest("hex"),
|
|
150
152
|
source
|
|
151
153
|
};
|