run402 4.129.0 → 4.130.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/lib/assets.mjs +36 -18
- package/lib/auth.mjs +48 -1
- package/lib/command-manifest.mjs +2 -1
- package/lib/deploy-v2.mjs +15 -15
- package/lib/dev.mjs +28 -7
- package/package.json +1 -1
- package/sdk/dist/errors.d.ts +8 -0
- package/sdk/dist/errors.d.ts.map +1 -1
- package/sdk/dist/errors.js +16 -0
- package/sdk/dist/errors.js.map +1 -1
- package/sdk/dist/namespaces/assets.d.ts +7 -1
- package/sdk/dist/namespaces/assets.d.ts.map +1 -1
- package/sdk/dist/namespaces/assets.js +39 -1
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/assets.types.d.ts +37 -0
- package/sdk/dist/namespaces/assets.types.d.ts.map +1 -1
- package/sdk/dist/namespaces/assets.types.js +2 -0
- package/sdk/dist/namespaces/assets.types.js.map +1 -1
- package/sdk/dist/namespaces/auth.d.ts +20 -0
- package/sdk/dist/namespaces/auth.d.ts.map +1 -1
- package/sdk/dist/namespaces/auth.js +20 -0
- package/sdk/dist/namespaces/auth.js.map +1 -1
- package/sdk/dist/namespaces/deploy.d.ts.map +1 -1
- package/sdk/dist/namespaces/deploy.js +92 -16
- package/sdk/dist/namespaces/deploy.js.map +1 -1
- package/sdk/dist/node/paid-fetch.js +2 -2
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/vault-degraded-read.d.ts.map +1 -1
- package/sdk/dist/node/vault-degraded-read.js +4 -8
- package/sdk/dist/node/vault-degraded-read.js.map +1 -1
- package/sdk/dist/scoped.d.ts +4 -2
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +6 -0
- package/sdk/dist/scoped.js.map +1 -1
- package/vault-surface.json +1 -1
|
@@ -24,7 +24,7 @@ import { isGrantKeyCredentials } from "../grant-key-credentials.js";
|
|
|
24
24
|
import { isKnownBinaryContent, isUtf8StringSource } from "../validation.js";
|
|
25
25
|
import { assertCiDeployableSpec } from "./ci.js";
|
|
26
26
|
import { ROUTE_PRICING_NETWORKS, ROUTE_HTTP_METHODS, isModernPlanMigrationDiff, normalizeDeployResolveRequest, } from "./deploy.types.js";
|
|
27
|
-
import { ApiError, LocalError,
|
|
27
|
+
import { ApiError, LocalError, PaymentRequired, Run402DeployError, Unauthorized, isNoResponseError, isRun402Error, isTransferFreezeError, } from "../errors.js";
|
|
28
28
|
import { assertAssetMetadata, assertExifPolicy, } from "./assets-validation.js";
|
|
29
29
|
import { withSiteRemovalSummaries } from "./site-removal-summary.js";
|
|
30
30
|
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
@@ -85,18 +85,22 @@ const STATIC_FUNCTION_LIMITS_BY_TIER = {
|
|
|
85
85
|
prototype: {
|
|
86
86
|
maxTimeoutSeconds: 10,
|
|
87
87
|
maxMemoryMb: 128,
|
|
88
|
+
maxSsrMemoryMb: 128,
|
|
88
89
|
maxScheduledFunctions: 1,
|
|
89
90
|
minCronIntervalMinutes: 15,
|
|
90
91
|
},
|
|
91
92
|
hobby: {
|
|
92
93
|
maxTimeoutSeconds: 30,
|
|
93
94
|
maxMemoryMb: 256,
|
|
95
|
+
maxSsrMemoryMb: 256,
|
|
94
96
|
maxScheduledFunctions: 3,
|
|
95
97
|
minCronIntervalMinutes: 5,
|
|
96
98
|
},
|
|
97
99
|
team: {
|
|
98
100
|
maxTimeoutSeconds: 60,
|
|
99
101
|
maxMemoryMb: 512,
|
|
102
|
+
// An SSR-class function (the Astro `ssr` function) may use one vCPU.
|
|
103
|
+
maxSsrMemoryMb: 1769,
|
|
100
104
|
maxScheduledFunctions: 10,
|
|
101
105
|
minCronIntervalMinutes: 1,
|
|
102
106
|
},
|
|
@@ -1353,12 +1357,19 @@ async function preflightTierFunctionLimits(client, spec, ciCredentials) {
|
|
|
1353
1357
|
});
|
|
1354
1358
|
}
|
|
1355
1359
|
const memory = entry.fn.config?.memoryMb;
|
|
1360
|
+
// An SSR-class function has its own cap. With no class declared the
|
|
1361
|
+
// function keeps its stored one, which only the gateway knows.
|
|
1362
|
+
const memoryLimit = entry.fn.class === "ssr"
|
|
1363
|
+
? limits.maxSsrMemoryMb ?? limits.maxMemoryMb
|
|
1364
|
+
: entry.fn.class === undefined
|
|
1365
|
+
? largerLimit(limits.maxMemoryMb, limits.maxSsrMemoryMb)
|
|
1366
|
+
: limits.maxMemoryMb;
|
|
1356
1367
|
if (memory !== undefined &&
|
|
1357
|
-
|
|
1358
|
-
memory >
|
|
1359
|
-
throw tierLimitError(`Function ${entry.name} memoryMb ${memory} exceeds the ${limits.tier} tier maximum of ${
|
|
1360
|
-
tier_max:
|
|
1361
|
-
max_function_memory_mb:
|
|
1368
|
+
memoryLimit &&
|
|
1369
|
+
memory > memoryLimit.value) {
|
|
1370
|
+
throw tierLimitError(`Function ${entry.name} memoryMb ${memory} exceeds the ${limits.tier} tier maximum of ${memoryLimit.value}.`, `${entry.fieldPrefix}.config.memoryMb`, memory, limits, memoryLimit, {
|
|
1371
|
+
tier_max: memoryLimit.value,
|
|
1372
|
+
max_function_memory_mb: memoryLimit.value,
|
|
1362
1373
|
});
|
|
1363
1374
|
}
|
|
1364
1375
|
for (const trigger of scheduleTriggersForFunction(entry.fn)) {
|
|
@@ -1387,6 +1398,13 @@ async function preflightTierFunctionLimits(client, spec, ciCredentials) {
|
|
|
1387
1398
|
}
|
|
1388
1399
|
}
|
|
1389
1400
|
}
|
|
1401
|
+
function largerLimit(a, b) {
|
|
1402
|
+
if (!a)
|
|
1403
|
+
return b;
|
|
1404
|
+
if (!b)
|
|
1405
|
+
return a;
|
|
1406
|
+
return b.value > a.value ? b : a;
|
|
1407
|
+
}
|
|
1390
1408
|
function hasFunctionTierPreflightInputs(functions) {
|
|
1391
1409
|
if (!functions)
|
|
1392
1410
|
return false;
|
|
@@ -1434,6 +1452,9 @@ async function readTierFunctionLimits(client) {
|
|
|
1434
1452
|
"memory_mb_max",
|
|
1435
1453
|
"function_memory_mb_max",
|
|
1436
1454
|
], fallback?.maxMemoryMb);
|
|
1455
|
+
// tier status names no SSR memory cap, so it comes from the static table.
|
|
1456
|
+
if (fallback)
|
|
1457
|
+
limits.maxSsrMemoryMb = { value: fallback.maxSsrMemoryMb, source: "local_static_fallback" };
|
|
1437
1458
|
limits.maxScheduledFunctions = tierStatusLimitOrFallback(status, [
|
|
1438
1459
|
"max_scheduled_functions",
|
|
1439
1460
|
"scheduled_functions_limit",
|
|
@@ -1895,7 +1916,7 @@ async function requestWithTransientRetry(send) {
|
|
|
1895
1916
|
function isTransientGatewayFailure(err) {
|
|
1896
1917
|
if (!isRun402Error(err))
|
|
1897
1918
|
return false;
|
|
1898
|
-
if (err
|
|
1919
|
+
if (isNoResponseError(err))
|
|
1899
1920
|
return true;
|
|
1900
1921
|
return err.status === 502 || err.status === 503 || err.status === 504;
|
|
1901
1922
|
}
|
|
@@ -4544,15 +4565,8 @@ function translateDeployError(err, phase, planId, operationId) {
|
|
|
4544
4565
|
context: err.context,
|
|
4545
4566
|
});
|
|
4546
4567
|
}
|
|
4547
|
-
if (err
|
|
4548
|
-
return
|
|
4549
|
-
code: "NETWORK_ERROR",
|
|
4550
|
-
phase,
|
|
4551
|
-
retryable: true,
|
|
4552
|
-
operationId,
|
|
4553
|
-
planId,
|
|
4554
|
-
context: phase,
|
|
4555
|
-
});
|
|
4568
|
+
if (isNoResponseError(err)) {
|
|
4569
|
+
return noResponseDeployError(err, phase, planId, operationId);
|
|
4556
4570
|
}
|
|
4557
4571
|
// Re-throw other Run402Error subclasses (PaymentRequired, Unauthorized, etc.)
|
|
4558
4572
|
// as-is — the consumer handles them at a different layer than
|
|
@@ -4579,6 +4593,68 @@ function translateDeployError(err, phase, planId, operationId) {
|
|
|
4579
4593
|
context: phase,
|
|
4580
4594
|
});
|
|
4581
4595
|
}
|
|
4596
|
+
/**
|
|
4597
|
+
* A deploy request that got no response: the connection failed or the client
|
|
4598
|
+
* gave up waiting (Node's fetch stops waiting for response headers after
|
|
4599
|
+
* 300 s). For a commit that is not a failed deploy: the gateway may still be
|
|
4600
|
+
* running the operation, and committing the plan again is safe (a plan commits
|
|
4601
|
+
* once), so the error says so and points at the operation.
|
|
4602
|
+
*/
|
|
4603
|
+
function noResponseDeployError(err, phase, planId, operationId) {
|
|
4604
|
+
const transportCode = noResponseTransportCode(err);
|
|
4605
|
+
const cause = transportCode ? ` (${transportCode})` : "";
|
|
4606
|
+
const isCommit = phase === "commit";
|
|
4607
|
+
const message = isCommit
|
|
4608
|
+
? `The deploy commit got no response from the API${cause}. The deploy may still be running on the gateway${operationId ? ` as operation ${operationId}` : ""}; nothing failed that is known. Check the operation, or commit the same plan again: a plan commits once, so a repeat follows the running deploy.`
|
|
4609
|
+
: `The deploy request (${phase}) got no response from the API${cause}. Repeating it is safe.`;
|
|
4610
|
+
const nextActions = [];
|
|
4611
|
+
if (operationId) {
|
|
4612
|
+
nextActions.push({
|
|
4613
|
+
type: "poll",
|
|
4614
|
+
method: "GET",
|
|
4615
|
+
path: `/apply/v1/operations/${operationId}`,
|
|
4616
|
+
command: `run402 deploy status ${operationId}`,
|
|
4617
|
+
safe_to_auto_execute: true,
|
|
4618
|
+
why: "Read the operation to learn whether the deploy is still running, finished, or failed.",
|
|
4619
|
+
});
|
|
4620
|
+
}
|
|
4621
|
+
nextActions.push({
|
|
4622
|
+
type: "retry",
|
|
4623
|
+
safe_to_auto_execute: true,
|
|
4624
|
+
why: isCommit
|
|
4625
|
+
? "Committing the same plan again cannot run the deploy twice: it attaches to the running operation or returns its stored result."
|
|
4626
|
+
: "The request got no response; repeating it is safe.",
|
|
4627
|
+
});
|
|
4628
|
+
return new Run402DeployError(message, {
|
|
4629
|
+
code: "NETWORK_ERROR",
|
|
4630
|
+
phase,
|
|
4631
|
+
retryable: true,
|
|
4632
|
+
operationId,
|
|
4633
|
+
planId,
|
|
4634
|
+
context: phase,
|
|
4635
|
+
body: {
|
|
4636
|
+
code: "NETWORK_ERROR",
|
|
4637
|
+
category: "network",
|
|
4638
|
+
retryable: true,
|
|
4639
|
+
safe_to_retry: true,
|
|
4640
|
+
mutation_state: isCommit ? "unknown" : "none",
|
|
4641
|
+
details: {
|
|
4642
|
+
...(transportCode ? { transport_code: transportCode } : {}),
|
|
4643
|
+
...(operationId ? { operation_id: operationId } : {}),
|
|
4644
|
+
},
|
|
4645
|
+
next_actions: nextActions,
|
|
4646
|
+
},
|
|
4647
|
+
});
|
|
4648
|
+
}
|
|
4649
|
+
function noResponseTransportCode(err) {
|
|
4650
|
+
const details = err.details;
|
|
4651
|
+
if (details && typeof details === "object" && !Array.isArray(details)) {
|
|
4652
|
+
const code = details.transport_code;
|
|
4653
|
+
if (typeof code === "string")
|
|
4654
|
+
return code;
|
|
4655
|
+
}
|
|
4656
|
+
return null;
|
|
4657
|
+
}
|
|
4582
4658
|
function extractGatewayError(body) {
|
|
4583
4659
|
// Gateway returns the error in any of:
|
|
4584
4660
|
// { error: { code, message?, phase?, ... } } — nested
|