@supacloud/cli 0.96.0 → 0.96.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 +13 -4
- package/dist/index.js +139 -12
- package/dist/shared/deployment-upgrade.d.ts +1 -1
- package/dist/shared/tools/deploy-tools.d.ts +1 -0
- package/dist/shared/tools/developer-experience-tools.d.ts +1 -1
- package/dist/shared/tools/frontend-release-control.d.ts +1 -0
- package/dist/tool-runtime.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,11 +26,15 @@ supacloud --env test deploy
|
|
|
26
26
|
overwriting an existing project configuration. `env list` and `env check` are
|
|
27
27
|
local-only, redact credentials, and provide stable JSON with `--json` for CI or
|
|
28
28
|
AI tooling. The real `.env.supacloud.*` files are added to `.gitignore`.
|
|
29
|
-
Fill in
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
Fill in the Management credentials and project/environment in the selected profile.
|
|
30
|
+
Static frontends need only `frontend` build configuration; no application binding
|
|
31
|
+
or backend delivery build is required. Set `SUPACLOUD_APPLICATION_ID` only for
|
|
32
|
+
executable application delivery. Upgrade the CLI with
|
|
32
33
|
`npm install -g @supacloud/cli@latest` and upgrade the SupaCloud server together.
|
|
33
34
|
`deploy` checks the server protocol before building or uploading.
|
|
35
|
+
Use `frontend.name` to select exactly one named site in each environment when
|
|
36
|
+
deployment IDs differ. A missing or ambiguous name fails before upload; it never
|
|
37
|
+
falls back to another site.
|
|
34
38
|
|
|
35
39
|
## Application Starter
|
|
36
40
|
|
|
@@ -645,7 +649,12 @@ FA-owned business features are documented in
|
|
|
645
649
|
and `--dry_run` are removed. Put build settings in `supacloud.json`; use
|
|
646
650
|
`app deploy-plan` for read-only review. Historical project-specific manifests
|
|
647
651
|
and standalone Function targets must move to application delivery configuration.
|
|
648
|
-
The CLI rejects them rather than falling back to a partial Web deployment.
|
|
652
|
+
The CLI rejects them rather than silently falling back to a partial Web deployment.
|
|
653
|
+
For an intentional Web-only release in a mixed repository, use
|
|
654
|
+
`supacloud --env test deploy --assets_only`. This preserves historical manifests,
|
|
655
|
+
Functions, schedules and migrations without invoking application compilation.
|
|
656
|
+
Static publication reuses immutable archives, pre-upload CAS, mutation receipts
|
|
657
|
+
and exact post-activation readback. It never retries a conflicting activation.
|
|
649
658
|
|
|
650
659
|
The legacy `.env` fallback is unclassified and therefore does not enable the
|
|
651
660
|
production confirmation gate. Production automation must select a `prod` or
|
package/dist/index.js
CHANGED
|
@@ -8767,7 +8767,7 @@ function outcomeUnknownGuidance(text) {
|
|
|
8767
8767
|
}
|
|
8768
8768
|
|
|
8769
8769
|
// src/shared/deployment-upgrade.ts
|
|
8770
|
-
var DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment
|
|
8770
|
+
var DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment commands are no longer supported. Upgrade with `npm install -g @supacloud/cli@latest`, configure frontend in supacloud.json for static assets, or application.id and application.environmentId for executable application delivery, then run `supacloud deploy`. Use `supacloud deploy --assets_only` to publish only Web assets in a mixed repository. SupaCloud owns activation; do not retry with legacy commands.";
|
|
8771
8771
|
var removedFrontendActions = new Set([
|
|
8772
8772
|
"deploy_git",
|
|
8773
8773
|
"deploy_upload",
|
|
@@ -16350,6 +16350,39 @@ async function getFrontendRelease(http, projectRef, deploymentId, releaseId) {
|
|
|
16350
16350
|
}
|
|
16351
16351
|
return toolResponse({ project_ref: projectRef, deployment_id: deploymentId, release });
|
|
16352
16352
|
}
|
|
16353
|
+
async function uploadFrontendRelease(http, projectRef, deploymentId, archivePath) {
|
|
16354
|
+
const endpoint = releaseEndpoint(projectRef, deploymentId);
|
|
16355
|
+
const archive = await verifiedArchive(archivePath);
|
|
16356
|
+
let response;
|
|
16357
|
+
try {
|
|
16358
|
+
response = await http.postBinary(endpoint, {
|
|
16359
|
+
stream: archiveStream(archive),
|
|
16360
|
+
byteLength: archive.sizeBytes
|
|
16361
|
+
}, {
|
|
16362
|
+
contentType: FRONTEND_ARCHIVE_CONTENT_TYPE,
|
|
16363
|
+
contentLength: archive.sizeBytes,
|
|
16364
|
+
contentSha256: archive.sha256,
|
|
16365
|
+
maxJsonBytes: RESPONSE_MAX_BYTES,
|
|
16366
|
+
timeoutMs: UPLOAD_REQUEST_TIMEOUT_MS,
|
|
16367
|
+
responseTimeoutMs: MUTATION_RESPONSE_TIMEOUT_MS
|
|
16368
|
+
});
|
|
16369
|
+
} finally {
|
|
16370
|
+
await archive.handle.close();
|
|
16371
|
+
}
|
|
16372
|
+
const release = response.ok ? releaseEnvelope(response.data, { projectRef, deploymentId, releaseId: archive.sha256 }) : null;
|
|
16373
|
+
if (!release) {
|
|
16374
|
+
if (response.status >= 400 && response.status < 500 && response.status !== 408 && !response.transportError) {
|
|
16375
|
+
return releaseFailure("frontend.upload_release", "HTTP_ERROR", response.status);
|
|
16376
|
+
}
|
|
16377
|
+
return uploadReadback(http, projectRef, deploymentId, archive.sha256, response.status);
|
|
16378
|
+
}
|
|
16379
|
+
const readback = await http.get(`${endpoint}/${release.release_id}`, { maxJsonBytes: RESPONSE_MAX_BYTES });
|
|
16380
|
+
const verified = readback.ok ? releaseEnvelope(readback.data, { projectRef, deploymentId, releaseId: release.release_id }) : null;
|
|
16381
|
+
if (!verified || verified.tree_sha256 !== release.tree_sha256) {
|
|
16382
|
+
return releaseFailure("frontend.upload_release", "OUTCOME_UNKNOWN", readback.status);
|
|
16383
|
+
}
|
|
16384
|
+
return toolResponse({ project_ref: projectRef, deployment_id: deploymentId, release: verified });
|
|
16385
|
+
}
|
|
16353
16386
|
async function uploadProjectWebRelease(http, projectRef, environmentId, deploymentId, archivePath) {
|
|
16354
16387
|
const endpoint = `/v1/projects/${encodeURIComponent(projectRef)}/environments/${encodeURIComponent(environmentId)}/deployments/web-release?deployment_id=${encodeURIComponent(deploymentId)}`;
|
|
16355
16388
|
const archive = await verifiedArchive(archivePath);
|
|
@@ -16404,6 +16437,16 @@ async function uploadProjectWebRelease(http, projectRef, environmentId, deployme
|
|
|
16404
16437
|
await archive.handle.close();
|
|
16405
16438
|
}
|
|
16406
16439
|
}
|
|
16440
|
+
async function uploadReadback(http, projectRef, deploymentId, releaseId, uploadStatus) {
|
|
16441
|
+
const response = await http.get(releasePath(projectRef, deploymentId, releaseId), {
|
|
16442
|
+
maxJsonBytes: RESPONSE_MAX_BYTES
|
|
16443
|
+
});
|
|
16444
|
+
const release = response.ok ? releaseEnvelope(response.data, { projectRef, deploymentId, releaseId }) : null;
|
|
16445
|
+
if (!release) {
|
|
16446
|
+
return releaseFailure("frontend.upload_release", "OUTCOME_UNKNOWN", uploadStatus);
|
|
16447
|
+
}
|
|
16448
|
+
return toolResponse({ project_ref: projectRef, deployment_id: deploymentId, release });
|
|
16449
|
+
}
|
|
16407
16450
|
function stableJson(candidate) {
|
|
16408
16451
|
if (candidate === null || typeof candidate !== "object")
|
|
16409
16452
|
return JSON.stringify(candidate);
|
|
@@ -16523,6 +16566,57 @@ async function getActiveFrontendRelease(http, projectRef, deploymentId) {
|
|
|
16523
16566
|
const snapshot = await readActiveFrontendRelease(http, projectRef, deploymentId);
|
|
16524
16567
|
return "failure" in snapshot ? snapshot.failure : toolResponse(snapshot.inventory);
|
|
16525
16568
|
}
|
|
16569
|
+
async function publishFrontendRelease(http, projectRef, deploymentId, archivePath, expectedTreeSha256) {
|
|
16570
|
+
const authority = await readActiveFrontendRelease(http, projectRef, deploymentId);
|
|
16571
|
+
if ("failure" in authority)
|
|
16572
|
+
return authority.failure;
|
|
16573
|
+
const inventory = authority.inventory;
|
|
16574
|
+
const current = inventory.releases[0];
|
|
16575
|
+
if (current?.tree_sha256 === expectedTreeSha256) {
|
|
16576
|
+
return toolResponse({
|
|
16577
|
+
operation: "frontend.deploy",
|
|
16578
|
+
project_ref: projectRef,
|
|
16579
|
+
deployment_id: deploymentId,
|
|
16580
|
+
active_release_id: inventory.active_release_id,
|
|
16581
|
+
activation_id: inventory.active_activation_id,
|
|
16582
|
+
release: current,
|
|
16583
|
+
unchanged: true
|
|
16584
|
+
});
|
|
16585
|
+
}
|
|
16586
|
+
const uploaded = await uploadFrontendRelease(http, projectRef, deploymentId, archivePath);
|
|
16587
|
+
if (uploaded.isError)
|
|
16588
|
+
return uploaded;
|
|
16589
|
+
const value = JSON.parse(uploaded.content[0].text);
|
|
16590
|
+
const envelope = value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
16591
|
+
const candidate = envelope?.release;
|
|
16592
|
+
const release = candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate : null;
|
|
16593
|
+
if (!release || release.tree_sha256 !== expectedTreeSha256 || typeof release.release_id !== "string" || !RELEASE_ID_PATTERN.test(release.release_id)) {
|
|
16594
|
+
return releaseFailure("frontend.deploy", "INVALID_RESPONSE", 200);
|
|
16595
|
+
}
|
|
16596
|
+
const mutationId = crypto.randomUUID();
|
|
16597
|
+
const activated = await activateFrontendRelease(http, {
|
|
16598
|
+
projectRef,
|
|
16599
|
+
deploymentId,
|
|
16600
|
+
releaseId: release.release_id,
|
|
16601
|
+
mutationId,
|
|
16602
|
+
expectedActiveReleaseId: inventory.active_release_id ?? "absent",
|
|
16603
|
+
expectedActivationId: inventory.active_activation_id ?? "absent"
|
|
16604
|
+
});
|
|
16605
|
+
const activatedPayload = JSON.parse(activated.content[0].text);
|
|
16606
|
+
const active = activatedPayload.release;
|
|
16607
|
+
const treeMismatch = !activated.isError && (!active || typeof active !== "object" || !("tree_sha256" in active) || active.tree_sha256 !== expectedTreeSha256);
|
|
16608
|
+
return {
|
|
16609
|
+
...toolResponse({
|
|
16610
|
+
...treeMismatch ? { ok: false, error: { code: "OUTCOME_UNKNOWN", http_status: 200 } } : activatedPayload,
|
|
16611
|
+
operation: "frontend.deploy",
|
|
16612
|
+
mutation_id: mutationId,
|
|
16613
|
+
target_release_id: release.release_id,
|
|
16614
|
+
previous_release_id: inventory.active_release_id,
|
|
16615
|
+
previous_activation_id: inventory.active_activation_id
|
|
16616
|
+
}),
|
|
16617
|
+
...activated.isError || treeMismatch ? { isError: true } : {}
|
|
16618
|
+
};
|
|
16619
|
+
}
|
|
16526
16620
|
async function rollbackFrontendRelease(http, projectRef, deploymentId, releaseId) {
|
|
16527
16621
|
if (releaseId !== undefined && !RELEASE_ID_PATTERN.test(releaseId)) {
|
|
16528
16622
|
throw new Error("'release_id' must be a SHA-256 digest");
|
|
@@ -28186,6 +28280,7 @@ var deployToolSchema = {
|
|
|
28186
28280
|
ref: optional(String2(), "Project ref (defaults to the linked project)"),
|
|
28187
28281
|
cwd: optional(String2(), "Project directory (default: current directory)"),
|
|
28188
28282
|
skip_build: optional(Boolean2(), "Use an existing output directory without building"),
|
|
28283
|
+
assets_only: optional(Boolean2(), "Publish only configured static assets; leave backend Functions, schedules and migrations unchanged"),
|
|
28189
28284
|
json: optional(Boolean2(), "Print only the final JSON result")
|
|
28190
28285
|
};
|
|
28191
28286
|
function record4(candidate) {
|
|
@@ -28280,6 +28375,7 @@ function deployTargetConfig(candidate, name) {
|
|
|
28280
28375
|
type: value.type,
|
|
28281
28376
|
root: optionalText(value.root, `targets.${name}.root`),
|
|
28282
28377
|
id: optionalText(value.id, `targets.${name}.id`),
|
|
28378
|
+
name: optionalText(value.name, `targets.${name}.name`),
|
|
28283
28379
|
slug: optionalText(value.slug, `targets.${name}.slug`),
|
|
28284
28380
|
buildCommand: optionalText(value.buildCommand, `targets.${name}.buildCommand`),
|
|
28285
28381
|
outputDirectory: optionalText(value.outputDirectory, `targets.${name}.outputDirectory`),
|
|
@@ -28330,6 +28426,7 @@ async function readDeployConfig(configRoot) {
|
|
|
28330
28426
|
targets: targetValues ? Object.fromEntries(Object.entries(targetValues).map(([name, value]) => [name, deployTargetConfig(value, name)])) : undefined,
|
|
28331
28427
|
frontend: frontend ? {
|
|
28332
28428
|
id: optionalText(frontend.id, "frontend.id"),
|
|
28429
|
+
name: optionalText(frontend.name, "frontend.name"),
|
|
28333
28430
|
root: optionalText(frontend.root, "frontend.root"),
|
|
28334
28431
|
buildCommand: optionalText(frontend.buildCommand, "frontend.buildCommand"),
|
|
28335
28432
|
outputDirectory: optionalText(frontend.outputDirectory, "frontend.outputDirectory"),
|
|
@@ -28392,13 +28489,22 @@ function deploymentList(candidate) {
|
|
|
28392
28489
|
throw new Error("Invalid frontend deployment list response");
|
|
28393
28490
|
return values.map(frontendDeployment);
|
|
28394
28491
|
}
|
|
28395
|
-
function selectDeployment(deployments, requestedId, projectName) {
|
|
28492
|
+
function selectDeployment(deployments, requestedId, projectName, requestedName) {
|
|
28396
28493
|
if (requestedId) {
|
|
28397
28494
|
const selected = deployments.find((deployment) => deployment.id === requestedId);
|
|
28398
28495
|
if (!selected)
|
|
28399
28496
|
throw new Error(`Frontend deployment '${requestedId}' was not found`);
|
|
28497
|
+
if (requestedName && selected.name !== requestedName) {
|
|
28498
|
+
throw new Error(`Frontend deployment '${requestedId}' does not match name '${requestedName}'`);
|
|
28499
|
+
}
|
|
28400
28500
|
return selected;
|
|
28401
28501
|
}
|
|
28502
|
+
if (requestedName) {
|
|
28503
|
+
const matches = deployments.filter((deployment) => deployment.name === requestedName);
|
|
28504
|
+
if (matches.length !== 1)
|
|
28505
|
+
throw new Error(`Expected exactly one frontend deployment named '${requestedName}'`);
|
|
28506
|
+
return matches[0];
|
|
28507
|
+
}
|
|
28402
28508
|
if (deployments.length === 1)
|
|
28403
28509
|
return deployments[0];
|
|
28404
28510
|
if (projectName) {
|
|
@@ -28416,6 +28522,7 @@ function selectFrontendTarget(configRoot, config) {
|
|
|
28416
28522
|
type: "frontend",
|
|
28417
28523
|
root: config.frontend?.root,
|
|
28418
28524
|
id: config.frontend?.id,
|
|
28525
|
+
name: config.frontend?.name,
|
|
28419
28526
|
buildCommand: config.frontend?.buildCommand,
|
|
28420
28527
|
outputDirectory: config.frontend?.outputDirectory,
|
|
28421
28528
|
buildEnv: config.frontend?.buildEnv
|
|
@@ -28580,7 +28687,7 @@ function payload(response) {
|
|
|
28580
28687
|
throw new Error("Deployment operation returned an invalid response");
|
|
28581
28688
|
return parsed;
|
|
28582
28689
|
}
|
|
28583
|
-
async function stageApplicationWebRelease(http, projectRef, environmentId, configRoot, skipBuild, json, environmentVariables) {
|
|
28690
|
+
async function stageApplicationWebRelease(http, projectRef, environmentId, configRoot, skipBuild, json, environmentVariables, assetsOnly = false) {
|
|
28584
28691
|
const target = selectFrontendTarget(configRoot, await readDeployConfig(configRoot));
|
|
28585
28692
|
if (!target)
|
|
28586
28693
|
return null;
|
|
@@ -28593,7 +28700,7 @@ async function stageApplicationWebRelease(http, projectRef, environmentId, confi
|
|
|
28593
28700
|
const listResponse = await http.get(`/v1/projects/${encodeURIComponent(projectRef)}/frontend/deployments`);
|
|
28594
28701
|
if (!listResponse.ok)
|
|
28595
28702
|
throw new Error(`Failed to list frontend deployments (HTTP ${listResponse.status})`);
|
|
28596
|
-
const selected = selectDeployment(deploymentList(listResponse.data), requestedId, await packageName(projectDirectory));
|
|
28703
|
+
const selected = selectDeployment(deploymentList(listResponse.data), requestedId, await packageName(projectDirectory), target.config.name);
|
|
28597
28704
|
const configuredBuildCommand = String(target.config.buildCommand || selected.buildCommand || "").trim();
|
|
28598
28705
|
const buildCommand = configuredBuildCommand || (skipBuild ? "" : await defaultBuildCommand(projectDirectory, configRoot));
|
|
28599
28706
|
const configuredOutput = String(target.config.outputDirectory || "").trim();
|
|
@@ -28606,6 +28713,9 @@ async function stageApplicationWebRelease(http, projectRef, environmentId, confi
|
|
|
28606
28713
|
}
|
|
28607
28714
|
const archive = await createFrontendArchive(outputDirectory);
|
|
28608
28715
|
try {
|
|
28716
|
+
if (assetsOnly) {
|
|
28717
|
+
return { result: await publishFrontendRelease(http, projectRef, selected.id, archive.archivePath, archive.treeSha256) };
|
|
28718
|
+
}
|
|
28609
28719
|
const uploaded = payload(await uploadProjectWebRelease(http, projectRef, environmentId, selected.id, archive.archivePath));
|
|
28610
28720
|
const release = record4(uploaded.release);
|
|
28611
28721
|
const releaseId = requiredString(release?.release_id, "release.release_id");
|
|
@@ -28635,7 +28745,23 @@ function registerDeployTools(server, http, options = {}) {
|
|
|
28635
28745
|
...config.application,
|
|
28636
28746
|
environmentId: options.environment || config.application.environmentId
|
|
28637
28747
|
} : undefined;
|
|
28638
|
-
|
|
28748
|
+
const legacyManifest = await hasProjectReleaseManifest(configRoot);
|
|
28749
|
+
const assetsOnly = args.assets_only === true || !application?.id && selectFrontendTarget(configRoot, config) !== null && !legacyManifest && !Object.values(config.targets ?? {}).some((target) => target.type === "edge_function");
|
|
28750
|
+
if (assetsOnly) {
|
|
28751
|
+
if (!selectFrontendTarget(configRoot, config)) {
|
|
28752
|
+
throw new Error("Static asset deployment requires a frontend configuration in supacloud.json");
|
|
28753
|
+
}
|
|
28754
|
+
const environmentId = options.environment?.trim() || application?.environmentId?.trim();
|
|
28755
|
+
if (!environmentId || !Check2(ApplicationIdSchema, environmentId)) {
|
|
28756
|
+
throw new Error("Static asset deployment requires SUPACLOUD_ENV");
|
|
28757
|
+
}
|
|
28758
|
+
await requireProjectDeploymentProtocol(http, projectRef, environmentId);
|
|
28759
|
+
const staged = await stageApplicationWebRelease(http, projectRef, environmentId, configRoot, args.skip_build === true, args.json === true, options.environmentVariables, true);
|
|
28760
|
+
if (!staged?.result)
|
|
28761
|
+
throw new Error("Static asset deployment did not produce a receipt");
|
|
28762
|
+
return staged.result;
|
|
28763
|
+
}
|
|
28764
|
+
if (legacyManifest) {
|
|
28639
28765
|
throw new Error(`${DEPLOYMENT_UPGRADE} Replace deploy-manifest.json with the current application delivery configuration; no remote mutation was performed.`);
|
|
28640
28766
|
}
|
|
28641
28767
|
if (application?.id) {
|
|
@@ -28963,7 +29089,7 @@ var TEST_PROFILE = [
|
|
|
28963
29089
|
"SUPACLOUD_API_URL=https://management.test.example.com",
|
|
28964
29090
|
"SUPACLOUD_API_TOKEN=<test-management-api-token>",
|
|
28965
29091
|
"SUPACLOUD_PROJECT_REF=<test-project-ref>",
|
|
28966
|
-
"SUPACLOUD_APPLICATION_ID=<application-id>",
|
|
29092
|
+
"# Optional for executable application delivery: SUPACLOUD_APPLICATION_ID=<application-id>",
|
|
28967
29093
|
""
|
|
28968
29094
|
].join(`
|
|
28969
29095
|
`);
|
|
@@ -28972,7 +29098,7 @@ var PRODUCTION_PROFILE = [
|
|
|
28972
29098
|
"SUPACLOUD_API_URL=https://management.example.com",
|
|
28973
29099
|
"SUPACLOUD_API_TOKEN=<production-management-api-token>",
|
|
28974
29100
|
"SUPACLOUD_PROJECT_REF=<production-project-ref>",
|
|
28975
|
-
"SUPACLOUD_APPLICATION_ID=<application-id>",
|
|
29101
|
+
"# Optional for executable application delivery: SUPACLOUD_APPLICATION_ID=<application-id>",
|
|
28976
29102
|
""
|
|
28977
29103
|
].join(`
|
|
28978
29104
|
`);
|
|
@@ -29096,7 +29222,7 @@ async function initializeProject(request, options) {
|
|
|
29096
29222
|
},
|
|
29097
29223
|
next: [
|
|
29098
29224
|
"cp .env.supacloud.test.example .env.supacloud.test",
|
|
29099
|
-
"
|
|
29225
|
+
"Configure frontend assets; set SUPACLOUD_APPLICATION_ID only for executable application delivery.",
|
|
29100
29226
|
"supacloud env check",
|
|
29101
29227
|
"supacloud --env test deploy"
|
|
29102
29228
|
]
|
|
@@ -29144,12 +29270,12 @@ function statusMissing(context) {
|
|
|
29144
29270
|
}
|
|
29145
29271
|
return ["SUPACLOUD_API_URL", "SUPACLOUD_API_TOKEN", "SUPACLOUD_PROJECT_REF"];
|
|
29146
29272
|
}
|
|
29147
|
-
function deployMissing(context, application) {
|
|
29273
|
+
function deployMissing(context, application, hasFrontend = false) {
|
|
29148
29274
|
const missing = statusMissing(context);
|
|
29149
29275
|
if (context.credentialScope !== "management") {
|
|
29150
29276
|
return [...missing, "Management API context"];
|
|
29151
29277
|
}
|
|
29152
|
-
if (!Check2(ApplicationIdSchema, context.applicationId || application?.id)) {
|
|
29278
|
+
if (!(hasFrontend && !context.applicationId && !application) && !Check2(ApplicationIdSchema, context.applicationId || application?.id)) {
|
|
29153
29279
|
missing.push("valid SUPACLOUD_APPLICATION_ID or supacloud.json application.id");
|
|
29154
29280
|
}
|
|
29155
29281
|
if (!Check2(ApplicationIdSchema, context.applicationEnvironmentId || application?.environmentId)) {
|
|
@@ -29169,7 +29295,8 @@ async function inspectProfile(profile) {
|
|
|
29169
29295
|
throw error;
|
|
29170
29296
|
});
|
|
29171
29297
|
const config = record5(JSON.parse(configText));
|
|
29172
|
-
const
|
|
29298
|
+
const hasFrontend = record5(config?.frontend) !== null || Object.values(record5(config?.targets) ?? {}).some((target) => record5(target)?.type === "frontend");
|
|
29299
|
+
const deploy = deployMissing(context, record5(config?.application), hasFrontend);
|
|
29173
29300
|
return {
|
|
29174
29301
|
name: profile.name,
|
|
29175
29302
|
path: profile.path,
|
|
@@ -29265,7 +29392,7 @@ function registerDeveloperExperienceTools(server, options = {}) {
|
|
|
29265
29392
|
// package.json
|
|
29266
29393
|
var package_default = {
|
|
29267
29394
|
name: "@supacloud/cli",
|
|
29268
|
-
version: "0.96.
|
|
29395
|
+
version: "0.96.1",
|
|
29269
29396
|
description: "Project-scoped CLI for SupaCloud users",
|
|
29270
29397
|
type: "module",
|
|
29271
29398
|
main: "./dist/index.js",
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment
|
|
1
|
+
export declare const DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment commands are no longer supported. Upgrade with `npm install -g @supacloud/cli@latest`, configure frontend in supacloud.json for static assets, or application.id and application.environmentId for executable application delivery, then run `supacloud deploy`. Use `supacloud deploy --assets_only` to publish only Web assets in a mixed repository. SupaCloud owns activation; do not retry with legacy commands.";
|
|
2
2
|
export declare function assertCurrentDeploymentInput(tool: string, input: unknown): void;
|
|
@@ -26,6 +26,7 @@ export declare const deployToolSchema: {
|
|
|
26
26
|
ref: Type.TOptional<Type.TString>;
|
|
27
27
|
cwd: Type.TOptional<Type.TString>;
|
|
28
28
|
skip_build: Type.TOptional<Type.TBoolean>;
|
|
29
|
+
assets_only: Type.TOptional<Type.TBoolean>;
|
|
29
30
|
json: Type.TOptional<Type.TBoolean>;
|
|
30
31
|
};
|
|
31
32
|
export declare function findDeployConfigRoot(startDirectory: string, environmentName?: string): Promise<string>;
|
|
@@ -15,7 +15,7 @@ export declare const environmentToolSchema: ToolSchema;
|
|
|
15
15
|
declare function outputDirectoryFor(manifest: PackageManifest): string;
|
|
16
16
|
declare function profileNameFromFile(name: string): string | null;
|
|
17
17
|
declare function statusMissing(context: ResolvedContext): string[];
|
|
18
|
-
declare function deployMissing(context: ResolvedContext, application?: Record<string, unknown> | null): string[];
|
|
18
|
+
declare function deployMissing(context: ResolvedContext, application?: Record<string, unknown> | null, hasFrontend?: boolean): string[];
|
|
19
19
|
export declare function registerDeveloperExperienceTools(server: ToolServer, options?: DeveloperExperienceOptions): void;
|
|
20
20
|
export declare const __internal: {
|
|
21
21
|
outputDirectoryFor: typeof outputDirectoryFor;
|
|
@@ -46,6 +46,7 @@ export declare function uploadProjectWebRelease(http: FrontendReleaseHttp, proje
|
|
|
46
46
|
export declare function uploadFrontendSource(http: FrontendReleaseHttp, projectRef: string, deploymentId: string, archivePath: string): Promise<ToolResponse>;
|
|
47
47
|
export declare function getActiveFrontendRelease(http: FrontendReleaseHttp, projectRef: string, deploymentId: string): Promise<ToolResponse>;
|
|
48
48
|
export declare function readFrontendReleaseAuthority(http: FrontendReleaseHttp, projectRef: string, deploymentId: string): Promise<ToolResponse>;
|
|
49
|
+
export declare function publishFrontendRelease(http: FrontendReleaseHttp, projectRef: string, deploymentId: string, archivePath: string, expectedTreeSha256: string): Promise<ToolResponse>;
|
|
49
50
|
export declare function rollbackFrontendRelease(http: FrontendReleaseHttp, projectRef: string, deploymentId: string, releaseId?: string): Promise<ToolResponse>;
|
|
50
51
|
export declare function activateFrontendRelease(http: FrontendReleaseHttp, input: {
|
|
51
52
|
projectRef: string;
|
package/dist/tool-runtime.js
CHANGED
|
@@ -131,7 +131,7 @@ import { Type as Type2 } from "typebox";
|
|
|
131
131
|
import { Value as Value2 } from "typebox/value";
|
|
132
132
|
|
|
133
133
|
// src/shared/deployment-upgrade.ts
|
|
134
|
-
var DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment
|
|
134
|
+
var DEPLOYMENT_UPGRADE = "DEPLOYMENT_UPGRADE_REQUIRED: Legacy deployment commands are no longer supported. Upgrade with `npm install -g @supacloud/cli@latest`, configure frontend in supacloud.json for static assets, or application.id and application.environmentId for executable application delivery, then run `supacloud deploy`. Use `supacloud deploy --assets_only` to publish only Web assets in a mixed repository. SupaCloud owns activation; do not retry with legacy commands.";
|
|
135
135
|
var removedFrontendActions = new Set([
|
|
136
136
|
"deploy_git",
|
|
137
137
|
"deploy_upload",
|