deepspace 0.27.0 → 0.27.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/CHANGELOG.md +11 -0
- package/dist/{chunk-SF6GNPYL.js → chunk-CRIG6LPA.js} +2 -2
- package/dist/{chunk-SF6GNPYL.js.map → chunk-CRIG6LPA.js.map} +1 -1
- package/dist/cli.js +280 -222
- package/dist/cli.js.map +1 -1
- package/dist/documentation-client-core.js +1 -1
- package/dist/documentation-default-renderer.cjs +1 -1
- package/dist/documentation-react.js +1 -1
- package/dist/documentation-runtime.js +1 -1
- package/dist/documentation-server-core.js +1 -1
- package/dist/documentation.d.ts +0 -1
- package/dist/documentation.js +41 -21
- package/dist/documentation.js.map +1 -1
- package/dist/feature-installer.js +27 -61
- package/dist/feature-installer.js.map +1 -1
- package/dist/index.d.ts +6 -55
- package/dist/index.js +4 -20
- package/dist/index.js.map +1 -1
- package/dist/schema.js.map +1 -1
- package/dist/server.d.ts +5 -38
- package/dist/server.js +3 -57
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +7 -80
- package/dist/worker.js +4 -62
- package/dist/worker.js.map +1 -1
- package/features/admin-page/feature.json +0 -1
- package/features/ai-chat/feature.json +0 -1
- package/features/canvas/feature.json +0 -1
- package/features/cron/feature.json +0 -1
- package/features/documents/feature.json +0 -1
- package/features/file-attachments/feature.json +0 -1
- package/features/file-manager/feature.json +0 -1
- package/features/integration-test/feature.json +0 -1
- package/features/items/feature.json +0 -1
- package/features/kanban/feature.json +0 -1
- package/features/landing/feature.json +0 -1
- package/features/leaderboard/feature.json +0 -1
- package/features/messaging/feature.json +0 -1
- package/features/search-bar/feature.json +0 -1
- package/features/tasks/feature.json +0 -1
- package/features/testing/feature.json +0 -1
- package/features/topbar/feature.json +1 -4
- package/features/tree/feature.json +1 -4
- package/package.json +1 -1
- package/features/presence-test/feature.json +0 -22
- package/features/presence-test/src/PresenceTestPage.tsx +0 -120
package/dist/cli.js
CHANGED
|
@@ -1946,6 +1946,15 @@ async function warnIfPhantomApp(deployUrl, token, appId, explicit) {
|
|
|
1946
1946
|
}
|
|
1947
1947
|
|
|
1948
1948
|
// src/cli/lib/app-tokens.ts
|
|
1949
|
+
async function refusalDetail(response) {
|
|
1950
|
+
const text2 = await response.text().catch(() => "");
|
|
1951
|
+
try {
|
|
1952
|
+
const body = JSON.parse(text2);
|
|
1953
|
+
return { detail: body.error ?? text2, code: body.code };
|
|
1954
|
+
} catch {
|
|
1955
|
+
return { detail: text2 };
|
|
1956
|
+
}
|
|
1957
|
+
}
|
|
1949
1958
|
async function fetchPublicKey(authUrl) {
|
|
1950
1959
|
const response = await fetch(`${authUrl}/api/auth/jwks`);
|
|
1951
1960
|
if (!response.ok) {
|
|
@@ -1965,8 +1974,13 @@ async function mintAppOwnerJwt(authUrl, callerJwt, appId) {
|
|
|
1965
1974
|
body: JSON.stringify({ appId })
|
|
1966
1975
|
});
|
|
1967
1976
|
if (!response.ok) {
|
|
1968
|
-
const detail = await response
|
|
1969
|
-
throw new
|
|
1977
|
+
const { detail, code } = await refusalDetail(response);
|
|
1978
|
+
throw new ApiError(
|
|
1979
|
+
`Failed to mint APP_OWNER_JWT (${response.status}): ${detail}`,
|
|
1980
|
+
response.status,
|
|
1981
|
+
code,
|
|
1982
|
+
"/api/auth/mint-app-token"
|
|
1983
|
+
);
|
|
1970
1984
|
}
|
|
1971
1985
|
const body = await response.json();
|
|
1972
1986
|
if (!body.token) {
|
|
@@ -1982,10 +1996,37 @@ async function fetchAppIdentityToken(deployUrl, callerJwt, appId) {
|
|
|
1982
1996
|
headers: { Authorization: `Bearer ${callerJwt}` }
|
|
1983
1997
|
}
|
|
1984
1998
|
);
|
|
1985
|
-
if (response.status === 404)
|
|
1999
|
+
if (response.status === 404) {
|
|
2000
|
+
const { detail, code } = await refusalDetail(response);
|
|
2001
|
+
if (code === "app_not_found") {
|
|
2002
|
+
throw new ApiError(
|
|
2003
|
+
// No executable command in this prose: this lib cannot know the
|
|
2004
|
+
// wrangler env, and a bare `app init` under --env would target the
|
|
2005
|
+
// TOP-LEVEL [vars] slot. dev/test/deploy attach the env-aware
|
|
2006
|
+
// remedy as a structured action; surfaces without an action channel
|
|
2007
|
+
// (secrets pull among them) fall back to the
|
|
2008
|
+
// app_not_found hint (check the id / `deepspace app list`).
|
|
2009
|
+
`App ${appId} is not registered on this platform \u2014 DEEPSPACE_APP_ID may belong to a different environment (a staging id does not exist on prod, and vice versa), or the app was never initialized here.`,
|
|
2010
|
+
404,
|
|
2011
|
+
code,
|
|
2012
|
+
`/api/apps/${appId}/identity-token`
|
|
2013
|
+
);
|
|
2014
|
+
}
|
|
2015
|
+
throw new ApiError(
|
|
2016
|
+
`Failed to fetch APP_IDENTITY_TOKEN (404): ${detail || "no such route"} \u2014 is DEEPSPACE_DEPLOY_URL pointing at the right deploy service?`,
|
|
2017
|
+
404,
|
|
2018
|
+
code,
|
|
2019
|
+
`/api/apps/${appId}/identity-token`
|
|
2020
|
+
);
|
|
2021
|
+
}
|
|
1986
2022
|
if (!response.ok) {
|
|
1987
|
-
const detail = await response
|
|
1988
|
-
throw new
|
|
2023
|
+
const { detail, code } = await refusalDetail(response);
|
|
2024
|
+
throw new ApiError(
|
|
2025
|
+
`Failed to fetch APP_IDENTITY_TOKEN (${response.status}): ${detail}`,
|
|
2026
|
+
response.status,
|
|
2027
|
+
code,
|
|
2028
|
+
`/api/apps/${appId}/identity-token`
|
|
2029
|
+
);
|
|
1989
2030
|
}
|
|
1990
2031
|
const body = await response.json();
|
|
1991
2032
|
if (!body.token) {
|
|
@@ -2006,11 +2047,29 @@ function requireAppIdFor(appDir, wranglerEnv) {
|
|
|
2006
2047
|
throw appTargetMissingError(appDir, wranglerEnv);
|
|
2007
2048
|
}
|
|
2008
2049
|
async function writeDevVars(appDir, ownerId, callerJwt, wranglerEnv, opts = {}) {
|
|
2009
|
-
const urls =
|
|
2050
|
+
const urls = effectivePlatformUrls();
|
|
2010
2051
|
const publicKey = await fetchPublicKey(urls.auth);
|
|
2011
2052
|
const appId = opts.appId ?? requireAppIdFor(appDir, wranglerEnv);
|
|
2012
|
-
|
|
2013
|
-
|
|
2053
|
+
let appOwnerJwt;
|
|
2054
|
+
let appIdentityToken;
|
|
2055
|
+
try {
|
|
2056
|
+
appOwnerJwt = await mintAppOwnerJwt(urls.auth, callerJwt, appId);
|
|
2057
|
+
appIdentityToken = await fetchAppIdentityToken(urls.deploy, callerJwt, appId);
|
|
2058
|
+
} catch (err) {
|
|
2059
|
+
if (err instanceof ApiError && err.code === "app_not_found") {
|
|
2060
|
+
throw new Refusal(err.message, "app_not_found", {
|
|
2061
|
+
actionRequired: true,
|
|
2062
|
+
action: {
|
|
2063
|
+
cwd: appDir,
|
|
2064
|
+
// Env-scoped like every upstream step: a bare `app init` reads and
|
|
2065
|
+
// writes the TOP-LEVEL [vars] slot — under --env it would either
|
|
2066
|
+
// no-op on the prod id or mint a new app into the wrong scope.
|
|
2067
|
+
argv: ["deepspace", "app", "init", ...wranglerEnv ? ["--env", wranglerEnv] : []]
|
|
2068
|
+
}
|
|
2069
|
+
});
|
|
2070
|
+
}
|
|
2071
|
+
throw err;
|
|
2072
|
+
}
|
|
2014
2073
|
const sdkVars = [
|
|
2015
2074
|
`AUTH_JWT_PUBLIC_KEY="${publicKey}"`,
|
|
2016
2075
|
`AUTH_JWT_ISSUER=${urls.auth}/api/auth`,
|
|
@@ -2019,7 +2078,7 @@ async function writeDevVars(appDir, ownerId, callerJwt, wranglerEnv, opts = {})
|
|
|
2019
2078
|
`PLATFORM_WORKER_URL=${urls.platform}`,
|
|
2020
2079
|
`OWNER_USER_ID=${ownerId}`,
|
|
2021
2080
|
`APP_OWNER_JWT=${appOwnerJwt}`,
|
|
2022
|
-
|
|
2081
|
+
`APP_IDENTITY_TOKEN=${appIdentityToken}`,
|
|
2023
2082
|
`ALLOW_DEBUG_ROUTES=true`
|
|
2024
2083
|
].join("\n");
|
|
2025
2084
|
const devVarsPath = devVarsPathFor(appDir);
|
|
@@ -3238,22 +3297,24 @@ var dev_default = defineDeepspaceCommand({
|
|
|
3238
3297
|
);
|
|
3239
3298
|
const readiness = new AbortController();
|
|
3240
3299
|
if (args.json) {
|
|
3241
|
-
void waitForPortListening(port, host, READINESS_TIMEOUT_MS, readiness.signal).then(
|
|
3242
|
-
|
|
3243
|
-
|
|
3244
|
-
|
|
3245
|
-
|
|
3246
|
-
ok:
|
|
3247
|
-
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3300
|
+
void waitForPortListening(port, host, READINESS_TIMEOUT_MS, readiness.signal).then(
|
|
3301
|
+
(ready) => {
|
|
3302
|
+
if (readiness.signal.aborted) return;
|
|
3303
|
+
console.log(
|
|
3304
|
+
JSON.stringify(
|
|
3305
|
+
ready ? { ok: true, ready: true, url, port, host, appDir } : {
|
|
3306
|
+
ok: false,
|
|
3307
|
+
code: "dev_server_not_ready",
|
|
3308
|
+
error: `The dev server did not answer on ${url} within ${READINESS_TIMEOUT_MS / 1e3}s.`,
|
|
3309
|
+
url,
|
|
3310
|
+
port,
|
|
3311
|
+
host,
|
|
3312
|
+
appDir
|
|
3313
|
+
}
|
|
3314
|
+
)
|
|
3315
|
+
);
|
|
3316
|
+
}
|
|
3317
|
+
);
|
|
3257
3318
|
}
|
|
3258
3319
|
let stopping = false;
|
|
3259
3320
|
const stop = () => {
|
|
@@ -5446,7 +5507,7 @@ function createDeployOutput(json) {
|
|
|
5446
5507
|
}
|
|
5447
5508
|
|
|
5448
5509
|
// src/cli/commands/deploy/request.ts
|
|
5449
|
-
import * as
|
|
5510
|
+
import * as p8 from "@clack/prompts";
|
|
5450
5511
|
import { readFileSync as readFileSync15 } from "fs";
|
|
5451
5512
|
|
|
5452
5513
|
// src/cli/commands/deploy/repository.ts
|
|
@@ -6157,6 +6218,80 @@ function detachedHeadRefusal() {
|
|
|
6157
6218
|
};
|
|
6158
6219
|
}
|
|
6159
6220
|
|
|
6221
|
+
// src/cli/commands/deploy/secrets.ts
|
|
6222
|
+
import * as p7 from "@clack/prompts";
|
|
6223
|
+
function secretsConfigCreateAction(appDir, configName, envName) {
|
|
6224
|
+
return {
|
|
6225
|
+
cwd: appDir,
|
|
6226
|
+
argv: [
|
|
6227
|
+
"deepspace",
|
|
6228
|
+
"secrets",
|
|
6229
|
+
"configs",
|
|
6230
|
+
"create",
|
|
6231
|
+
configName,
|
|
6232
|
+
...envName ? ["--env", envName] : []
|
|
6233
|
+
]
|
|
6234
|
+
};
|
|
6235
|
+
}
|
|
6236
|
+
async function loadDeploySecrets(options) {
|
|
6237
|
+
const { deployUrl, appDir, appId, envName, ownerId, token, output } = options;
|
|
6238
|
+
const configName = defaultConfigNameForEnv(envName);
|
|
6239
|
+
let exists = false;
|
|
6240
|
+
let refreshed;
|
|
6241
|
+
try {
|
|
6242
|
+
refreshed = await refreshSecretsCache(deployUrl, token, appId, envName, configName);
|
|
6243
|
+
exists = refreshed.pulled !== null;
|
|
6244
|
+
if (refreshed.summary) p7.log.info(refreshed.summary);
|
|
6245
|
+
const names = Object.keys(refreshed.pulled?.values ?? {}).sort();
|
|
6246
|
+
if (names.length) p7.log.info(`App secrets: ${names.join(", ")}`);
|
|
6247
|
+
else if (exists) {
|
|
6248
|
+
p7.log.warn(
|
|
6249
|
+
"App secrets: none \u2014 this deploy ships no user secrets and removes any live on the app"
|
|
6250
|
+
);
|
|
6251
|
+
}
|
|
6252
|
+
} catch (error) {
|
|
6253
|
+
if (error?.status === 403) {
|
|
6254
|
+
output.die(
|
|
6255
|
+
"You're not authorized to deploy this app \u2014 you must be its owner or a current collaborator. If you were a collaborator, your access may have been revoked.",
|
|
6256
|
+
"not_authorized"
|
|
6257
|
+
);
|
|
6258
|
+
}
|
|
6259
|
+
output.die(
|
|
6260
|
+
`Failed to refresh app secrets before deploy: ${errorMessage4(error)}`,
|
|
6261
|
+
"secrets_refresh_failed"
|
|
6262
|
+
);
|
|
6263
|
+
}
|
|
6264
|
+
try {
|
|
6265
|
+
await writeDevVars(appDir, ownerId, token, envName, {
|
|
6266
|
+
appId,
|
|
6267
|
+
generatedSecretsCache: refreshed.rendered
|
|
6268
|
+
});
|
|
6269
|
+
} catch (error) {
|
|
6270
|
+
if (error instanceof Refusal && error.code === "app_not_found") {
|
|
6271
|
+
output.die(`Could not write .dev.vars before deploy: ${error.message}`, error.code, {
|
|
6272
|
+
actionRequired: true,
|
|
6273
|
+
action: error.action
|
|
6274
|
+
});
|
|
6275
|
+
}
|
|
6276
|
+
const code = error instanceof ApiError && error.code ? error.code : "dev_vars_failed";
|
|
6277
|
+
output.die(`Could not write .dev.vars before deploy: ${errorMessage4(error)}`, code);
|
|
6278
|
+
}
|
|
6279
|
+
if (!exists) {
|
|
6280
|
+
output.die(
|
|
6281
|
+
`Secrets config "${configName}" does not exist. Create it explicitly before deploying; this distinguishes an intentional empty config from an uninitialized app and protects live Worker secrets from a deleted config.`,
|
|
6282
|
+
"secrets_config_missing",
|
|
6283
|
+
{
|
|
6284
|
+
actionRequired: true,
|
|
6285
|
+
action: secretsConfigCreateAction(appDir, configName, envName)
|
|
6286
|
+
}
|
|
6287
|
+
);
|
|
6288
|
+
}
|
|
6289
|
+
return { configName };
|
|
6290
|
+
}
|
|
6291
|
+
function errorMessage4(error) {
|
|
6292
|
+
return error instanceof Error ? error.message : String(error);
|
|
6293
|
+
}
|
|
6294
|
+
|
|
6160
6295
|
// src/cli/commands/deploy/request.ts
|
|
6161
6296
|
var postWithRetry = fetchWithTransientRetry;
|
|
6162
6297
|
var STALE_DISPLAY_NAME_LOCATIONS = [
|
|
@@ -6173,6 +6308,7 @@ function renamePromptMessage(rename2) {
|
|
|
6173
6308
|
var CLOUDFLARE_DEPLOY_ERROR_HINT = "Deployment reached the DeepSpace deploy worker, but Cloudflare's deployment control-plane API failed. This is often caused by a Cloudflare Dashboard/API incident or Workers for Platforms entitlement outage. Already deployed apps should keep serving; wait for Cloudflare to recover and retry.";
|
|
6174
6309
|
var DEPLOY_SERVICE_LIMIT_HINT = "The DeepSpace deploy service hit a resource limit processing this deploy (the deploy worker was terminated before it could answer). This is a DeepSpace-side failure, not a Cloudflare incident \u2014 your app was not changed. Retry; if it keeps happening, report the app id and asset count.";
|
|
6175
6310
|
var REQUIRED_ASSET_TRANSPORT = "content-addressed-v1";
|
|
6311
|
+
var REQUIRED_SECRETS_SOURCE = "store-read-v1";
|
|
6176
6312
|
var REQUIRED_WORKER_MODULE_TRANSPORT = "multipart-v1";
|
|
6177
6313
|
var UPLOAD_CONCURRENCY = 16;
|
|
6178
6314
|
var ASSET_UPLOAD_ATTEMPT_TIMEOUT_MS = 15e4;
|
|
@@ -6214,7 +6350,8 @@ async function deployBuiltBundle(options) {
|
|
|
6214
6350
|
claimReleased,
|
|
6215
6351
|
ignoreStale,
|
|
6216
6352
|
bundle,
|
|
6217
|
-
|
|
6353
|
+
secretsConfig,
|
|
6354
|
+
envName,
|
|
6218
6355
|
repository,
|
|
6219
6356
|
output,
|
|
6220
6357
|
spinner
|
|
@@ -6222,11 +6359,11 @@ async function deployBuiltBundle(options) {
|
|
|
6222
6359
|
const auth2 = createDeployAuthSession(token, refreshToken);
|
|
6223
6360
|
spinner.start(`Deploying ${appName}...`);
|
|
6224
6361
|
if (bundle.extraRoutes === true) {
|
|
6225
|
-
|
|
6362
|
+
p8.log.info("Worker-first routing: all requests");
|
|
6226
6363
|
} else if (bundle.extraRoutes.length) {
|
|
6227
|
-
|
|
6364
|
+
p8.log.info(`Custom worker-first routes: ${bundle.extraRoutes.join(", ")}`);
|
|
6228
6365
|
}
|
|
6229
|
-
await
|
|
6366
|
+
await requireWorkerModulesCapability(deployUrl, bundle.worker.modules.length > 1, spinner, output);
|
|
6230
6367
|
await uploadDeployAssetsWithAuth(
|
|
6231
6368
|
{ deployUrl, appId, assets: bundle.assets, output, spinner },
|
|
6232
6369
|
auth2
|
|
@@ -6236,7 +6373,7 @@ async function deployBuiltBundle(options) {
|
|
|
6236
6373
|
const bail = async (message, stopLabel = "Deploy failed", code, actionRequired = false, rawAction) => {
|
|
6237
6374
|
const action = rawAction ? executableAction(rawAction) : void 0;
|
|
6238
6375
|
if (stopLabel !== null) spinner.stop(stopLabel);
|
|
6239
|
-
|
|
6376
|
+
p8.cancel(code ? withSlug(message, code) : message);
|
|
6240
6377
|
if (action) printAction(action);
|
|
6241
6378
|
if (output.json) {
|
|
6242
6379
|
output.emitJson({
|
|
@@ -6278,7 +6415,7 @@ async function deployBuiltBundle(options) {
|
|
|
6278
6415
|
if (bundle.customBindings.length) {
|
|
6279
6416
|
form.append("bindingManifest", JSON.stringify(bundle.customBindings));
|
|
6280
6417
|
}
|
|
6281
|
-
|
|
6418
|
+
form.append("secretsConfig", secretsConfig);
|
|
6282
6419
|
if (bundle.extraRoutes === true || bundle.extraRoutes.length) {
|
|
6283
6420
|
form.append("extraRunWorkerFirst", JSON.stringify(bundle.extraRoutes));
|
|
6284
6421
|
}
|
|
@@ -6335,7 +6472,7 @@ async function deployBuiltBundle(options) {
|
|
|
6335
6472
|
response = await postCommit();
|
|
6336
6473
|
} catch (error) {
|
|
6337
6474
|
await bail(
|
|
6338
|
-
error instanceof ApiError ?
|
|
6475
|
+
error instanceof ApiError ? errorMessage5(error) : `Deploy request failed: ${errorMessage5(error)}`,
|
|
6339
6476
|
"Deploy failed",
|
|
6340
6477
|
error instanceof ApiError ? error.code : "deploy_request_failed"
|
|
6341
6478
|
);
|
|
@@ -6349,8 +6486,8 @@ async function deployBuiltBundle(options) {
|
|
|
6349
6486
|
if (output.nonInteractive) {
|
|
6350
6487
|
await bail(renameRefusalMessage(rename2), null, "rename_required");
|
|
6351
6488
|
}
|
|
6352
|
-
const confirmed = await
|
|
6353
|
-
if (
|
|
6489
|
+
const confirmed = await p8.confirm({ message: renamePromptMessage(rename2) });
|
|
6490
|
+
if (p8.isCancel(confirmed) || !confirmed) await bail("Deploy cancelled.", null);
|
|
6354
6491
|
confirmRename = true;
|
|
6355
6492
|
renamedFrom = rename2.fromHost;
|
|
6356
6493
|
spinner.start(`Deploying ${appName}...`);
|
|
@@ -6366,6 +6503,15 @@ async function deployBuiltBundle(options) {
|
|
|
6366
6503
|
{ cwd: appDir, argv: ["deepspace", "pull"] }
|
|
6367
6504
|
);
|
|
6368
6505
|
}
|
|
6506
|
+
if (response.status === 409 && body.code === "secrets_config_missing") {
|
|
6507
|
+
await bail(
|
|
6508
|
+
`Secrets config "${secretsConfig}" does not exist on the platform (it was deleted after the pre-deploy check). Create it explicitly before deploying` + (envName ? ` (run the action below \u2014 plain \`configs create\` targets the top-level app)` : "") + ".",
|
|
6509
|
+
"Deploy failed",
|
|
6510
|
+
"secrets_config_missing",
|
|
6511
|
+
true,
|
|
6512
|
+
secretsConfigCreateAction(appDir, secretsConfig, envName)
|
|
6513
|
+
);
|
|
6514
|
+
}
|
|
6369
6515
|
if (response.status === 409 && body.code === "release_in_progress") {
|
|
6370
6516
|
await bail(
|
|
6371
6517
|
`${body.error ?? "Another deploy of this app is already in progress"}. It is committing now \u2014 this run built and uploaded fine but did not release. Wait a moment and run the same deploy again; if it keeps refusing for more than a couple of minutes, check \`deepspace releases\`.`,
|
|
@@ -6382,14 +6528,14 @@ async function deployBuiltBundle(options) {
|
|
|
6382
6528
|
body.code ?? "deploy_failed"
|
|
6383
6529
|
);
|
|
6384
6530
|
}
|
|
6385
|
-
|
|
6531
|
+
p8.log.info(`Platform commit: ${Math.round((Date.now() - commitStarted) / 1e3)}s`);
|
|
6386
6532
|
if (body.staleBaseGuard === "skipped") {
|
|
6387
|
-
|
|
6533
|
+
p8.log.warn(
|
|
6388
6534
|
"The stale-base guard was skipped (repo store unavailable) \u2014 this deploy was NOT checked against the live release. Verify you're not clobbering newer work."
|
|
6389
6535
|
);
|
|
6390
6536
|
}
|
|
6391
6537
|
if (body.bundleRetained === false) {
|
|
6392
|
-
|
|
6538
|
+
p8.log.warn(
|
|
6393
6539
|
"This deploy is live, but its rollback bundle was not retained because the app storage quota is full."
|
|
6394
6540
|
);
|
|
6395
6541
|
}
|
|
@@ -6398,33 +6544,62 @@ async function deployBuiltBundle(options) {
|
|
|
6398
6544
|
function assetManifest(assets) {
|
|
6399
6545
|
return assets.map((asset) => ({ path: asset.path, hash: asset.hash, size: asset.size }));
|
|
6400
6546
|
}
|
|
6401
|
-
async function
|
|
6402
|
-
let capabilities;
|
|
6547
|
+
async function probeDeployCapabilities(deployUrl, spinner, output) {
|
|
6548
|
+
let capabilities = {};
|
|
6403
6549
|
try {
|
|
6404
6550
|
const response = await postWithRetry(`${deployUrl}/api/health`, () => ({}), {
|
|
6405
|
-
|
|
6551
|
+
attempts: 2,
|
|
6552
|
+
timeoutMs: 1e4
|
|
6406
6553
|
});
|
|
6407
6554
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
|
6408
6555
|
const body = await response.json();
|
|
6409
|
-
capabilities = body.capabilities;
|
|
6556
|
+
capabilities = body.capabilities ?? {};
|
|
6410
6557
|
} catch (error) {
|
|
6411
|
-
spinner
|
|
6558
|
+
spinner?.stop("Deploy failed");
|
|
6412
6559
|
output.die(
|
|
6413
|
-
`Could not reach the DeepSpace deploy service at ${deployUrl} to check its capabilities: ${
|
|
6560
|
+
`Could not reach the DeepSpace deploy service at ${deployUrl} to check its capabilities: ${errorMessage5(error)}`,
|
|
6414
6561
|
"deploy_service_unreachable"
|
|
6415
6562
|
);
|
|
6416
6563
|
}
|
|
6417
|
-
|
|
6418
|
-
|
|
6419
|
-
|
|
6420
|
-
|
|
6421
|
-
|
|
6422
|
-
|
|
6423
|
-
|
|
6424
|
-
|
|
6425
|
-
|
|
6564
|
+
return capabilities;
|
|
6565
|
+
}
|
|
6566
|
+
function requireCapability(deployUrl, spinner, output, name, advertised, required, code, pinHint = "") {
|
|
6567
|
+
if (advertised === required) return;
|
|
6568
|
+
spinner?.stop("Deploy failed");
|
|
6569
|
+
output.die(
|
|
6570
|
+
`The DeepSpace deploy service at ${deployUrl} does not support this CLI's ${name} (needs "${required}", found ${advertised === void 0 ? "none" : `"${String(advertised)}"`}). Wait for the platform to finish updating${pinHint}.`,
|
|
6571
|
+
code
|
|
6572
|
+
);
|
|
6573
|
+
}
|
|
6574
|
+
async function requireDeployCapabilities(deployUrl, spinner, output) {
|
|
6575
|
+
const capabilities = await probeDeployCapabilities(deployUrl, spinner, output);
|
|
6576
|
+
requireCapability(
|
|
6577
|
+
deployUrl,
|
|
6578
|
+
spinner,
|
|
6579
|
+
output,
|
|
6580
|
+
"asset transport",
|
|
6581
|
+
capabilities.assetTransport,
|
|
6582
|
+
REQUIRED_ASSET_TRANSPORT,
|
|
6583
|
+
"asset_transport_unsupported"
|
|
6584
|
+
);
|
|
6585
|
+
requireCapability(
|
|
6586
|
+
deployUrl,
|
|
6587
|
+
spinner,
|
|
6588
|
+
output,
|
|
6589
|
+
"secrets source",
|
|
6590
|
+
capabilities.secretsSource,
|
|
6591
|
+
REQUIRED_SECRETS_SOURCE,
|
|
6592
|
+
"secrets_source_unsupported",
|
|
6593
|
+
", or pin the last pre-cutover CLI (`npm i -g deepspace@0.23`)"
|
|
6594
|
+
);
|
|
6595
|
+
}
|
|
6596
|
+
async function requireWorkerModulesCapability(deployUrl, needsWorkerModules, spinner, output) {
|
|
6597
|
+
if (!needsWorkerModules) return;
|
|
6598
|
+
const capabilities = await probeDeployCapabilities(deployUrl, spinner, output);
|
|
6599
|
+
if (capabilities.workerModules !== REQUIRED_WORKER_MODULE_TRANSPORT) {
|
|
6600
|
+
spinner?.stop("Deploy failed");
|
|
6426
6601
|
output.die(
|
|
6427
|
-
`This build contains multiple Worker modules, but the DeepSpace deploy service at ${deployUrl} does not support their transport (needs "${REQUIRED_WORKER_MODULE_TRANSPORT}", found ${capabilities
|
|
6602
|
+
`This build contains multiple Worker modules, but the DeepSpace deploy service at ${deployUrl} does not support their transport (needs "${REQUIRED_WORKER_MODULE_TRANSPORT}", found ${capabilities.workerModules === void 0 ? "none" : `"${String(capabilities.workerModules)}"`}). Wait for the platform to finish updating before retrying this deploy.`,
|
|
6428
6603
|
"worker_module_transport_unsupported"
|
|
6429
6604
|
);
|
|
6430
6605
|
}
|
|
@@ -6448,9 +6623,9 @@ async function uploadDeployAssetsWithAuth(options, auth2) {
|
|
|
6448
6623
|
} catch (error) {
|
|
6449
6624
|
spinner.stop("Deploy failed");
|
|
6450
6625
|
if (error instanceof ApiError) {
|
|
6451
|
-
output.die(
|
|
6626
|
+
output.die(errorMessage5(error), error.code ?? "upload_failed");
|
|
6452
6627
|
}
|
|
6453
|
-
output.die(`Asset plan failed (network): ${
|
|
6628
|
+
output.die(`Asset plan failed (network): ${errorMessage5(error)}`, "upload_failed");
|
|
6454
6629
|
}
|
|
6455
6630
|
const planBody = await planResponse.json().catch(() => ({}));
|
|
6456
6631
|
if (!planResponse.ok) {
|
|
@@ -6473,11 +6648,11 @@ async function uploadDeployAssetsWithAuth(options, auth2) {
|
|
|
6473
6648
|
missing.push(asset);
|
|
6474
6649
|
}
|
|
6475
6650
|
if (missing.length === 0) {
|
|
6476
|
-
|
|
6651
|
+
p8.log.info(`Assets: ${byHash.size} file(s), all already uploaded`);
|
|
6477
6652
|
return;
|
|
6478
6653
|
}
|
|
6479
6654
|
const missingBytes = missing.reduce((total2, asset) => total2 + asset.size, 0);
|
|
6480
|
-
|
|
6655
|
+
p8.log.info(
|
|
6481
6656
|
`Assets: ${byHash.size} file(s), uploading ${missing.length} (${Math.ceil(missingBytes / 1024)} KiB); the rest are already stored`
|
|
6482
6657
|
);
|
|
6483
6658
|
const total = missing.length;
|
|
@@ -6518,16 +6693,16 @@ async function uploadDeployAssetsWithAuth(options, auth2) {
|
|
|
6518
6693
|
const uploadStarted = Date.now();
|
|
6519
6694
|
try {
|
|
6520
6695
|
await Promise.all(Array.from({ length: Math.min(UPLOAD_CONCURRENCY, missing.length) }, worker));
|
|
6521
|
-
|
|
6696
|
+
p8.log.info(`Uploaded ${total} file(s) in ${Math.round((Date.now() - uploadStarted) / 1e3)}s`);
|
|
6522
6697
|
} catch (error) {
|
|
6523
6698
|
spinner.stop("Deploy failed");
|
|
6524
6699
|
if (error instanceof AssetUploadError) {
|
|
6525
6700
|
output.die(formatDeployWorkerError(error.status, error.message, error.code), error.code);
|
|
6526
6701
|
}
|
|
6527
6702
|
if (error instanceof ApiError) {
|
|
6528
|
-
output.die(
|
|
6703
|
+
output.die(errorMessage5(error), error.code ?? "upload_failed");
|
|
6529
6704
|
}
|
|
6530
|
-
output.die(`Asset upload failed (network): ${
|
|
6705
|
+
output.die(`Asset upload failed (network): ${errorMessage5(error)}`, "upload_failed");
|
|
6531
6706
|
}
|
|
6532
6707
|
}
|
|
6533
6708
|
var AssetUploadError = class extends Error {
|
|
@@ -6543,7 +6718,9 @@ function isDeployServiceResourceLimit(status3, error) {
|
|
|
6543
6718
|
}
|
|
6544
6719
|
function formatDeployWorkerError(status3, error, code) {
|
|
6545
6720
|
const detail = error ?? `Deployment error (${status3})`;
|
|
6546
|
-
if (code === "cli_outdated")
|
|
6721
|
+
if (code === "cli_outdated" || code === "secrets_read_failed" || code === "release_reconciliation_pending") {
|
|
6722
|
+
return detail;
|
|
6723
|
+
}
|
|
6547
6724
|
if (isDeployServiceResourceLimit(status3, error)) {
|
|
6548
6725
|
return `${DEPLOY_SERVICE_LIMIT_HINT}
|
|
6549
6726
|
|
|
@@ -6562,82 +6739,6 @@ Underlying error: ${detail}`;
|
|
|
6562
6739
|
|
|
6563
6740
|
Underlying error: ${detail}`;
|
|
6564
6741
|
}
|
|
6565
|
-
function errorMessage4(error) {
|
|
6566
|
-
return error instanceof Error ? error.message : String(error);
|
|
6567
|
-
}
|
|
6568
|
-
|
|
6569
|
-
// src/cli/commands/deploy/secrets.ts
|
|
6570
|
-
import * as p8 from "@clack/prompts";
|
|
6571
|
-
async function loadDeploySecrets(options) {
|
|
6572
|
-
const { deployUrl, appDir, appId, envName, ownerId, token, output } = options;
|
|
6573
|
-
let linked = null;
|
|
6574
|
-
try {
|
|
6575
|
-
const refreshed = await refreshSecretsCache(deployUrl, token, appId, envName);
|
|
6576
|
-
linked = refreshed.pulled;
|
|
6577
|
-
await writeDevVars(appDir, ownerId, token, envName, {
|
|
6578
|
-
appId,
|
|
6579
|
-
generatedSecretsCache: refreshed.rendered
|
|
6580
|
-
});
|
|
6581
|
-
if (refreshed.summary) p8.log.info(refreshed.summary);
|
|
6582
|
-
} catch (error) {
|
|
6583
|
-
if (error?.status === 403) {
|
|
6584
|
-
output.die(
|
|
6585
|
-
"You're not authorized to deploy this app \u2014 you must be its owner or a current collaborator. If you were a collaborator, your access may have been revoked.",
|
|
6586
|
-
"not_authorized"
|
|
6587
|
-
);
|
|
6588
|
-
}
|
|
6589
|
-
output.die(
|
|
6590
|
-
`Failed to refresh app secrets before deploy: ${errorMessage5(error)}`,
|
|
6591
|
-
"secrets_refresh_failed"
|
|
6592
|
-
);
|
|
6593
|
-
}
|
|
6594
|
-
if (!linked) {
|
|
6595
|
-
const configName = defaultConfigNameForEnv(envName);
|
|
6596
|
-
output.die(
|
|
6597
|
-
`Secrets config "${configName}" does not exist. Create it explicitly before deploying; this distinguishes an intentional empty config from an uninitialized app and protects live Worker secrets during the platform rollout.`,
|
|
6598
|
-
"secrets_config_missing",
|
|
6599
|
-
{
|
|
6600
|
-
action: {
|
|
6601
|
-
cwd: appDir,
|
|
6602
|
-
argv: [
|
|
6603
|
-
"deepspace",
|
|
6604
|
-
"secrets",
|
|
6605
|
-
"configs",
|
|
6606
|
-
"create",
|
|
6607
|
-
configName,
|
|
6608
|
-
...envName ? ["--env", envName] : []
|
|
6609
|
-
]
|
|
6610
|
-
}
|
|
6611
|
-
}
|
|
6612
|
-
);
|
|
6613
|
-
}
|
|
6614
|
-
return { linked };
|
|
6615
|
-
}
|
|
6616
|
-
function prepareDeploySecrets(options) {
|
|
6617
|
-
const { cache, customBindings, doManifest, output } = options;
|
|
6618
|
-
const values = cache.linked ? { ...cache.linked.values } : {};
|
|
6619
|
-
const names = Object.keys(values);
|
|
6620
|
-
const declaredBindingNames = /* @__PURE__ */ new Set([
|
|
6621
|
-
...customBindings.map((binding) => binding.name),
|
|
6622
|
-
...(doManifest ?? []).map((binding) => binding.binding)
|
|
6623
|
-
]);
|
|
6624
|
-
for (const name of names) {
|
|
6625
|
-
if (RESERVED_BINDING_NAMES.has(name)) {
|
|
6626
|
-
output.die(
|
|
6627
|
-
`App secret "${name}" is a reserved binding name \u2014 rename or remove that secret before deploying.`,
|
|
6628
|
-
"reserved_binding"
|
|
6629
|
-
);
|
|
6630
|
-
}
|
|
6631
|
-
if (declaredBindingNames.has(name)) {
|
|
6632
|
-
output.die(
|
|
6633
|
-
`App secret "${name}" collides with a binding declared in wrangler.toml \u2014 rename one or the other.`,
|
|
6634
|
-
"binding_collision"
|
|
6635
|
-
);
|
|
6636
|
-
}
|
|
6637
|
-
}
|
|
6638
|
-
if (names.length) p8.log.info(`App secrets: ${names.join(", ")}`);
|
|
6639
|
-
return { values, names, authoritative: cache.linked !== null };
|
|
6640
|
-
}
|
|
6641
6742
|
function errorMessage5(error) {
|
|
6642
6743
|
return error instanceof Error ? error.message : String(error);
|
|
6643
6744
|
}
|
|
@@ -6817,11 +6918,12 @@ async function runLockedDeploy(args, output, appDir, envName) {
|
|
|
6817
6918
|
});
|
|
6818
6919
|
if (!sourceState.registered) {
|
|
6819
6920
|
output.die(
|
|
6820
|
-
`${appId} is not registered. If this repo's id came from an older SDK's scaffold, run \`deepspace app init --new-id\` to register it as a fresh app; a brand-new app dir registers with \`deepspace app init\`.`,
|
|
6921
|
+
`${appId} is not registered. If this repo's id came from an older SDK's scaffold, run \`deepspace app init --new-id${envName ? ` --env ${envName}` : ""}\` to register it as a fresh app; a brand-new app dir registers with \`deepspace app init${envName ? ` --env ${envName}` : ""}\`.`,
|
|
6821
6922
|
"app_not_registered"
|
|
6822
6923
|
);
|
|
6823
6924
|
}
|
|
6824
|
-
|
|
6925
|
+
await requireDeployCapabilities(DEPLOY_URL4, null, output);
|
|
6926
|
+
const { configName: secretsConfig } = await loadDeploySecrets({
|
|
6825
6927
|
deployUrl: DEPLOY_URL4,
|
|
6826
6928
|
appDir,
|
|
6827
6929
|
appId,
|
|
@@ -6833,7 +6935,9 @@ async function runLockedDeploy(args, output, appDir, envName) {
|
|
|
6833
6935
|
const ownerJwtRefusal = ownerJwtMissingRefusal(sourceState);
|
|
6834
6936
|
if (ownerJwtRefusal) output.die(ownerJwtRefusal.error, ownerJwtRefusal.code);
|
|
6835
6937
|
if (sourceState.onBehalf) {
|
|
6836
|
-
process.stderr.write(
|
|
6938
|
+
process.stderr.write(
|
|
6939
|
+
"Deploying on behalf of the owner \u2014 this app belongs to another account.\n"
|
|
6940
|
+
);
|
|
6837
6941
|
}
|
|
6838
6942
|
let confirmRename = args.rename === true;
|
|
6839
6943
|
const rename2 = pendingRename(sourceState.registeredHost, appName);
|
|
@@ -6878,12 +6982,6 @@ async function runLockedDeploy(args, output, appDir, envName) {
|
|
|
6878
6982
|
output,
|
|
6879
6983
|
sourceState
|
|
6880
6984
|
});
|
|
6881
|
-
const secrets = prepareDeploySecrets({
|
|
6882
|
-
cache: secretsCache,
|
|
6883
|
-
customBindings: bundle.customBindings,
|
|
6884
|
-
doManifest: bundle.doManifest,
|
|
6885
|
-
output
|
|
6886
|
-
});
|
|
6887
6985
|
const body = await deployBuiltBundle({
|
|
6888
6986
|
deployUrl: DEPLOY_URL4,
|
|
6889
6987
|
appDir,
|
|
@@ -6895,7 +6993,8 @@ async function runLockedDeploy(args, output, appDir, envName) {
|
|
|
6895
6993
|
claimReleased: args["claim-released"] === true,
|
|
6896
6994
|
ignoreStale: Boolean(args["ignore-stale"]),
|
|
6897
6995
|
bundle,
|
|
6898
|
-
|
|
6996
|
+
secretsConfig,
|
|
6997
|
+
envName,
|
|
6899
6998
|
repository,
|
|
6900
6999
|
output,
|
|
6901
7000
|
spinner
|
|
@@ -7773,24 +7872,11 @@ function featureCatalog(packageRoot = featurePackageRoot()) {
|
|
|
7773
7872
|
description: config.description ?? null
|
|
7774
7873
|
}));
|
|
7775
7874
|
}
|
|
7776
|
-
function editDistance2(a, b) {
|
|
7777
|
-
const row = Array.from({ length: b.length + 1 }, (_, index) => index);
|
|
7778
|
-
for (let i = 1; i <= a.length; i++) {
|
|
7779
|
-
let previous = row[0];
|
|
7780
|
-
row[0] = i;
|
|
7781
|
-
for (let j = 1; j <= b.length; j++) {
|
|
7782
|
-
const current = row[j];
|
|
7783
|
-
row[j] = Math.min(row[j] + 1, row[j - 1] + 1, previous + (a[i - 1] === b[j - 1] ? 0 : 1));
|
|
7784
|
-
previous = current;
|
|
7785
|
-
}
|
|
7786
|
-
}
|
|
7787
|
-
return row[b.length];
|
|
7788
|
-
}
|
|
7789
7875
|
function suggestFeature(featureId, packageRoot = featurePackageRoot()) {
|
|
7790
7876
|
let closest = null;
|
|
7791
7877
|
let closestDistance = Number.POSITIVE_INFINITY;
|
|
7792
7878
|
for (const feature of listFeatureConfigs(packageRoot)) {
|
|
7793
|
-
const distance =
|
|
7879
|
+
const distance = editDistance(featureId, feature.id);
|
|
7794
7880
|
if (distance < closestDistance) {
|
|
7795
7881
|
closest = feature.id;
|
|
7796
7882
|
closestDistance = distance;
|
|
@@ -7839,7 +7925,7 @@ function installFiles(packageRoot, config, targetDir, emit) {
|
|
|
7839
7925
|
if (!existed) missing.push(resolvedDest);
|
|
7840
7926
|
continue;
|
|
7841
7927
|
}
|
|
7842
|
-
if (existed
|
|
7928
|
+
if (existed) {
|
|
7843
7929
|
emit(` Exists (skipped): ${resolvedDest}`);
|
|
7844
7930
|
skipped++;
|
|
7845
7931
|
continue;
|
|
@@ -7848,8 +7934,8 @@ function installFiles(packageRoot, config, targetDir, emit) {
|
|
|
7848
7934
|
const shiftLevels = resolvedDest.split("/").length - file.dest.split("/").length;
|
|
7849
7935
|
if (wasRedirected) copyFileWithImportShift(srcPath, destPath, shiftLevels);
|
|
7850
7936
|
else copyFile(srcPath, destPath);
|
|
7851
|
-
emit(`
|
|
7852
|
-
|
|
7937
|
+
emit(` Copied: ${resolvedDest}`);
|
|
7938
|
+
created.push(resolvedDest);
|
|
7853
7939
|
copied++;
|
|
7854
7940
|
}
|
|
7855
7941
|
return { copied, skipped, files: { created, preexisting, missing } };
|
|
@@ -8119,50 +8205,6 @@ function rateLimitBindingBlock(scope, binding) {
|
|
|
8119
8205
|
`simple = { limit = ${binding.limit}, period = ${binding.period} }`
|
|
8120
8206
|
].join("\n");
|
|
8121
8207
|
}
|
|
8122
|
-
function integrateCss(packageRoot, config, targetDir, emit) {
|
|
8123
|
-
if (!config.css?.length) return [];
|
|
8124
|
-
const stylesPath = join22(targetDir, "src", "styles.css");
|
|
8125
|
-
if (!existsSync21(stylesPath)) {
|
|
8126
|
-
emit(" Warning: Cannot integrate CSS \u2014 src/styles.css not found");
|
|
8127
|
-
return [
|
|
8128
|
-
{
|
|
8129
|
-
area: "css",
|
|
8130
|
-
reason: "src/styles.css was not found.",
|
|
8131
|
-
steps: config.css.map(
|
|
8132
|
-
(cssFile) => `Append node_modules/deepspace/features/${config.id}/${cssFile} to src/styles.css.`
|
|
8133
|
-
)
|
|
8134
|
-
}
|
|
8135
|
-
];
|
|
8136
|
-
}
|
|
8137
|
-
let styles = readFileSync17(stylesPath, "utf-8");
|
|
8138
|
-
let integrated = 0;
|
|
8139
|
-
const unresolved = [];
|
|
8140
|
-
for (const cssFile of config.css) {
|
|
8141
|
-
const srcPath = join22(packageRoot, "features", config.id, cssFile);
|
|
8142
|
-
if (!existsSync21(srcPath)) {
|
|
8143
|
-
emit(` Warning: CSS source not found: ${cssFile}`, "stderr");
|
|
8144
|
-
unresolved.push({
|
|
8145
|
-
area: "css",
|
|
8146
|
-
reason: `Feature CSS source '${cssFile}' was not found in the installed package.`,
|
|
8147
|
-
steps: ["Reinstall the current deepspace package, then retry this feature installation."]
|
|
8148
|
-
});
|
|
8149
|
-
continue;
|
|
8150
|
-
}
|
|
8151
|
-
const css = readFileSync17(srcPath, "utf-8");
|
|
8152
|
-
const fingerprint = css.match(/\.([\w-]+)\s*\{|@keyframes\s+([\w-]+)/);
|
|
8153
|
-
const marker = fingerprint?.[1] ?? fingerprint?.[2];
|
|
8154
|
-
if (marker && styles.includes(marker)) {
|
|
8155
|
-
emit(` CSS already present: ${cssFile} (found .${marker})`);
|
|
8156
|
-
continue;
|
|
8157
|
-
}
|
|
8158
|
-
styles += `
|
|
8159
|
-
${css}`;
|
|
8160
|
-
integrated++;
|
|
8161
|
-
emit(` CSS integrated: ${cssFile} -> styles.css`);
|
|
8162
|
-
}
|
|
8163
|
-
if (integrated > 0) writeFileSync7(stylesPath, styles);
|
|
8164
|
-
return unresolved;
|
|
8165
|
-
}
|
|
8166
8208
|
function unresolvedRoute(route, config, reason, emit) {
|
|
8167
8209
|
const roles = routeRolesSuffix(route);
|
|
8168
8210
|
emit("");
|
|
@@ -8387,7 +8429,6 @@ function installFeature(options) {
|
|
|
8387
8429
|
...integrateActions(config, targetDir, emit),
|
|
8388
8430
|
...integrateWrangler(config, targetDir, emit),
|
|
8389
8431
|
...integrateCode(config, targetDir, emit),
|
|
8390
|
-
...integrateCss(packageRoot, config, targetDir, emit),
|
|
8391
8432
|
...integrateRoute(config, targetDir, emit)
|
|
8392
8433
|
];
|
|
8393
8434
|
const dependencyResult = integrateDependencies(
|
|
@@ -10852,10 +10893,17 @@ var pull = defineCommand9({
|
|
|
10852
10893
|
wranglerEnv,
|
|
10853
10894
|
t.configName
|
|
10854
10895
|
);
|
|
10855
|
-
|
|
10856
|
-
|
|
10857
|
-
|
|
10858
|
-
|
|
10896
|
+
try {
|
|
10897
|
+
await writeDevVars(appDir, ownerId, t.token, wranglerEnv, {
|
|
10898
|
+
appId: t.appId,
|
|
10899
|
+
generatedSecretsCache: refreshed.rendered
|
|
10900
|
+
});
|
|
10901
|
+
} catch (err) {
|
|
10902
|
+
if (args.app && err instanceof Refusal && err.code === "app_not_found") {
|
|
10903
|
+
throw new Refusal(err.message, err.code);
|
|
10904
|
+
}
|
|
10905
|
+
throw err;
|
|
10906
|
+
}
|
|
10859
10907
|
const count = Object.keys(refreshed.pulled?.values ?? {}).length;
|
|
10860
10908
|
ok(
|
|
10861
10909
|
args.json === true,
|
|
@@ -11031,7 +11079,7 @@ var init_default = defineDeepspaceCommand({
|
|
|
11031
11079
|
} catch (error) {
|
|
11032
11080
|
if (error instanceof ApiError && error.code === "forbidden") {
|
|
11033
11081
|
throw new Refusal(
|
|
11034
|
-
`wrangler.toml carries ${existing}, which is registered to another user. Run \`deepspace app init --new-id\` to fork this repo as your own app (new data and secrets; the original is untouched).`,
|
|
11082
|
+
`wrangler.toml carries ${existing}, which is registered to another user. Run \`deepspace app init --new-id${envName ? ` --env ${envName}` : ""}\` to fork this repo as your own app (new data and secrets; the original is untouched).`,
|
|
11035
11083
|
"not_app_owner"
|
|
11036
11084
|
);
|
|
11037
11085
|
}
|
|
@@ -11039,7 +11087,7 @@ var init_default = defineDeepspaceCommand({
|
|
|
11039
11087
|
}
|
|
11040
11088
|
if (!state.registered) {
|
|
11041
11089
|
throw new Refusal(
|
|
11042
|
-
`wrangler.toml carries ${existing}, but that id was never registered \u2014 it was minted locally by an older SDK. Ids are server-minted at registration now, and an existing unregistered id cannot be claimed. Run \`deepspace app init --new-id\` to register this repo as a fresh app (new data and secrets; nothing to migrate \u2014 the old id never had server-side state).`,
|
|
11090
|
+
`wrangler.toml carries ${existing}, but that id was never registered \u2014 it was minted locally by an older SDK. Ids are server-minted at registration now, and an existing unregistered id cannot be claimed. Run \`deepspace app init --new-id${envName ? ` --env ${envName}` : ""}\` to register this repo as a fresh app (new data and secrets; nothing to migrate \u2014 the old id never had server-side state).`,
|
|
11043
11091
|
"app_not_registered",
|
|
11044
11092
|
{
|
|
11045
11093
|
action: cliAction(
|
|
@@ -11117,7 +11165,14 @@ var init_default = defineDeepspaceCommand({
|
|
|
11117
11165
|
...!committedScaffold && wranglerConfigUncommitted(appDir) ? {
|
|
11118
11166
|
action: {
|
|
11119
11167
|
cwd: appDir,
|
|
11120
|
-
argv: [
|
|
11168
|
+
argv: [
|
|
11169
|
+
"git",
|
|
11170
|
+
"commit",
|
|
11171
|
+
"-m",
|
|
11172
|
+
existing ? `Fork as ${appId}` : `Register ${appId}`,
|
|
11173
|
+
"--",
|
|
11174
|
+
"wrangler.toml"
|
|
11175
|
+
]
|
|
11121
11176
|
}
|
|
11122
11177
|
} : {}
|
|
11123
11178
|
};
|
|
@@ -12254,9 +12309,11 @@ var releases_default = defineDeepspaceCommand({
|
|
|
12254
12309
|
// src/cli/commands/rollback.ts
|
|
12255
12310
|
import * as p20 from "@clack/prompts";
|
|
12256
12311
|
var REL_ID_RE = /^rel_[0-9A-HJKMNP-TV-Z]{26}$/;
|
|
12257
|
-
function unavailableDoGuardRefusal(message) {
|
|
12312
|
+
function unavailableDoGuardRefusal(message, detail) {
|
|
12313
|
+
const cause = typeof detail === "string" && detail !== "" ? `
|
|
12314
|
+
Cause: ${detail}` : "";
|
|
12258
12315
|
return new Refusal(
|
|
12259
|
-
`${message}
|
|
12316
|
+
`${message}${cause}
|
|
12260
12317
|
Retry in a moment, or re-run with --allow-do-deletion to accept the risk.`,
|
|
12261
12318
|
"do_guard_unavailable"
|
|
12262
12319
|
);
|
|
@@ -12352,7 +12409,7 @@ Re-run with --allow-do-deletion to accept the data loss.`,
|
|
|
12352
12409
|
);
|
|
12353
12410
|
}
|
|
12354
12411
|
if (err instanceof ApiError && err.code === "do_guard_unavailable") {
|
|
12355
|
-
throw unavailableDoGuardRefusal(err.message);
|
|
12412
|
+
throw unavailableDoGuardRefusal(err.message, err.details?.detail);
|
|
12356
12413
|
}
|
|
12357
12414
|
throw err;
|
|
12358
12415
|
}
|
|
@@ -12373,7 +12430,8 @@ Re-run with --allow-do-deletion to accept the data loss.`,
|
|
|
12373
12430
|
const doClassGuard = result.doClassGuard === "unverified" ? "unverified" : void 0;
|
|
12374
12431
|
if (!args.json) {
|
|
12375
12432
|
if (result.url) {
|
|
12376
|
-
if (serving === "unconfirmed")
|
|
12433
|
+
if (serving === "unconfirmed")
|
|
12434
|
+
p20.log.warn(`URL: ${result.url} (accepted; serving not yet verified)`);
|
|
12377
12435
|
else p20.log.success(`Live at: ${result.url}`);
|
|
12378
12436
|
}
|
|
12379
12437
|
if (result.bundleRetained === false) {
|
|
@@ -14627,7 +14685,7 @@ import { join as join28, resolve as resolve21 } from "path";
|
|
|
14627
14685
|
// package.json
|
|
14628
14686
|
var package_default = {
|
|
14629
14687
|
name: "deepspace",
|
|
14630
|
-
version: "0.27.
|
|
14688
|
+
version: "0.27.1",
|
|
14631
14689
|
engines: {
|
|
14632
14690
|
node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
|
|
14633
14691
|
},
|