wawesome 0.21.0 → 0.22.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/LICENSE +21 -0
- package/dist/{guest-parity-W61MH7Fb.mjs → guest-parity-DA7x-8BC.mjs} +1 -1
- package/dist/guest-parity.mjs +1 -1
- package/dist/{guest-surface-D5X-IMAN.mjs → guest-surface-BwrNP2Cz.mjs} +9 -1
- package/dist/index.mjs +106 -30
- package/dist/vite.mjs +1 -1
- package/dist/vitest-setup.mjs +1 -1
- package/package.json +2 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 wawesome.io
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as shimmedGlobals, i as polyfilledGlobals, o as unsupportedGlobals, r as methodRemedy, t as declaredMethods } from "./guest-surface-BwrNP2Cz.mjs";
|
|
2
2
|
//#region ../../server/guest-surface/message-channel.js
|
|
3
3
|
const ENTANGLED = Symbol("entangled");
|
|
4
4
|
const QUEUE = Symbol("queue");
|
package/dist/guest-parity.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as applyGuestParity } from "./guest-parity-
|
|
1
|
+
import { t as applyGuestParity } from "./guest-parity-DA7x-8BC.mjs";
|
|
2
2
|
export { applyGuestParity };
|
|
@@ -130,6 +130,11 @@ var globals = [
|
|
|
130
130
|
"remedy": "the guest runs one thread and shares memory with nothing; use an ArrayBuffer"
|
|
131
131
|
}
|
|
132
132
|
];
|
|
133
|
+
var modules = [{
|
|
134
|
+
"specifiers": ["node:fs/promises", "fs/promises"],
|
|
135
|
+
"shim": "fs-promises",
|
|
136
|
+
"why": "Reads the private files the Version carries. The platform writes the module into the guest folder, so a bundler must leave the import alone."
|
|
137
|
+
}];
|
|
133
138
|
var methods = [
|
|
134
139
|
{
|
|
135
140
|
"target": "Number.prototype",
|
|
@@ -159,6 +164,9 @@ var methods = [
|
|
|
159
164
|
var methodRemedy$1 = "the engine carries no ICU, so it ignores the locale and returns an unlocalised string; format the value yourself, or bundle a formatting library and call it directly";
|
|
160
165
|
//#endregion
|
|
161
166
|
//#region src/guest-surface.ts
|
|
167
|
+
function declaredModules() {
|
|
168
|
+
return modules;
|
|
169
|
+
}
|
|
162
170
|
function declaredGlobals() {
|
|
163
171
|
return globals;
|
|
164
172
|
}
|
|
@@ -205,4 +213,4 @@ function declaredPackages(projectDir) {
|
|
|
205
213
|
});
|
|
206
214
|
}
|
|
207
215
|
//#endregion
|
|
208
|
-
export {
|
|
216
|
+
export { shimmedGlobals as a, polyfilledGlobals as i, declaredModules as n, unsupportedGlobals as o, methodRemedy as r, declaredMethods as t };
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as polyfilledGlobals, n as declaredModules, o as unsupportedGlobals, r as methodRemedy, t as declaredMethods } from "./guest-surface-BwrNP2Cz.mjs";
|
|
2
2
|
import cac from "cac";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import path from "node:path";
|
|
@@ -12,21 +12,45 @@ import { Readable } from "node:stream";
|
|
|
12
12
|
import readline from "node:readline";
|
|
13
13
|
import { confirm, select } from "@inquirer/prompts";
|
|
14
14
|
import zlib from "node:zlib";
|
|
15
|
+
//#region src/brand.ts
|
|
16
|
+
const PLAIN = "[w] wawesome";
|
|
17
|
+
const TRUECOLOR_INDIGO = "\x1B[38;2;107;124;255m";
|
|
18
|
+
const INDIGO_256 = "\x1B[38;5;105m";
|
|
19
|
+
const BOLD = "\x1B[1m";
|
|
20
|
+
const RESET = "\x1B[0m";
|
|
21
|
+
function lockup(stream = process.stdout, env = process.env) {
|
|
22
|
+
if (!stream.isTTY || env.NO_COLOR) return PLAIN;
|
|
23
|
+
const indigo = /^(truecolor|24bit)$/i.test(env.COLORTERM ?? "") ? TRUECOLOR_INDIGO : INDIGO_256;
|
|
24
|
+
const bracket = (b) => `${indigo}${BOLD}${b}${RESET}`;
|
|
25
|
+
return `${bracket("[")}${BOLD}w${RESET}${bracket("]")} ${BOLD}wawesome${RESET}`;
|
|
26
|
+
}
|
|
27
|
+
const LOCKUP_HTML = "<div style=\"margin-bottom: 24px; font: 700 20px/1 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; letter-spacing: -0.02em; color: #e8eaf0\"><span style=\"font-size: 22px; letter-spacing: -0.06em\"><span style=\"color: #6b7cff\">[</span>w<span style=\"color: #6b7cff\">]</span></span> wawesome</div>";
|
|
28
|
+
//#endregion
|
|
15
29
|
//#region src/errors.ts
|
|
16
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* A rejection carrying the gateway's own prose and, where given, its reason.
|
|
32
|
+
*
|
|
33
|
+
* The call's trace id rides in the message itself, on a line of its own, so
|
|
34
|
+
* every place that prints a refusal prints the one thing support can search by.
|
|
35
|
+
*/
|
|
17
36
|
var GatewayError = class extends Error {
|
|
18
37
|
status;
|
|
19
38
|
reason;
|
|
20
39
|
/** The raw response, for `--verbose` to print when the prose is not enough. */
|
|
21
40
|
body;
|
|
22
|
-
|
|
23
|
-
|
|
41
|
+
traceId;
|
|
42
|
+
constructor(message, status, reason, body = "", traceId) {
|
|
43
|
+
super(traceId ? `${message}\n${traceLine(traceId)}` : message);
|
|
24
44
|
this.name = "GatewayError";
|
|
25
45
|
this.status = status;
|
|
26
46
|
this.reason = reason;
|
|
27
47
|
this.body = body;
|
|
48
|
+
this.traceId = traceId;
|
|
28
49
|
}
|
|
29
50
|
};
|
|
51
|
+
function traceLine(traceId) {
|
|
52
|
+
return `Trace ID: ${traceId}`;
|
|
53
|
+
}
|
|
30
54
|
/**
|
|
31
55
|
* Read a failed response into a `GatewayError`.
|
|
32
56
|
*
|
|
@@ -36,15 +60,19 @@ var GatewayError = class extends Error {
|
|
|
36
60
|
* was doing, so callers handle it before reaching this.
|
|
37
61
|
*/
|
|
38
62
|
async function asGatewayError(res, fallback) {
|
|
39
|
-
|
|
63
|
+
const traceId = res.headers?.get("x-wawesome-trace-id") ?? void 0;
|
|
64
|
+
return rejectionOf(await res.text().catch(() => ""), res.status, fallback, traceId);
|
|
40
65
|
}
|
|
41
|
-
/**
|
|
42
|
-
|
|
66
|
+
/**
|
|
67
|
+
* The same reading, for a caller that has already taken the body off the wire.
|
|
68
|
+
* `traceId` is the header's, for a body that never made it here as JSON.
|
|
69
|
+
*/
|
|
70
|
+
function rejectionOf(body, status, fallback, traceId) {
|
|
43
71
|
try {
|
|
44
72
|
const parsed = JSON.parse(body);
|
|
45
|
-
return new GatewayError(parsed.error || fallback, status, parsed.reason, body);
|
|
73
|
+
return new GatewayError(parsed.error || fallback, status, parsed.reason, body, parsed.trace_id || traceId);
|
|
46
74
|
} catch {
|
|
47
|
-
return new GatewayError(fallback, status, void 0, body);
|
|
75
|
+
return new GatewayError(fallback, status, void 0, body, traceId);
|
|
48
76
|
}
|
|
49
77
|
}
|
|
50
78
|
/** Why the gateway refused, where what was thrown might not be a refusal at all. */
|
|
@@ -73,7 +101,12 @@ function credentialPrefix(secret) {
|
|
|
73
101
|
*/
|
|
74
102
|
function unauthorizedMessage(status, body) {
|
|
75
103
|
const secret = credentialFromEnvironment();
|
|
76
|
-
if (!secret)
|
|
104
|
+
if (!secret) {
|
|
105
|
+
const refusal = rejectionOf(body, status, `The platform refused this request (HTTP ${status}).`);
|
|
106
|
+
if (status !== 401) return refusal.message;
|
|
107
|
+
const expired = "Authentication expired. Run 'wawesome login' again.";
|
|
108
|
+
return refusal.traceId ? `${expired}\n${traceLine(refusal.traceId)}` : expired;
|
|
109
|
+
}
|
|
77
110
|
return rejectionOf(body, status, `The deploy credential ${credentialPrefix(secret)} was refused (HTTP ${status}).`).message;
|
|
78
111
|
}
|
|
79
112
|
function reportSessionCommandRefused(secret, consequence) {
|
|
@@ -847,6 +880,7 @@ async function buildHandler(entryInput, config, options) {
|
|
|
847
880
|
"worker",
|
|
848
881
|
"browser"
|
|
849
882
|
],
|
|
883
|
+
external: declaredModules().flatMap((module) => module.specifiers),
|
|
850
884
|
target: "es2022",
|
|
851
885
|
treeShaking: true,
|
|
852
886
|
minify: true,
|
|
@@ -895,7 +929,7 @@ async function buildHandler(entryInput, config, options) {
|
|
|
895
929
|
* that has to name this version — `--version`, the dependency a scaffolded
|
|
896
930
|
* project pins — reads it here, so a release bumps one file.
|
|
897
931
|
*/
|
|
898
|
-
const CLI_VERSION = "0.
|
|
932
|
+
const CLI_VERSION = "0.22.0";
|
|
899
933
|
//#endregion
|
|
900
934
|
//#region src/cli-login.ts
|
|
901
935
|
const START_PATH = "/v1/cli/login/start";
|
|
@@ -1068,13 +1102,14 @@ function listen(server, port) {
|
|
|
1068
1102
|
});
|
|
1069
1103
|
});
|
|
1070
1104
|
}
|
|
1071
|
-
const STYLE = "
|
|
1105
|
+
const STYLE = "margin: 0; padding: 50px; text-align: center; background: #0e1016; color: #9298a8; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;";
|
|
1072
1106
|
function page(title, said) {
|
|
1073
1107
|
return `<!DOCTYPE html>
|
|
1074
1108
|
<html>
|
|
1075
1109
|
<head><title>wawesome — ${escapeHtml(title.toLowerCase())}</title></head>
|
|
1076
1110
|
<body style="${STYLE}">
|
|
1077
|
-
|
|
1111
|
+
${LOCKUP_HTML}
|
|
1112
|
+
<h2 style="color: #e8eaf0">${escapeHtml(title)}</h2>
|
|
1078
1113
|
<p>${escapeHtml(said)}</p>
|
|
1079
1114
|
</body>
|
|
1080
1115
|
</html>`;
|
|
@@ -1372,7 +1407,7 @@ function storeSession({ gatewayUrl, dashboardUrl, session }) {
|
|
|
1372
1407
|
tenant_slug: session.tenant_slug,
|
|
1373
1408
|
tenant_name: session.tenant_name
|
|
1374
1409
|
});
|
|
1375
|
-
console.log(
|
|
1410
|
+
console.log(`\n${lockup()}`);
|
|
1376
1411
|
console.log("🎉 \x1B[32mLOGIN SUCCESSFUL!\x1B[0m");
|
|
1377
1412
|
console.log("======================================================");
|
|
1378
1413
|
if (session.tenant_name) console.log(`\n Workspace: ${session.tenant_name}`);
|
|
@@ -1577,8 +1612,15 @@ function planLimitAdvice(reason) {
|
|
|
1577
1612
|
//#region src/report.ts
|
|
1578
1613
|
/** Where a value sits in the deploy's summary block, so every line under one label agrees. */
|
|
1579
1614
|
const VALUE_COLUMN = " ".repeat(14);
|
|
1580
|
-
/**
|
|
1615
|
+
/**
|
|
1616
|
+
* The platform's own prose, kept inside the block it is printed in. A line
|
|
1617
|
+
* break it already carries stays one, which keeps a refusal's trace id on a
|
|
1618
|
+
* line of its own.
|
|
1619
|
+
*/
|
|
1581
1620
|
function wrapped(said) {
|
|
1621
|
+
return said.split("\n").flatMap(wrappedLine);
|
|
1622
|
+
}
|
|
1623
|
+
function wrappedLine(said) {
|
|
1582
1624
|
const width = 64;
|
|
1583
1625
|
const lines = [];
|
|
1584
1626
|
let line = "";
|
|
@@ -2019,6 +2061,13 @@ function attachedDomainLines(domain, printedBy = "deploy") {
|
|
|
2019
2061
|
`${VALUE_COLUMN}Remove 'domain' from wawesome-function.json, or deploy again`,
|
|
2020
2062
|
`${VALUE_COLUMN}once it is gone to attach it afresh.`
|
|
2021
2063
|
];
|
|
2064
|
+
if (domain.withdrawn) return [
|
|
2065
|
+
"",
|
|
2066
|
+
` Domain: \x1b[33m${hostname}: stopped, because the plan does not include custom domains\x1b[0m`,
|
|
2067
|
+
`${VALUE_COLUMN}It is still attached, and its records and certificate are kept.`,
|
|
2068
|
+
`${VALUE_COLUMN}Move to a paid plan and it answers again within the hour.`,
|
|
2069
|
+
`${VALUE_COLUMN}This app's own address still answers.`
|
|
2070
|
+
];
|
|
2022
2071
|
const legs = domain.legs ?? [];
|
|
2023
2072
|
if (legs.length > 1) return pairLines(domain, legs, printedBy);
|
|
2024
2073
|
const lines = ["", ` Domain: \x1b[36m${hostname}\x1b[0m: ${whereItGotTo(domain)}`];
|
|
@@ -2312,22 +2361,26 @@ function sha256(bytes) {
|
|
|
2312
2361
|
}
|
|
2313
2362
|
/**
|
|
2314
2363
|
* What this deploy *is*: the server bundle together with the sorted set of
|
|
2315
|
-
* asset path and content-hash pairs,
|
|
2364
|
+
* asset path and content-hash pairs, the same set for its **Private file**s
|
|
2365
|
+
* marked apart, and the **Fallback document** it declares.
|
|
2316
2366
|
*
|
|
2317
2367
|
* Computed here, before anything is uploaded, so a deploy that changed nothing
|
|
2318
2368
|
* is refused before a byte moves. Mirrors `deploy_digest` in
|
|
2319
2369
|
* `server/crates/core/src/features/assets/identity.rs` — the gateway recomputes
|
|
2320
2370
|
* it from what actually arrives, so the two have to agree exactly.
|
|
2321
2371
|
*
|
|
2322
|
-
* A deploy declaring no fallback
|
|
2323
|
-
* absence, so every digest computed before
|
|
2372
|
+
* A deploy declaring no fallback and no private files contributes nothing here
|
|
2373
|
+
* for either rather than a stated absence, so every digest computed before
|
|
2374
|
+
* they existed is unmoved.
|
|
2324
2375
|
*/
|
|
2325
2376
|
const DEPLOY_DIGEST_DOMAIN = "wawesome-deploy-v1";
|
|
2326
|
-
function deployDigest(bundle, assets, fallback) {
|
|
2377
|
+
function deployDigest(bundle, assets, fallback, privateFiles = []) {
|
|
2378
|
+
const byPath = (files) => [...files].sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
|
|
2327
2379
|
const digest = crypto.createHash("sha256");
|
|
2328
2380
|
digest.update(`${DEPLOY_DIGEST_DOMAIN}\n`);
|
|
2329
2381
|
digest.update(`${sha256(bundle)}\n`);
|
|
2330
|
-
for (const asset of
|
|
2382
|
+
for (const asset of byPath(assets)) digest.update(`${asset.path}\0${asset.content_hash}\n`);
|
|
2383
|
+
for (const file of byPath(privateFiles)) digest.update(`private\0${file.path}\0${file.content_hash}\n`);
|
|
2331
2384
|
if (fallback) digest.update(`fallback\0${fallback.path}\0${fallback.status}\n`);
|
|
2332
2385
|
return digest.digest("hex");
|
|
2333
2386
|
}
|
|
@@ -3314,6 +3367,7 @@ async function deploy(entryInput, options) {
|
|
|
3314
3367
|
const declaresSchedules = config.schedules !== void 0;
|
|
3315
3368
|
const declaresFallback = declared.fallback !== void 0;
|
|
3316
3369
|
const assets = config.assets ? collectAssets(path.resolve(config.assets)) : [];
|
|
3370
|
+
const privateFiles = config.files ? collectAssets(path.resolve(config.files)) : [];
|
|
3317
3371
|
const documents = assets.filter((asset) => isDocument(asset.path));
|
|
3318
3372
|
if (jsCode === null && documents.length === 0) {
|
|
3319
3373
|
console.error(`[wawesome] Error: Entry file '${DEFAULT_ENTRY}' not found, and this project carries no pages.`);
|
|
@@ -3322,7 +3376,10 @@ async function deploy(entryInput, options) {
|
|
|
3322
3376
|
console.error("[wawesome] \x1B[36m\"assets\"\x1B[0m at a directory holding an index.html.");
|
|
3323
3377
|
process.exit(1);
|
|
3324
3378
|
}
|
|
3325
|
-
if (assets.length > 0) await uploadAssets(creds, app, funcName, jsCode ?? "",
|
|
3379
|
+
if (assets.length > 0 || privateFiles.length > 0) await uploadAssets(creds, app, funcName, jsCode ?? "", {
|
|
3380
|
+
assets,
|
|
3381
|
+
privateFiles
|
|
3382
|
+
}, declared, isVerbose, declaresSchedules);
|
|
3326
3383
|
console.log(`[wawesome] Uploading code for ${app}/${funcName}...`);
|
|
3327
3384
|
const uploadUrl = `${creds.gateway_url}/v1/apps/${encodeURIComponent(app)}/functions/${encodeURIComponent(funcName)}/code`;
|
|
3328
3385
|
if (isVerbose) console.log(`[wawesome:verbose] POST ${uploadUrl}`);
|
|
@@ -3330,7 +3387,7 @@ async function deploy(entryInput, options) {
|
|
|
3330
3387
|
...declaredFields(declared),
|
|
3331
3388
|
...declared.message ? { message: declared.message } : {}
|
|
3332
3389
|
};
|
|
3333
|
-
const uploadRes = assets.length > 0 || declaresSchedules || declaresFallback || Object.keys(declaredOnTheWire).length > 0 || jsCode === null ? await authorizedFetch(uploadUrl, {
|
|
3390
|
+
const uploadRes = assets.length > 0 || privateFiles.length > 0 || declaresSchedules || declaresFallback || Object.keys(declaredOnTheWire).length > 0 || jsCode === null ? await authorizedFetch(uploadUrl, {
|
|
3334
3391
|
method: "POST",
|
|
3335
3392
|
headers: {
|
|
3336
3393
|
Authorization: `Bearer ${creds.tenant_jwt}`,
|
|
@@ -3339,6 +3396,7 @@ async function deploy(entryInput, options) {
|
|
|
3339
3396
|
body: JSON.stringify({
|
|
3340
3397
|
...jsCode !== null ? { code: jsCode } : {},
|
|
3341
3398
|
...assets.length > 0 ? { assets: manifestOf(assets) } : {},
|
|
3399
|
+
...privateFiles.length > 0 ? { files: manifestOf(privateFiles) } : {},
|
|
3342
3400
|
...declaresSchedules ? { schedules: config.schedules } : {},
|
|
3343
3401
|
...declaresFallback ? { fallback: declared.fallback } : {},
|
|
3344
3402
|
...declaredOnTheWire
|
|
@@ -3446,6 +3504,7 @@ async function deploy(entryInput, options) {
|
|
|
3446
3504
|
if (version !== void 0) console.log(` Version: ${version}${nothingBuilt ? " (already live, nothing promoted)" : ""}`);
|
|
3447
3505
|
for (const line of handlerLines(bundlePath)) console.log(line);
|
|
3448
3506
|
if (assets.length > 0) console.log(` Assets: ${assets.length}${pageCount(documents.length)}`);
|
|
3507
|
+
if (privateFiles.length > 0) console.log(` Private: ${privateFiles.length}`);
|
|
3449
3508
|
console.log(` Visibility: ${visibility}`);
|
|
3450
3509
|
if (schedules.length > 0) {
|
|
3451
3510
|
console.log("");
|
|
@@ -3495,7 +3554,7 @@ function pageCount(pages) {
|
|
|
3495
3554
|
* The identity of the whole deploy goes with the question, so a redeploy that
|
|
3496
3555
|
* changed nothing at all is refused here — before a byte of it has moved.
|
|
3497
3556
|
*/
|
|
3498
|
-
async function uploadAssets(creds, app, funcName, bundle, assets, declared, isVerbose, continueWhenUnchanged) {
|
|
3557
|
+
async function uploadAssets(creds, app, funcName, bundle, { assets, privateFiles }, declared, isVerbose, continueWhenUnchanged) {
|
|
3499
3558
|
const manifestRes = await authorizedFetch(`${creds.gateway_url}/v1/apps/${encodeURIComponent(app)}/functions/${encodeURIComponent(funcName)}/assets/manifest`, {
|
|
3500
3559
|
method: "POST",
|
|
3501
3560
|
headers: {
|
|
@@ -3503,8 +3562,9 @@ async function uploadAssets(creds, app, funcName, bundle, assets, declared, isVe
|
|
|
3503
3562
|
"Content-Type": "application/json"
|
|
3504
3563
|
},
|
|
3505
3564
|
body: JSON.stringify({
|
|
3506
|
-
deploy_digest: deployDigest(Buffer.from(bundle, "utf-8"), assets, declared.fallback),
|
|
3565
|
+
deploy_digest: deployDigest(Buffer.from(bundle, "utf-8"), assets, declared.fallback, privateFiles),
|
|
3507
3566
|
assets: manifestOf(assets),
|
|
3567
|
+
...privateFiles.length > 0 ? { files: manifestOf(privateFiles) } : {},
|
|
3508
3568
|
...declaredFields(declared)
|
|
3509
3569
|
})
|
|
3510
3570
|
});
|
|
@@ -3531,12 +3591,13 @@ async function uploadAssets(creds, app, funcName, bundle, assets, declared, isVe
|
|
|
3531
3591
|
process.exit(1);
|
|
3532
3592
|
}
|
|
3533
3593
|
const { missing = [] } = await manifestRes.json();
|
|
3534
|
-
const
|
|
3594
|
+
const carried = [...assets, ...privateFiles];
|
|
3595
|
+
const toUpload = [...new Map(carried.filter((file) => missing.includes(file.content_hash)).map((file) => [file.content_hash, file])).values()];
|
|
3535
3596
|
if (toUpload.length === 0) {
|
|
3536
|
-
console.log(`[wawesome] ✅ ${
|
|
3597
|
+
console.log(`[wawesome] ✅ ${carried.length} file(s) already on the platform, nothing to upload.`);
|
|
3537
3598
|
return;
|
|
3538
3599
|
}
|
|
3539
|
-
console.log(`[wawesome] Uploading ${toUpload.length} of ${
|
|
3600
|
+
console.log(`[wawesome] Uploading ${toUpload.length} of ${carried.length} file(s)...`);
|
|
3540
3601
|
for (const asset of toUpload) {
|
|
3541
3602
|
if (isVerbose) console.log(`[wawesome:verbose] PUT ${asset.path} (${asset.size_bytes} bytes)`);
|
|
3542
3603
|
const res = await authorizedFetch(`${creds.gateway_url}/v1/assets/${asset.content_hash}`, () => ({
|
|
@@ -3559,7 +3620,7 @@ async function uploadAssets(creds, app, funcName, bundle, assets, declared, isVe
|
|
|
3559
3620
|
process.exit(1);
|
|
3560
3621
|
}
|
|
3561
3622
|
}
|
|
3562
|
-
console.log(`[wawesome] ✅ ${toUpload.length}
|
|
3623
|
+
console.log(`[wawesome] ✅ ${toUpload.length} file(s) uploaded.`);
|
|
3563
3624
|
}
|
|
3564
3625
|
//#endregion
|
|
3565
3626
|
//#region src/opens-host.ts
|
|
@@ -4423,7 +4484,8 @@ async function promptForDeclaredEnv(session, declared) {
|
|
|
4423
4484
|
console.log(` \x1b[1m${variable.key}\x1b[0m \x1b[90m(${flags.join(", ")})\x1b[0m`);
|
|
4424
4485
|
console.log(` ${variable.description}`);
|
|
4425
4486
|
console.log(` \x1b[90mWhere to find it: ${variable.where_to_find}\x1b[0m`);
|
|
4426
|
-
const
|
|
4487
|
+
const later = variable.required ? " (leave blank to set it after the deploy)" : "";
|
|
4488
|
+
const value = await session.ask(` ${variable.key}?${later}`, "");
|
|
4427
4489
|
console.log("");
|
|
4428
4490
|
answers.push({
|
|
4429
4491
|
declared: variable,
|
|
@@ -5096,6 +5158,20 @@ async function fetchInvocationLogBody(gatewayUrl, tenantJwt, invocationId, isVer
|
|
|
5096
5158
|
}
|
|
5097
5159
|
const body = await res.text();
|
|
5098
5160
|
process.stdout.write(body.endsWith("\n") ? body : body + "\n");
|
|
5161
|
+
const remediation = await fetchRemediation(gatewayUrl, tenantJwt, invocationId);
|
|
5162
|
+
if (remediation?.cause === "egress-blocked") console.log(`[wawesome] An outbound call was blocked (egress-blocked). Open its host under Egress: ${remediation.dashboard_url}`);
|
|
5163
|
+
}
|
|
5164
|
+
async function fetchRemediation(gatewayUrl, tenantJwt, invocationId) {
|
|
5165
|
+
try {
|
|
5166
|
+
const res = await authorizedFetch(`${gatewayUrl}/v1/invocations/${encodeURIComponent(invocationId)}`, {
|
|
5167
|
+
method: "GET",
|
|
5168
|
+
headers: { Authorization: `Bearer ${tenantJwt}` }
|
|
5169
|
+
});
|
|
5170
|
+
if (!res.ok) return void 0;
|
|
5171
|
+
return (await res.json()).remediation;
|
|
5172
|
+
} catch {
|
|
5173
|
+
return;
|
|
5174
|
+
}
|
|
5099
5175
|
}
|
|
5100
5176
|
/**
|
|
5101
5177
|
* List recent invocations for a function.
|
|
@@ -6768,7 +6844,7 @@ cli.command("cron pause <schedule>", "Pause a schedule by name").option("-r, --r
|
|
|
6768
6844
|
cli.command("cron resume <schedule>", "Resume a paused schedule").option("-f, --function <function>", "Function name override").option("-a, --app <app>", "App slug override").option("-v, --verbose", "Enable verbose debug output").action((schedule, options) => resumeScheduleCommand(schedule, void 0, options));
|
|
6769
6845
|
cli.command("cron history [target]", "Read background run history").alias("cron runs").option("-s, --state <state>", "Filter run history by state (pending, running, dispatched, skipped, missed, cancelled, lost, failed)").option("--status <status>", "Alias for --state").option("-l, --limit <limit>", "Limit number of history rows (default: 50)").option("-a, --app <app>", "App slug override").option("-v, --verbose", "Enable verbose debug output").action((target, options) => runHistoryCommand(target, options));
|
|
6770
6846
|
cli.command("schedules [action] [target]", "Alias for 'cron'").option("-a, --app <app>", "App slug override").option("-v, --verbose", "Enable verbose debug output").action((action, target, options) => cronCommand(action, target, void 0, options));
|
|
6771
|
-
cli.help();
|
|
6847
|
+
cli.help((sections) => [{ body: `${lockup()} ${CLI_VERSION}` }, ...sections.slice(1)]);
|
|
6772
6848
|
cli.version(CLI_VERSION);
|
|
6773
6849
|
cli.parse();
|
|
6774
6850
|
//#endregion
|
package/dist/vite.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as polyfilledGlobals, o as unsupportedGlobals, r as methodRemedy, t as declaredMethods } from "./guest-surface-BwrNP2Cz.mjs";
|
|
2
2
|
import fs from "node:fs";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
//#region src/vite.ts
|
package/dist/vitest-setup.mjs
CHANGED
package/package.json
CHANGED