@supacloud/cli 0.83.0 → 0.84.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/README.md +5 -3
- package/dist/index.js +187 -85
- package/dist/shared/tools/app-tools.d.ts +1 -0
- package/dist/shared/tools/application-preview-tools.d.ts +11 -11
- package/dist/shared/tools/application-preview.test.d.ts +1 -0
- package/dist/shared/tools/application-tools.d.ts +1 -1
- package/dist/shared/tools/application-workflow-schemas.d.ts +20 -20
- package/dist/shared/transports/http.d.ts +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -86,6 +86,7 @@ supacloud-cli app preview-plan --env test --id orders --environment_id test --re
|
|
|
86
86
|
supacloud-cli app preview --env test --id orders --environment_id test --release_id RELEASE_SHA256 --configuration_id CONFIG_UUID --ttl_seconds 3600 --wait --timeout_seconds 300
|
|
87
87
|
supacloud-cli app previews --env test --id orders --environment_id test
|
|
88
88
|
supacloud-cli app preview-status --env test --id orders --environment_id test --preview_id PREVIEW_UUID --wait --timeout_seconds 300
|
|
89
|
+
supacloud-cli app preview-reconcile --env test --id orders --environment_id test --preview_id PREVIEW_UUID
|
|
89
90
|
supacloud-cli app preview-cleanup --env test --id orders --environment_id test --preview_id PREVIEW_UUID
|
|
90
91
|
```
|
|
91
92
|
|
|
@@ -114,9 +115,10 @@ query or identity drift ends it with nonzero status. A wait timeout returns
|
|
|
114
115
|
same-ID continuation in `reconciliation`. It does not mark provisioning failed,
|
|
115
116
|
retry a failed lifecycle GET, delete resources or promote an environment.
|
|
116
117
|
|
|
117
|
-
`preview-plan`
|
|
118
|
-
provisioning
|
|
119
|
-
|
|
118
|
+
`preview-plan`, `previews` and `preview-status` are read-only. They never resume
|
|
119
|
+
persisted provisioning. Use `preview-reconcile` to explicitly resume a selected
|
|
120
|
+
Preview ID; it is classified as a write, including in read-only and production
|
|
121
|
+
profiles. The platform may clean eligible expired
|
|
120
122
|
previews, but never interrupts a serving preview or empties nonempty Storage
|
|
121
123
|
automatically. Explicit cleanup remains available. Failed previews return
|
|
122
124
|
nonzero with the validated receipt and cleanup state. Unknown create outcomes
|
package/dist/index.js
CHANGED
|
@@ -9152,8 +9152,8 @@ function resolveSupaCloudContext(env = process.env, cwd = process.cwd(), selecti
|
|
|
9152
9152
|
var ACTION_POLICY = {
|
|
9153
9153
|
deploy: { write: ["deploy"] },
|
|
9154
9154
|
applications: {
|
|
9155
|
-
read: ["list_releases", "get_release", "get_runtime", "get_deployment_evidence", "get_configuration", "get_release_transfer_plan", "get_promotion_plan", "get_rollback_snapshot", "get_history", "get_deploy_plan", "
|
|
9156
|
-
write: ["upload_release", "put_configuration", "transfer_release", "promote_application", "reconcile_promotion", "create_preview", "
|
|
9155
|
+
read: ["list_releases", "get_release", "get_runtime", "get_deployment_evidence", "get_configuration", "get_release_transfer_plan", "get_promotion_plan", "get_promotion_status", "get_rollback_snapshot", "get_history", "get_deploy_plan", "logs", "get_preview_plan", "list_previews", "get_preview"],
|
|
9156
|
+
write: ["upload_release", "put_configuration", "transfer_release", "promote_application", "reconcile_promotion", "create_preview", "reconcile_preview", "cleanup_preview", "activate_release", "deploy_release", "rollback_release", "reconcile_activation", "retire_activation"]
|
|
9157
9157
|
},
|
|
9158
9158
|
project: {
|
|
9159
9159
|
read: ["get", "endpoints", "health", "logs", "api_keys", "settings", "tasks", "task_detail", "task_stats", "dlq", "background_settings"],
|
|
@@ -9248,8 +9248,8 @@ var ACTION_POLICY = {
|
|
|
9248
9248
|
ai: { local: ["show_skill", "install_skill"] },
|
|
9249
9249
|
app: {
|
|
9250
9250
|
local: ["init", "generate", "dev", "watch", "verify-plan", "compile", "check", "graph", "explain", "export-tools", "context", "doctor", "fix", "plan", "build"],
|
|
9251
|
-
read: ["status", "logs", "transfer-plan", "promote-plan", "rollback-plan", "history", "deploy-plan", "diff", "promote-status", "preview-plan"],
|
|
9252
|
-
write: ["upload", "configure", "transfer", "promote", "promote-reconcile", "deploy", "rollback", "reconcile", "retire", "preview", "
|
|
9251
|
+
read: ["status", "logs", "transfer-plan", "promote-plan", "rollback-plan", "history", "deploy-plan", "diff", "promote-status", "preview-plan", "previews", "preview-list", "preview-status"],
|
|
9252
|
+
write: ["upload", "configure", "transfer", "promote", "promote-reconcile", "deploy", "rollback", "reconcile", "retire", "preview", "preview-create", "preview-reconcile", "preview-cleanup"]
|
|
9253
9253
|
},
|
|
9254
9254
|
db: {
|
|
9255
9255
|
local: ["context", "lint", "explain", "diff", "role_sql"],
|
|
@@ -9826,7 +9826,10 @@ class HttpTransport {
|
|
|
9826
9826
|
return transportFailure(error);
|
|
9827
9827
|
}
|
|
9828
9828
|
}
|
|
9829
|
-
async delete(path, body) {
|
|
9829
|
+
async delete(path, body, options) {
|
|
9830
|
+
const timeoutMs = validatedPostTimeout(options);
|
|
9831
|
+
const maxJsonBytes = validatedJsonResponseLimit(options?.maxJsonBytes);
|
|
9832
|
+
const responseTimeoutMs = validatedResponseTimeout(options?.responseTimeoutMs);
|
|
9830
9833
|
try {
|
|
9831
9834
|
const serializedBody = serializedRequestBody(body);
|
|
9832
9835
|
const request = {
|
|
@@ -9834,7 +9837,11 @@ class HttpTransport {
|
|
|
9834
9837
|
headers: this.headers(),
|
|
9835
9838
|
...serializedBody === undefined ? {} : { body: serializedBody }
|
|
9836
9839
|
};
|
|
9837
|
-
const res = await fetchWithRetry(`${this.baseUrl}${path}`, request,
|
|
9840
|
+
const res = await fetchWithRetry(`${this.baseUrl}${path}`, request, timeoutMs, this.insecureTls);
|
|
9841
|
+
if (maxJsonBytes !== undefined) {
|
|
9842
|
+
const data = await boundedResponseJson(res, maxJsonBytes, responseTimeoutMs);
|
|
9843
|
+
return data === null ? responseReadFailure(res.status) : { ok: res.ok, status: res.status, data };
|
|
9844
|
+
}
|
|
9838
9845
|
const data = await res.json().catch(() => null);
|
|
9839
9846
|
return { ok: res.ok, status: res.status, data };
|
|
9840
9847
|
} catch (error) {
|
|
@@ -10547,6 +10554,78 @@ function parseApplicationActivationHistory(value) {
|
|
|
10547
10554
|
}
|
|
10548
10555
|
return structuredClone(value);
|
|
10549
10556
|
}
|
|
10557
|
+
// node_modules/@supacloud/delivery/src/application-preview.ts
|
|
10558
|
+
var phaseStatus = Union([
|
|
10559
|
+
Literal("pending"),
|
|
10560
|
+
Literal("ready"),
|
|
10561
|
+
Literal("failed"),
|
|
10562
|
+
Literal("cleaned")
|
|
10563
|
+
]);
|
|
10564
|
+
var closed3 = { additionalProperties: false };
|
|
10565
|
+
var ApplicationPreviewReceiptSchema = _Object_({
|
|
10566
|
+
schema: Literal("supacloud.application-preview.v1"),
|
|
10567
|
+
preview_id: String2({ pattern: "^[a-f0-9-]{8,64}$" }),
|
|
10568
|
+
project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
|
|
10569
|
+
application_id: ApplicationIdSchema,
|
|
10570
|
+
environment_id: ApplicationIdSchema,
|
|
10571
|
+
release_id: ApplicationReleaseIdSchema,
|
|
10572
|
+
expires_at: Optional(Union([String2({
|
|
10573
|
+
pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$",
|
|
10574
|
+
maxLength: 24
|
|
10575
|
+
}), Null()])),
|
|
10576
|
+
status: Union([
|
|
10577
|
+
Literal("planned"),
|
|
10578
|
+
Literal("provisioning"),
|
|
10579
|
+
Literal("ready"),
|
|
10580
|
+
Literal("failed"),
|
|
10581
|
+
Literal("cleaned")
|
|
10582
|
+
]),
|
|
10583
|
+
resources: _Object_({
|
|
10584
|
+
build_artifact: _Object_({ status: phaseStatus, release_id: ApplicationReleaseIdSchema }, closed3),
|
|
10585
|
+
database_branch: _Object_({
|
|
10586
|
+
status: phaseStatus,
|
|
10587
|
+
branch_ref: String2({ pattern: "^[A-Za-z0-9_-]{1,20}$" }),
|
|
10588
|
+
data_mode: Union([Literal("schema_only"), Literal("full_clone")])
|
|
10589
|
+
}, closed3),
|
|
10590
|
+
queue_namespace: _Object_({
|
|
10591
|
+
status: phaseStatus,
|
|
10592
|
+
namespace: String2({ minLength: 1, maxLength: 128 })
|
|
10593
|
+
}, closed3),
|
|
10594
|
+
storage_namespace: _Object_({
|
|
10595
|
+
status: phaseStatus,
|
|
10596
|
+
namespace: String2({ minLength: 1, maxLength: 128 })
|
|
10597
|
+
}, closed3),
|
|
10598
|
+
test_secret: _Object_({
|
|
10599
|
+
status: phaseStatus,
|
|
10600
|
+
name: String2({ minLength: 1, maxLength: 128 }),
|
|
10601
|
+
value_issued: Literal(false)
|
|
10602
|
+
}, closed3),
|
|
10603
|
+
configuration_revision: _Object_({
|
|
10604
|
+
status: phaseStatus,
|
|
10605
|
+
configuration_id: Union([ApplicationConfigurationIdSchema, Null()])
|
|
10606
|
+
}, closed3),
|
|
10607
|
+
application_activation: _Object_({
|
|
10608
|
+
status: phaseStatus,
|
|
10609
|
+
activation_id: Union([ApplicationActivationIdSchema, Null()])
|
|
10610
|
+
}, closed3),
|
|
10611
|
+
smoke_test: _Object_({
|
|
10612
|
+
status: phaseStatus,
|
|
10613
|
+
checks: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 32 }),
|
|
10614
|
+
passed: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 32 }),
|
|
10615
|
+
failed: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 32 })
|
|
10616
|
+
}, closed3)
|
|
10617
|
+
}, closed3),
|
|
10618
|
+
cleanup: _Object_({
|
|
10619
|
+
required: Boolean2(),
|
|
10620
|
+
completed: Boolean2(),
|
|
10621
|
+
error: Union([String2({ minLength: 1, maxLength: 128 }), Null()])
|
|
10622
|
+
}, closed3)
|
|
10623
|
+
}, closed3);
|
|
10624
|
+
function applicationPreviewBranchRef(previewId) {
|
|
10625
|
+
if (!/^[a-f0-9-]{8,64}$/.test(previewId))
|
|
10626
|
+
throw new Error("Invalid preview ID");
|
|
10627
|
+
return `pv${previewId.replace(/-/g, "").slice(0, 18)}`;
|
|
10628
|
+
}
|
|
10550
10629
|
// node_modules/@supacloud/delivery/src/application-release-transfer.ts
|
|
10551
10630
|
var projectRef = String2({ pattern: "^[A-Za-z0-9_-]{1,20}$" });
|
|
10552
10631
|
var source = _Object_({
|
|
@@ -10594,7 +10673,7 @@ function parseApplicationReleaseTransferResult(candidate) {
|
|
|
10594
10673
|
return candidate;
|
|
10595
10674
|
}
|
|
10596
10675
|
// node_modules/@supacloud/delivery/src/deployment-evidence.ts
|
|
10597
|
-
var
|
|
10676
|
+
var closed4 = { additionalProperties: false };
|
|
10598
10677
|
var sha256 = String2({ pattern: "^[a-f0-9]{64}$" });
|
|
10599
10678
|
var isoDate = String2({ minLength: 20, maxLength: 40 });
|
|
10600
10679
|
var status = Union([
|
|
@@ -10621,19 +10700,19 @@ var DatabaseProviderSchema = _Object_({
|
|
|
10621
10700
|
Literal("not-proven"),
|
|
10622
10701
|
Literal("failed")
|
|
10623
10702
|
])
|
|
10624
|
-
},
|
|
10703
|
+
}, closed4),
|
|
10625
10704
|
backup: _Object_({
|
|
10626
10705
|
status,
|
|
10627
10706
|
latest_success_at: Union([isoDate, Null()]),
|
|
10628
10707
|
freshness_seconds: Union([Integer({ minimum: 0 }), Null()])
|
|
10629
|
-
},
|
|
10708
|
+
}, closed4),
|
|
10630
10709
|
recovery: _Object_({
|
|
10631
10710
|
status,
|
|
10632
10711
|
drill_id: Union([String2({ minLength: 1, maxLength: 128 }), Null()]),
|
|
10633
10712
|
rpo_seconds: Union([Integer({ minimum: 0 }), Null()]),
|
|
10634
10713
|
rto_seconds: Union([Integer({ minimum: 0 }), Null()])
|
|
10635
|
-
},
|
|
10636
|
-
},
|
|
10714
|
+
}, closed4)
|
|
10715
|
+
}, closed4);
|
|
10637
10716
|
var componentName = Union([
|
|
10638
10717
|
Literal("management-api"),
|
|
10639
10718
|
Literal("web-console"),
|
|
@@ -10651,7 +10730,7 @@ var DeploymentComponentEvidenceSchema = _Object_({
|
|
|
10651
10730
|
status,
|
|
10652
10731
|
health_check: Union([String2({ minLength: 1, maxLength: 256 }), Null()]),
|
|
10653
10732
|
checked_at: Union([isoDate, Null()])
|
|
10654
|
-
},
|
|
10733
|
+
}, closed4);
|
|
10655
10734
|
var DeploymentEvidenceSchema = _Object_({
|
|
10656
10735
|
schema: Literal(DEPLOYMENT_EVIDENCE_SCHEMA),
|
|
10657
10736
|
status: evidenceStatus,
|
|
@@ -10660,33 +10739,33 @@ var DeploymentEvidenceSchema = _Object_({
|
|
|
10660
10739
|
project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
|
|
10661
10740
|
application_id: ApplicationIdSchema,
|
|
10662
10741
|
environment_id: ApplicationIdSchema
|
|
10663
|
-
},
|
|
10742
|
+
}, closed4),
|
|
10664
10743
|
source: _Object_({
|
|
10665
10744
|
commit_sha: Union([String2({ pattern: "^[0-9a-f]{7,64}$" }), Null()]),
|
|
10666
10745
|
manifest_sha256: sha256,
|
|
10667
10746
|
contract_schema: Union([String2({ minLength: 1, maxLength: 128 }), Null()]),
|
|
10668
10747
|
environment_binding_version: Union([sha256, Null()])
|
|
10669
|
-
},
|
|
10748
|
+
}, closed4),
|
|
10670
10749
|
database: DatabaseProviderSchema,
|
|
10671
10750
|
components: _Array_(DeploymentComponentEvidenceSchema, { minItems: 1, maxItems: 32 }),
|
|
10672
10751
|
activation: _Object_({
|
|
10673
10752
|
release_id: ApplicationReleaseIdSchema,
|
|
10674
10753
|
configuration_id: ApplicationConfigurationIdSchema,
|
|
10675
10754
|
activation_id: ApplicationConfigurationIdSchema
|
|
10676
|
-
},
|
|
10755
|
+
}, closed4),
|
|
10677
10756
|
health: _Object_({
|
|
10678
10757
|
status,
|
|
10679
10758
|
checked_at: Union([isoDate, Null()]),
|
|
10680
10759
|
authenticated_smoke: status
|
|
10681
|
-
},
|
|
10760
|
+
}, closed4),
|
|
10682
10761
|
rollback: _Object_({
|
|
10683
10762
|
release_id: Union([ApplicationReleaseIdSchema, Null()]),
|
|
10684
10763
|
configuration_id: Union([ApplicationConfigurationIdSchema, Null()]),
|
|
10685
10764
|
status: Union([Literal("ready"), Literal("not-ready"), Literal("unknown")]),
|
|
10686
10765
|
result: Union([status, Null()])
|
|
10687
|
-
},
|
|
10766
|
+
}, closed4),
|
|
10688
10767
|
notes: _Array_(String2({ minLength: 1, maxLength: 512 }), { maxItems: 32 })
|
|
10689
|
-
},
|
|
10768
|
+
}, closed4);
|
|
10690
10769
|
function isIsoDate(value) {
|
|
10691
10770
|
return Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
|
|
10692
10771
|
}
|
|
@@ -10719,7 +10798,7 @@ function parseDeploymentEvidence(value) {
|
|
|
10719
10798
|
return structuredClone(value);
|
|
10720
10799
|
}
|
|
10721
10800
|
// node_modules/@supacloud/delivery/src/application-promotion.ts
|
|
10722
|
-
var
|
|
10801
|
+
var closed5 = { additionalProperties: false };
|
|
10723
10802
|
var projectRef2 = String2({ pattern: "^[a-z0-9-]{1,20}$" });
|
|
10724
10803
|
var sha2562 = ApplicationReleaseIdSchema;
|
|
10725
10804
|
var nullableActivation = Union([ApplicationActivationIdSchema, Null()]);
|
|
@@ -10756,7 +10835,7 @@ var ApplicationPromotionPlanSchema = _Object_({
|
|
|
10756
10835
|
environment_id: ApplicationIdSchema,
|
|
10757
10836
|
release_id: sha2562,
|
|
10758
10837
|
...observation
|
|
10759
|
-
},
|
|
10838
|
+
}, closed5),
|
|
10760
10839
|
target: _Object_({
|
|
10761
10840
|
candidate_release_id: sha2562,
|
|
10762
10841
|
current_release_id: Union([sha2562, Null()]),
|
|
@@ -10764,18 +10843,18 @@ var ApplicationPromotionPlanSchema = _Object_({
|
|
|
10764
10843
|
configuration_id: Union([ApplicationConfigurationIdSchema, Null()]),
|
|
10765
10844
|
configuration: Union([ApplicationConfigurationViewSchema, Null()]),
|
|
10766
10845
|
...observation
|
|
10767
|
-
},
|
|
10846
|
+
}, closed5),
|
|
10768
10847
|
migrations: _Object_({
|
|
10769
10848
|
ledger_digest: sha2562,
|
|
10770
10849
|
ledger_compatible: Boolean2(),
|
|
10771
10850
|
project_migrations_applied: Boolean2(),
|
|
10772
10851
|
pending_versions: _Array_(String2({ pattern: "^\\d{1,20}$" }), { maxItems: 4096, uniqueItems: true }),
|
|
10773
10852
|
operator_provisioning_required: Boolean2()
|
|
10774
|
-
},
|
|
10853
|
+
}, closed5),
|
|
10775
10854
|
backup: _Object_({
|
|
10776
10855
|
required: Boolean2(),
|
|
10777
10856
|
confirmed: Literal(false)
|
|
10778
|
-
},
|
|
10857
|
+
}, closed5),
|
|
10779
10858
|
action: Union([Literal("promote"), Literal("no-op"), Literal("blocked")]),
|
|
10780
10859
|
blockers: _Array_(Enum([...blocker]), {
|
|
10781
10860
|
maxItems: blocker.length,
|
|
@@ -10784,7 +10863,7 @@ var ApplicationPromotionPlanSchema = _Object_({
|
|
|
10784
10863
|
steps: _Array_(String2({ minLength: 1, maxLength: 64 }), { maxItems: 8, uniqueItems: true }),
|
|
10785
10864
|
execution_performed: Literal(false),
|
|
10786
10865
|
data_recovery: Literal("separate-required")
|
|
10787
|
-
},
|
|
10866
|
+
}, closed5);
|
|
10788
10867
|
function applicationPromotionPlanDigest(value) {
|
|
10789
10868
|
return digest(canonical(value));
|
|
10790
10869
|
}
|
|
@@ -16970,7 +17049,7 @@ async function fetchMutationStatus(http, ref, mutationId) {
|
|
|
16970
17049
|
}
|
|
16971
17050
|
|
|
16972
17051
|
// src/shared/tools/application-workflow-schemas.ts
|
|
16973
|
-
var
|
|
17052
|
+
var closed6 = { additionalProperties: false };
|
|
16974
17053
|
var ref5 = String2({ pattern: "^[A-Za-z0-9_-]{1,20}$" });
|
|
16975
17054
|
var uuid = ApplicationActivationIdSchema2;
|
|
16976
17055
|
var nullableUuid = Union([uuid, Null()]);
|
|
@@ -16984,7 +17063,7 @@ var ApplicationPromotionResultSchema = _Object_({
|
|
|
16984
17063
|
plan_sha256: ApplicationReleaseIdSchema2,
|
|
16985
17064
|
action: Literal("promote"),
|
|
16986
17065
|
replayed: Boolean2()
|
|
16987
|
-
},
|
|
17066
|
+
}, closed6);
|
|
16988
17067
|
var ApplicationPromotionStatusSchema = _Object_({
|
|
16989
17068
|
...scope2,
|
|
16990
17069
|
mutation: Unknown(),
|
|
@@ -17003,13 +17082,13 @@ var ApplicationPromotionStatusSchema = _Object_({
|
|
|
17003
17082
|
configuration_id: Union([ApplicationConfigurationIdSchema2, Null()]),
|
|
17004
17083
|
backup_id: Union([String2({ pattern: "^logical-full_[a-z0-9-]{1,20}_[a-f0-9]{32}$" }), Null()]),
|
|
17005
17084
|
data_recovery: Literal("separate-required")
|
|
17006
|
-
},
|
|
17007
|
-
},
|
|
17085
|
+
}, closed6)
|
|
17086
|
+
}, closed6);
|
|
17008
17087
|
var phase = Union([Literal("pending"), Literal("ready"), Literal("failed"), Literal("cleaned")]);
|
|
17009
17088
|
var previewId = String2({ pattern: "^[a-f0-9-]{8,64}$" });
|
|
17010
17089
|
var name = String2({ minLength: 1, maxLength: 256 });
|
|
17011
17090
|
var checks = _Array_(String2({ minLength: 1, maxLength: 128 }), { maxItems: 64, uniqueItems: true });
|
|
17012
|
-
var
|
|
17091
|
+
var ApplicationPreviewReceiptSchema2 = _Object_({
|
|
17013
17092
|
schema: Literal("supacloud.application-preview.v1"),
|
|
17014
17093
|
...scope2,
|
|
17015
17094
|
preview_id: previewId,
|
|
@@ -17023,35 +17102,35 @@ var ApplicationPreviewReceiptSchema = _Object_({
|
|
|
17023
17102
|
Literal("cleaned")
|
|
17024
17103
|
]),
|
|
17025
17104
|
resources: _Object_({
|
|
17026
|
-
build_artifact: _Object_({ status: phase, release_id: ApplicationReleaseIdSchema2 },
|
|
17105
|
+
build_artifact: _Object_({ status: phase, release_id: ApplicationReleaseIdSchema2 }, closed6),
|
|
17027
17106
|
database_branch: _Object_({
|
|
17028
17107
|
status: phase,
|
|
17029
17108
|
branch_ref: ref5,
|
|
17030
17109
|
data_mode: Union([Literal("schema_only"), Literal("full_clone")])
|
|
17031
|
-
},
|
|
17032
|
-
queue_namespace: _Object_({ status: phase, namespace: name },
|
|
17033
|
-
storage_namespace: _Object_({ status: phase, namespace: name },
|
|
17034
|
-
test_secret: _Object_({ status: phase, name, value_issued: Literal(false) },
|
|
17035
|
-
configuration_revision: _Object_({ status: phase, configuration_id: Union([ApplicationConfigurationIdSchema2, Null()]) },
|
|
17036
|
-
application_activation: _Object_({ status: phase, activation_id: nullableUuid },
|
|
17037
|
-
smoke_test: _Object_({ status: phase, checks, passed: checks, failed: checks },
|
|
17038
|
-
},
|
|
17110
|
+
}, closed6),
|
|
17111
|
+
queue_namespace: _Object_({ status: phase, namespace: name }, closed6),
|
|
17112
|
+
storage_namespace: _Object_({ status: phase, namespace: name }, closed6),
|
|
17113
|
+
test_secret: _Object_({ status: phase, name, value_issued: Literal(false) }, closed6),
|
|
17114
|
+
configuration_revision: _Object_({ status: phase, configuration_id: Union([ApplicationConfigurationIdSchema2, Null()]) }, closed6),
|
|
17115
|
+
application_activation: _Object_({ status: phase, activation_id: nullableUuid }, closed6),
|
|
17116
|
+
smoke_test: _Object_({ status: phase, checks, passed: checks, failed: checks }, closed6)
|
|
17117
|
+
}, closed6),
|
|
17039
17118
|
cleanup: _Object_({
|
|
17040
17119
|
required: Boolean2(),
|
|
17041
17120
|
completed: Boolean2(),
|
|
17042
17121
|
error: Union([String2({ pattern: "^[A-Z][A-Z0-9_]{0,63}$" }), Null()])
|
|
17043
|
-
},
|
|
17122
|
+
}, closed6),
|
|
17044
17123
|
branch_name: Optional(String2({ minLength: 1, maxLength: 80 })),
|
|
17045
17124
|
queue_name: Optional(name),
|
|
17046
17125
|
test_secret_name: Optional(name),
|
|
17047
17126
|
source_configuration_id: Optional(Union([ApplicationConfigurationIdSchema2, Null()])),
|
|
17048
17127
|
created_at: Optional(timestamp2),
|
|
17049
17128
|
updated_at: Optional(timestamp2)
|
|
17050
|
-
},
|
|
17129
|
+
}, closed6);
|
|
17051
17130
|
var previewListSchema = _Object_({
|
|
17052
17131
|
...scope2,
|
|
17053
|
-
previews: _Array_(
|
|
17054
|
-
},
|
|
17132
|
+
previews: _Array_(ApplicationPreviewReceiptSchema2, { maxItems: 1000 })
|
|
17133
|
+
}, closed6);
|
|
17055
17134
|
function assertScope(value, identity) {
|
|
17056
17135
|
if (value.project_ref !== identity.project_ref || value.application_id !== identity.application_id || value.environment_id !== identity.environment_id)
|
|
17057
17136
|
throw new Error("Application workflow scope mismatch");
|
|
@@ -17078,7 +17157,7 @@ function parsePromotionStatus(value, identity) {
|
|
|
17078
17157
|
return structuredClone({ ...value, mutation });
|
|
17079
17158
|
}
|
|
17080
17159
|
function parsePreviewReceipt(value, identity) {
|
|
17081
|
-
if (!Check2(
|
|
17160
|
+
if (!Check2(ApplicationPreviewReceiptSchema2, value))
|
|
17082
17161
|
throw new Error("Invalid preview receipt");
|
|
17083
17162
|
assertScope(value, identity);
|
|
17084
17163
|
if (identity.preview_id !== undefined && value.preview_id !== identity.preview_id || identity.release_id !== undefined && value.release_id !== identity.release_id || identity.branch_ref !== undefined && value.resources.database_branch.branch_ref !== identity.branch_ref || identity.data_mode !== undefined && value.resources.database_branch.data_mode !== identity.data_mode || identity.configuration_id !== undefined && value.source_configuration_id !== identity.configuration_id || value.resources.build_artifact.release_id !== value.release_id)
|
|
@@ -17158,11 +17237,13 @@ async function applicationReleaseTransfer(http, input, project) {
|
|
|
17158
17237
|
}
|
|
17159
17238
|
|
|
17160
17239
|
// src/shared/tools/application-preview-tools.ts
|
|
17240
|
+
import { randomUUID } from "node:crypto";
|
|
17161
17241
|
var APPLICATION_PREVIEW_ACTIONS = [
|
|
17162
17242
|
"get_preview_plan",
|
|
17163
17243
|
"create_preview",
|
|
17164
17244
|
"list_previews",
|
|
17165
17245
|
"get_preview",
|
|
17246
|
+
"reconcile_preview",
|
|
17166
17247
|
"cleanup_preview"
|
|
17167
17248
|
];
|
|
17168
17249
|
var previewIdSchema = String2({ pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$" });
|
|
@@ -17174,7 +17255,7 @@ var timestampSchema = String2({
|
|
|
17174
17255
|
maxLength: 24
|
|
17175
17256
|
});
|
|
17176
17257
|
var APPLICATION_PREVIEW_FIELDS = {
|
|
17177
|
-
preview_id: optional(previewIdSchema, "[get_preview/cleanup_preview] Preview receipt ID"),
|
|
17258
|
+
preview_id: optional(previewIdSchema, "[get_preview/reconcile_preview/cleanup_preview] Preview receipt ID; create/plan may pin a stable ID"),
|
|
17178
17259
|
branch_ref: optional(branchRefSchema, "[get_preview_plan] Proposed branch ref; create assigns its own"),
|
|
17179
17260
|
branch_name: optional(String2({ minLength: 1, maxLength: 80 }), "[create_preview] Branch display name"),
|
|
17180
17261
|
data_mode: optional(stringEnum(["schema_only", "full_clone"]), "[get_preview_plan/create_preview] Default schema_only; full_clone copies rows"),
|
|
@@ -17194,7 +17275,7 @@ var receiptSchema = _Object_({
|
|
|
17194
17275
|
application_id: ApplicationIdSchema2,
|
|
17195
17276
|
environment_id: ApplicationIdSchema2,
|
|
17196
17277
|
release_id: ApplicationReleaseIdSchema2,
|
|
17197
|
-
expires_at: Union([timestampSchema, Null()]),
|
|
17278
|
+
expires_at: Optional(Union([timestampSchema, Null()])),
|
|
17198
17279
|
status: stringEnum(["planned", "provisioning", "ready", "failed", "cleaned"]),
|
|
17199
17280
|
resources: _Object_({
|
|
17200
17281
|
build_artifact: _Object_({ status: phase2, release_id: ApplicationReleaseIdSchema2 }, strict),
|
|
@@ -17236,10 +17317,11 @@ var mandatoryChecks = [
|
|
|
17236
17317
|
"tenant_runtime"
|
|
17237
17318
|
];
|
|
17238
17319
|
var actionFields = {
|
|
17239
|
-
get_preview_plan: ["release_id", "branch_ref", "data_mode", "configuration_id", "ttl_seconds"],
|
|
17240
|
-
create_preview: ["release_id", "configuration_id", "data_mode", "branch_name", "ttl_seconds", "wait", "timeout_seconds"],
|
|
17320
|
+
get_preview_plan: ["release_id", "preview_id", "branch_ref", "data_mode", "configuration_id", "ttl_seconds"],
|
|
17321
|
+
create_preview: ["release_id", "preview_id", "configuration_id", "data_mode", "branch_name", "ttl_seconds", "wait", "timeout_seconds"],
|
|
17241
17322
|
list_previews: [],
|
|
17242
17323
|
get_preview: ["preview_id", "wait", "timeout_seconds"],
|
|
17324
|
+
reconcile_preview: ["preview_id"],
|
|
17243
17325
|
cleanup_preview: ["preview_id"]
|
|
17244
17326
|
};
|
|
17245
17327
|
function timestamp3(value) {
|
|
@@ -17249,7 +17331,7 @@ function receipt(value, identity) {
|
|
|
17249
17331
|
if (!Check2(receiptSchema, value) || value.project_ref !== identity.ref || value.application_id !== identity.id || value.environment_id !== identity.environment || identity.previewId && value.preview_id !== identity.previewId || value.resources.build_artifact.release_id !== value.release_id || value.resources.storage_namespace.namespace !== value.resources.database_branch.branch_ref) {
|
|
17250
17332
|
throw new Error("Invalid preview receipt");
|
|
17251
17333
|
}
|
|
17252
|
-
if (value.expires_at !== null && !timestamp3(value.expires_at) || value.created_at !== undefined && !timestamp3(value.created_at) || value.updated_at !== undefined && !timestamp3(value.updated_at) || value.expires_at !== null && value.created_at !== undefined && !Check2(ttlSecondsSchema, (Date.parse(value.expires_at) - Date.parse(value.created_at)) / 1000)) {
|
|
17334
|
+
if (value.expires_at !== undefined && value.expires_at !== null && !timestamp3(value.expires_at) || value.created_at !== undefined && !timestamp3(value.created_at) || value.updated_at !== undefined && !timestamp3(value.updated_at) || value.expires_at !== undefined && value.expires_at !== null && value.created_at !== undefined && !Check2(ttlSecondsSchema, (Date.parse(value.expires_at) - Date.parse(value.created_at)) / 1000)) {
|
|
17253
17335
|
throw new Error("Invalid preview expiry");
|
|
17254
17336
|
}
|
|
17255
17337
|
if (value.status === "ready") {
|
|
@@ -17385,8 +17467,8 @@ async function applicationPreviewAction(http, args, project) {
|
|
|
17385
17467
|
const identity = { project_ref: ref, application_id: id, environment_id: environment };
|
|
17386
17468
|
const applicationPath = `/v1/projects/${project}/applications/${encodeURIComponent(id)}`;
|
|
17387
17469
|
const path = `${applicationPath}/environments/${encodeURIComponent(environment)}`;
|
|
17388
|
-
const previewId = action === "get_preview" || action === "cleanup_preview" ? required5(args, "preview_id") : undefined;
|
|
17389
|
-
const mutation = action === "create_preview" || action === "cleanup_preview";
|
|
17470
|
+
const previewId = action === "get_preview" || action === "reconcile_preview" || action === "cleanup_preview" ? required5(args, "preview_id") : action === "create_preview" ? typeof args["preview_id"] === "string" ? required5(args, "preview_id") : randomUUID() : action === "get_preview_plan" && typeof args["preview_id"] === "string" ? required5(args, "preview_id") : undefined;
|
|
17471
|
+
const mutation = action === "create_preview" || action === "reconcile_preview" || action === "cleanup_preview";
|
|
17390
17472
|
const requestBudget = startedAt === undefined ? 120000 : Math.min(120000, timeoutSeconds * 1000);
|
|
17391
17473
|
const options = {
|
|
17392
17474
|
timeoutMs: requestBudget,
|
|
@@ -17403,7 +17485,10 @@ async function applicationPreviewAction(http, args, project) {
|
|
|
17403
17485
|
if (!Check2(ApplicationReleaseIdSchema2, releaseId))
|
|
17404
17486
|
throw new Error("Invalid release ID");
|
|
17405
17487
|
if (action === "get_preview_plan") {
|
|
17406
|
-
const
|
|
17488
|
+
const branchRef = typeof args["branch_ref"] === "string" ? required5(args, "branch_ref") : previewId === undefined ? required5(args, "branch_ref") : applicationPreviewBranchRef(previewId);
|
|
17489
|
+
const query = new URLSearchParams({ release_id: releaseId, branch_ref: branchRef });
|
|
17490
|
+
if (previewId !== undefined)
|
|
17491
|
+
query.set("preview_id", previewId);
|
|
17407
17492
|
if (typeof args["data_mode"] === "string")
|
|
17408
17493
|
query.set("data_mode", args["data_mode"]);
|
|
17409
17494
|
if (typeof args["configuration_id"] === "string")
|
|
@@ -17412,17 +17497,19 @@ async function applicationPreviewAction(http, args, project) {
|
|
|
17412
17497
|
query.set("ttl_seconds", String(args["ttl_seconds"]));
|
|
17413
17498
|
result = await http.get(`${path}/preview-plan?${query}`, options);
|
|
17414
17499
|
} else {
|
|
17415
|
-
const configurationId =
|
|
17416
|
-
if (!Check2(ApplicationConfigurationIdSchema2, configurationId))
|
|
17500
|
+
const configurationId = args["configuration_id"];
|
|
17501
|
+
if (configurationId !== undefined && !Check2(ApplicationConfigurationIdSchema2, configurationId)) {
|
|
17417
17502
|
throw new Error("Invalid configuration ID");
|
|
17503
|
+
}
|
|
17418
17504
|
const source = await sourceManifest(http, applicationPath, ref, id, releaseId);
|
|
17419
17505
|
if (!source.manifest)
|
|
17420
17506
|
return releaseControlFailure(operation, source.result.ok ? "INVALID_RESPONSE" : "HTTP_ERROR", source.result.status, { ...identity, release_id: releaseId, configuration_id: configurationId });
|
|
17421
17507
|
sourceHash = source.manifest;
|
|
17422
17508
|
result = await http.post(`${path}/previews`, {
|
|
17509
|
+
preview_id: previewId,
|
|
17423
17510
|
release_id: releaseId,
|
|
17424
|
-
configuration_id: configurationId,
|
|
17425
17511
|
data_mode: args["data_mode"] ?? "schema_only",
|
|
17512
|
+
...configurationId === undefined ? {} : { configuration_id: configurationId },
|
|
17426
17513
|
...args["branch_name"] === undefined ? {} : { branch_name: args["branch_name"] },
|
|
17427
17514
|
...args["ttl_seconds"] === undefined ? {} : { ttl_seconds: args["ttl_seconds"] }
|
|
17428
17515
|
}, options);
|
|
@@ -17432,7 +17519,7 @@ async function applicationPreviewAction(http, args, project) {
|
|
|
17432
17519
|
} else if (previewId) {
|
|
17433
17520
|
if (!Check2(previewIdSchema, previewId))
|
|
17434
17521
|
throw new Error("Invalid preview ID");
|
|
17435
|
-
result = action === "cleanup_preview" ? await http.deleteReleaseMutation(`${path}/previews/${previewId}`) : await http.get(`${path}/previews/${previewId}`, options);
|
|
17522
|
+
result = action === "cleanup_preview" ? await http.deleteReleaseMutation(`${path}/previews/${previewId}`) : action === "reconcile_preview" ? await http.post(`${path}/previews/${previewId}/reconcile`, {}, options) : await http.get(`${path}/previews/${previewId}`, options);
|
|
17436
17523
|
} else {
|
|
17437
17524
|
throw new Error("Unknown preview action");
|
|
17438
17525
|
}
|
|
@@ -17440,7 +17527,13 @@ async function applicationPreviewAction(http, args, project) {
|
|
|
17440
17527
|
...identity,
|
|
17441
17528
|
...previewId ? { preview_id: previewId } : {},
|
|
17442
17529
|
...releaseId ? { source_release_id: releaseId } : {},
|
|
17443
|
-
reconciliation: previewId ? {
|
|
17530
|
+
reconciliation: previewId ? {
|
|
17531
|
+
action: action === "reconcile_preview" ? "reconcile_preview" : "get_preview",
|
|
17532
|
+
ref,
|
|
17533
|
+
id,
|
|
17534
|
+
environment_id: environment,
|
|
17535
|
+
preview_id: previewId
|
|
17536
|
+
} : { action: "list_previews", ref, id, environment_id: environment }
|
|
17444
17537
|
};
|
|
17445
17538
|
if (!result.ok)
|
|
17446
17539
|
return mutation ? releaseControlMutationFailure(operation, result, state) : releaseControlFailure(operation, "HTTP_ERROR", result.status, state);
|
|
@@ -17464,24 +17557,29 @@ async function applicationPreviewAction(http, args, project) {
|
|
|
17464
17557
|
...previewId === undefined ? {} : { previewId }
|
|
17465
17558
|
});
|
|
17466
17559
|
if (action === "get_preview_plan") {
|
|
17467
|
-
|
|
17560
|
+
const expectedBranchRef = typeof args["branch_ref"] === "string" ? args["branch_ref"] : previewId === undefined ? undefined : applicationPreviewBranchRef(previewId);
|
|
17561
|
+
if (preview.status !== "planned" || previewId === undefined && preview.release_id !== releaseId || expectedBranchRef === undefined || preview.resources.database_branch.branch_ref !== expectedBranchRef || preview.resources.database_branch.data_mode !== (args["data_mode"] ?? "schema_only") || (args["ttl_seconds"] === undefined ? preview.expires_at !== null && preview.expires_at !== undefined : preview.expires_at === null || preview.expires_at === undefined))
|
|
17468
17562
|
throw new Error;
|
|
17469
17563
|
} else {
|
|
17470
|
-
if (preview.status === "planned" || preview.resources.database_branch.branch_ref !==
|
|
17471
|
-
throw new Error;
|
|
17472
|
-
if (action === "create_preview" && (preview.release_id !== applicationReleaseId(preview.resources.database_branch.branch_ref, id, sourceHash) || preview.resources.database_branch.data_mode !== (args["data_mode"] ?? "schema_only") || !Check2(receiptSchema, result.data) || result.data.source_configuration_id !== args["configuration_id"] || preview.expires_at === null || result.data.created_at === undefined || args["ttl_seconds"] !== undefined && Date.parse(preview.expires_at) - Date.parse(result.data.created_at) !== args["ttl_seconds"] * 1000))
|
|
17564
|
+
if (preview.status === "planned" || preview.resources.database_branch.branch_ref !== applicationPreviewBranchRef(preview.preview_id))
|
|
17473
17565
|
throw new Error;
|
|
17474
|
-
|
|
17475
|
-
|
|
17476
|
-
|
|
17477
|
-
|
|
17478
|
-
|
|
17479
|
-
|
|
17480
|
-
|
|
17566
|
+
if (action === "create_preview") {
|
|
17567
|
+
const expiresAt = preview.expires_at;
|
|
17568
|
+
const createdAt = typeof result.data === "object" && result.data !== null && "created_at" in result.data && typeof result.data.created_at === "string" ? result.data.created_at : undefined;
|
|
17569
|
+
if (preview.release_id !== applicationReleaseId(preview.resources.database_branch.branch_ref, id, sourceHash) || preview.resources.database_branch.data_mode !== (args["data_mode"] ?? "schema_only") || !Check2(receiptSchema, result.data) || args["configuration_id"] !== undefined && result.data.source_configuration_id !== args["configuration_id"] || expiresAt === null || expiresAt === undefined || args["ttl_seconds"] !== undefined && (createdAt === undefined || Date.parse(expiresAt) - Date.parse(createdAt) !== args["ttl_seconds"] * 1000))
|
|
17570
|
+
throw new Error;
|
|
17571
|
+
}
|
|
17572
|
+
if (preview.status === "failed" || action === "cleanup_preview" && preview.status !== "cleaned") {
|
|
17573
|
+
return releaseControlFailure(operation, "MUTATION_NOT_SUCCEEDED", result.status, {
|
|
17574
|
+
...identity,
|
|
17575
|
+
preview_id: preview.preview_id,
|
|
17576
|
+
preview
|
|
17577
|
+
});
|
|
17578
|
+
}
|
|
17481
17579
|
}
|
|
17482
17580
|
if (timeoutSeconds !== undefined)
|
|
17483
17581
|
return await waitForPreview(http, path, operation, identity, preview, timeoutSeconds, startedAt);
|
|
17484
|
-
return releaseControlSuccess(operation, { ...identity, preview });
|
|
17582
|
+
return releaseControlSuccess(operation, { ...identity, preview_id: preview.preview_id, preview });
|
|
17485
17583
|
} catch {
|
|
17486
17584
|
return releaseControlFailure(operation, mutation ? "OUTCOME_UNKNOWN" : "INVALID_RESPONSE", result.status, state);
|
|
17487
17585
|
}
|
|
@@ -24108,7 +24206,7 @@ async function createVerificationPlan(root, graph, target, sourceRoot = root) {
|
|
|
24108
24206
|
}
|
|
24109
24207
|
|
|
24110
24208
|
// src/shared/tools/app-scaffold-writes.ts
|
|
24111
|
-
import { randomUUID } from "node:crypto";
|
|
24209
|
+
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
24112
24210
|
import { link, lstat as lstat3, mkdir as mkdir4, open as open3, readFile as readFile3, realpath as realpath4, rename as rename2, rmdir, unlink } from "node:fs/promises";
|
|
24113
24211
|
import { dirname as dirname7, isAbsolute as isAbsolute5, join as join12, relative as relative6, resolve as resolve16, sep as sep4, win32 } from "node:path";
|
|
24114
24212
|
|
|
@@ -24229,7 +24327,7 @@ async function applyScaffoldWrites(plan) {
|
|
|
24229
24327
|
if (!sameFile(write.before, await snapshot(plan.root, write.path))) {
|
|
24230
24328
|
throw new ScaffoldError("SCAFFOLD_CHANGED", `Scaffold target changed during generation: ${write.path}`);
|
|
24231
24329
|
}
|
|
24232
|
-
const pending = `${target}.supacloud-${
|
|
24330
|
+
const pending = `${target}.supacloud-${randomUUID2()}`;
|
|
24233
24331
|
const file = await open3(pending, "wx", write.before?.mode);
|
|
24234
24332
|
temporary.push(pending);
|
|
24235
24333
|
let after;
|
|
@@ -24264,7 +24362,7 @@ async function applyScaffoldWrites(plan) {
|
|
|
24264
24362
|
if (!write.before)
|
|
24265
24363
|
await unlink(target);
|
|
24266
24364
|
else {
|
|
24267
|
-
const pending = `${target}.supacloud-${
|
|
24365
|
+
const pending = `${target}.supacloud-${randomUUID2()}`;
|
|
24268
24366
|
const file = await open3(pending, "wx", write.before.mode);
|
|
24269
24367
|
temporary.push(pending);
|
|
24270
24368
|
try {
|
|
@@ -24317,12 +24415,13 @@ var REMOTE_APP_ACTIONS = {
|
|
|
24317
24415
|
retire: "retire_activation",
|
|
24318
24416
|
logs: "logs",
|
|
24319
24417
|
preview: "create_preview",
|
|
24320
|
-
previews: "list_previews"
|
|
24418
|
+
previews: "list_previews",
|
|
24419
|
+
"preview-reconcile": "reconcile_preview"
|
|
24321
24420
|
};
|
|
24322
24421
|
var REMOTE_APP_DESCRIPTIONS = {
|
|
24323
|
-
ref: "[upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Project ref (defaults to context)",
|
|
24324
|
-
id: "[upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Application ID",
|
|
24325
|
-
environment_id: "[configure/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Target environment ID",
|
|
24422
|
+
ref: "[upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Project ref (defaults to context)",
|
|
24423
|
+
id: "[upload/configure/transfer-plan/transfer/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Application ID",
|
|
24424
|
+
environment_id: "[configure/promote-plan/diff/promote/promote-status/promote-reconcile/preview-plan/preview/previews/preview-list/preview-create/preview-status/preview-reconcile/preview-cleanup/deploy/deploy-plan/status/rollback/rollback-plan/history/reconcile/retire] Target environment ID",
|
|
24326
24425
|
configuration_id: "[promote-plan/diff/promote/preview-plan/preview/preview-create/deploy/deploy-plan/rollback] Immutable target configuration revision",
|
|
24327
24426
|
activation_id: "[deploy/rollback/reconcile/retire] Required explicit activation ID",
|
|
24328
24427
|
expected_activation_id: "[deploy/rollback] Required current activation ID, or absent for first activation",
|
|
@@ -24340,7 +24439,7 @@ var REMOTE_APP_DESCRIPTIONS = {
|
|
|
24340
24439
|
ttl_seconds: "[preview-plan/preview/preview-create] Lifetime from 300 to 604800 seconds; creation defaults to the platform TTL",
|
|
24341
24440
|
wait: "[preview/preview-create/preview-status] Wait for verified readiness of the selected preview",
|
|
24342
24441
|
timeout_seconds: "[preview/preview-create/preview-status] Observation budget with --wait, from 1 to 3600 seconds (default 300)",
|
|
24343
|
-
preview_id: "[preview-status/preview-cleanup] Preview ID",
|
|
24442
|
+
preview_id: "[preview-status/preview-reconcile/preview-cleanup] Preview ID",
|
|
24344
24443
|
cursor: "[history] Returned page cursor",
|
|
24345
24444
|
limit: "[history] Page size, default 20 (1-100)"
|
|
24346
24445
|
};
|
|
@@ -25408,7 +25507,7 @@ function formatWorkflowObservation(result, action) {
|
|
|
25408
25507
|
].join(`
|
|
25409
25508
|
`));
|
|
25410
25509
|
}
|
|
25411
|
-
if (action === "preview-list") {
|
|
25510
|
+
if (action === "preview-list" || action === "previews") {
|
|
25412
25511
|
const list = parsePreviewList({ ...identity, previews: data.previews }, identity);
|
|
25413
25512
|
return textResult([
|
|
25414
25513
|
`${label}: ${list.previews.length} preview(s)`,
|
|
@@ -25416,8 +25515,8 @@ function formatWorkflowObservation(result, action) {
|
|
|
25416
25515
|
].join(`
|
|
25417
25516
|
`));
|
|
25418
25517
|
}
|
|
25419
|
-
if (["preview-create", "preview-status", "preview-cleanup"].includes(action)) {
|
|
25420
|
-
const preview = parsePreviewReceipt(data.preview, identity);
|
|
25518
|
+
if (["preview-plan", "preview-create", "preview-status", "preview-reconcile", "preview-cleanup"].includes(action)) {
|
|
25519
|
+
const preview = parsePreviewReceipt(data.preview ?? data, identity);
|
|
25421
25520
|
return textResult([
|
|
25422
25521
|
`${label}: ${preview.status}`,
|
|
25423
25522
|
`Preview: ${preview.preview_id}`,
|
|
@@ -25639,6 +25738,7 @@ function registerAppTools(server, options = {}) {
|
|
|
25639
25738
|
"preview-create",
|
|
25640
25739
|
"preview-status",
|
|
25641
25740
|
"preview-cleanup",
|
|
25741
|
+
"preview-reconcile",
|
|
25642
25742
|
"promote",
|
|
25643
25743
|
"promote-status",
|
|
25644
25744
|
"promote-reconcile"
|
|
@@ -26354,7 +26454,7 @@ function registerDbGovernanceTools(server, options = {}) {
|
|
|
26354
26454
|
}
|
|
26355
26455
|
|
|
26356
26456
|
// src/shared/tools/scheduled-function-tools.ts
|
|
26357
|
-
import { randomUUID as
|
|
26457
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
26358
26458
|
import { readFileSync as readFileSync9, statSync as statSync8 } from "node:fs";
|
|
26359
26459
|
import { resolve as resolve20 } from "node:path";
|
|
26360
26460
|
import { isDeepStrictEqual } from "node:util";
|
|
@@ -26664,7 +26764,7 @@ function readOnlyResult2() {
|
|
|
26664
26764
|
}
|
|
26665
26765
|
function createRequest(args, environment) {
|
|
26666
26766
|
return {
|
|
26667
|
-
request_id:
|
|
26767
|
+
request_id: randomUUID3(),
|
|
26668
26768
|
name: requiredName(args, "create"),
|
|
26669
26769
|
slug: requiredSlug(args, "create"),
|
|
26670
26770
|
cron: requiredCron(args, "create"),
|
|
@@ -26726,7 +26826,7 @@ function updateRequest(args, environment) {
|
|
|
26726
26826
|
throw new Error("Scheduled Function update requires at least one field");
|
|
26727
26827
|
}
|
|
26728
26828
|
return {
|
|
26729
|
-
request_id:
|
|
26829
|
+
request_id: randomUUID3(),
|
|
26730
26830
|
expected_updated_at: expectedUpdatedAt,
|
|
26731
26831
|
...mutationFields
|
|
26732
26832
|
};
|
|
@@ -28423,7 +28523,7 @@ function registerRemoteDevTools(server, options = {}) {
|
|
|
28423
28523
|
// package.json
|
|
28424
28524
|
var package_default = {
|
|
28425
28525
|
name: "@supacloud/cli",
|
|
28426
|
-
version: "0.
|
|
28526
|
+
version: "0.84.0",
|
|
28427
28527
|
description: "Project-scoped CLI for SupaCloud users",
|
|
28428
28528
|
type: "module",
|
|
28429
28529
|
main: "./dist/index.js",
|
|
@@ -28476,13 +28576,13 @@ var package_default = {
|
|
|
28476
28576
|
},
|
|
28477
28577
|
dependencies: {
|
|
28478
28578
|
"@supacloud/compiler": "^0.43.0",
|
|
28479
|
-
"@supacloud/delivery": "0.
|
|
28579
|
+
"@supacloud/delivery": "0.13.0",
|
|
28480
28580
|
"@supacloud/db": "0.16.0",
|
|
28481
28581
|
typebox: "1.3.34"
|
|
28482
28582
|
},
|
|
28483
28583
|
overrides: {
|
|
28484
28584
|
"@supacloud/contracts": "0.8.0",
|
|
28485
|
-
"@supacloud/delivery": "0.
|
|
28585
|
+
"@supacloud/delivery": "0.13.0",
|
|
28486
28586
|
"@graphql-tools/utils": "^12.0.3"
|
|
28487
28587
|
},
|
|
28488
28588
|
devDependencies: {
|
|
@@ -28753,7 +28853,9 @@ EXAMPLES
|
|
|
28753
28853
|
${preferredCommand} app preview-plan --ref abc123 --id orders --environment_id test --release_id <sha256> --branch_ref preview-orders
|
|
28754
28854
|
${preferredCommand} app preview --ref abc123 --id orders --environment_id test --release_id <sha256> --configuration_id <uuid> --ttl_seconds 3600 --wait
|
|
28755
28855
|
${preferredCommand} app previews --ref abc123 --id orders --environment_id test
|
|
28856
|
+
${preferredCommand} app preview-list --ref abc123 --id orders --environment_id test
|
|
28756
28857
|
${preferredCommand} app preview-status --ref abc123 --id orders --environment_id test --preview_id <uuid> --wait --timeout_seconds 300
|
|
28858
|
+
${preferredCommand} app preview-reconcile --ref abc123 --id orders --environment_id test --preview_id <uuid>
|
|
28757
28859
|
${preferredCommand} app preview-cleanup --ref abc123 --id orders --environment_id test --preview_id <uuid>
|
|
28758
28860
|
${preferredCommand} --env production app promote --id orders --environment_id production --source_ref staging --source_environment_id staging --source_release_id <sha256> --confirm-production abc123
|
|
28759
28861
|
${preferredCommand} app promote-status --ref abc123 --id orders --environment_id production --mutation_id <uuid>
|
|
@@ -25,6 +25,7 @@ declare const REMOTE_APP_ACTIONS: {
|
|
|
25
25
|
readonly logs: "logs";
|
|
26
26
|
readonly preview: "create_preview";
|
|
27
27
|
readonly previews: "list_previews";
|
|
28
|
+
readonly "preview-reconcile": "reconcile_preview";
|
|
28
29
|
};
|
|
29
30
|
export interface AppToolOptions {
|
|
30
31
|
getApplications?: () => ((args: Record<string, unknown>) => Promise<ToolResult>) | undefined;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Type, type Static } from "typebox";
|
|
2
2
|
import type { HttpTransport } from "../transports/http";
|
|
3
|
-
export declare const APPLICATION_PREVIEW_ACTIONS: readonly ["get_preview_plan", "create_preview", "list_previews", "get_preview", "cleanup_preview"];
|
|
3
|
+
export declare const APPLICATION_PREVIEW_ACTIONS: readonly ["get_preview_plan", "create_preview", "list_previews", "get_preview", "reconcile_preview", "cleanup_preview"];
|
|
4
4
|
export declare const APPLICATION_PREVIEW_FIELDS: {
|
|
5
5
|
preview_id: Type.TOptional<Type.TString>;
|
|
6
6
|
branch_ref: Type.TOptional<Type.TString>;
|
|
@@ -17,41 +17,41 @@ declare const receiptSchema: Type.TObject<{
|
|
|
17
17
|
application_id: Type.TString;
|
|
18
18
|
environment_id: Type.TString;
|
|
19
19
|
release_id: Type.TString;
|
|
20
|
-
expires_at: Type.TUnion<[Type.TString, Type.TNull]
|
|
21
|
-
status: Type.TEnum<("
|
|
20
|
+
expires_at: Type.TOptional<Type.TUnion<[Type.TString, Type.TNull]>>;
|
|
21
|
+
status: Type.TEnum<("ready" | "failed" | "cleaned" | "planned" | "provisioning")[]>;
|
|
22
22
|
resources: Type.TObject<{
|
|
23
23
|
build_artifact: Type.TObject<{
|
|
24
|
-
status: Type.TEnum<("pending" | "
|
|
24
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
25
25
|
release_id: Type.TString;
|
|
26
26
|
}>;
|
|
27
27
|
database_branch: Type.TObject<{
|
|
28
|
-
status: Type.TEnum<("pending" | "
|
|
28
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
29
29
|
branch_ref: Type.TString;
|
|
30
30
|
data_mode: Type.TEnum<("schema_only" | "full_clone")[]>;
|
|
31
31
|
}>;
|
|
32
32
|
queue_namespace: Type.TObject<{
|
|
33
|
-
status: Type.TEnum<("pending" | "
|
|
33
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
34
34
|
namespace: Type.TString;
|
|
35
35
|
}>;
|
|
36
36
|
storage_namespace: Type.TObject<{
|
|
37
|
-
status: Type.TEnum<("pending" | "
|
|
37
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
38
38
|
namespace: Type.TString;
|
|
39
39
|
}>;
|
|
40
40
|
test_secret: Type.TObject<{
|
|
41
|
-
status: Type.TEnum<("pending" | "
|
|
41
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
42
42
|
name: Type.TString;
|
|
43
43
|
value_issued: Type.TLiteral<false>;
|
|
44
44
|
}>;
|
|
45
45
|
configuration_revision: Type.TObject<{
|
|
46
|
-
status: Type.TEnum<("pending" | "
|
|
46
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
47
47
|
configuration_id: Type.TUnion<[Type.TString, Type.TNull]>;
|
|
48
48
|
}>;
|
|
49
49
|
application_activation: Type.TObject<{
|
|
50
|
-
status: Type.TEnum<("pending" | "
|
|
50
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
51
51
|
activation_id: Type.TUnion<[Type.TString, Type.TNull]>;
|
|
52
52
|
}>;
|
|
53
53
|
smoke_test: Type.TObject<{
|
|
54
|
-
status: Type.TEnum<("pending" | "
|
|
54
|
+
status: Type.TEnum<("pending" | "ready" | "failed" | "cleaned")[]>;
|
|
55
55
|
checks: Type.TArray<Type.TString>;
|
|
56
56
|
passed: Type.TArray<Type.TString>;
|
|
57
57
|
failed: Type.TArray<Type.TString>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -9,7 +9,7 @@ export declare const APPLICATION_TOOL_SCHEMA: {
|
|
|
9
9
|
ttl_seconds: Type.TOptional<Type.TInteger>;
|
|
10
10
|
wait: Type.TOptional<Type.TBoolean>;
|
|
11
11
|
timeout_seconds: Type.TOptional<Type.TInteger>;
|
|
12
|
-
action: Type.TEnum<("list_releases" | "get_release" | "upload_release" | "activate_release" | "logs" | "get_runtime" | "get_deployment_evidence" | "get_configuration" | "get_release_transfer_plan" | "get_promotion_plan" | "get_rollback_snapshot" | "get_history" | "get_deploy_plan" | "
|
|
12
|
+
action: Type.TEnum<("list_releases" | "get_release" | "upload_release" | "activate_release" | "logs" | "get_runtime" | "get_deployment_evidence" | "get_configuration" | "get_release_transfer_plan" | "get_promotion_plan" | "get_promotion_status" | "get_rollback_snapshot" | "get_history" | "get_deploy_plan" | "get_preview_plan" | "list_previews" | "get_preview" | "put_configuration" | "transfer_release" | "promote_application" | "reconcile_promotion" | "create_preview" | "reconcile_preview" | "cleanup_preview" | "deploy_release" | "rollback_release" | "reconcile_activation" | "retire_activation")[]>;
|
|
13
13
|
ref: Type.TString;
|
|
14
14
|
id: Type.TString;
|
|
15
15
|
environment_id: Type.TOptional<Type.TString>;
|
|
@@ -121,49 +121,49 @@ export declare function parsePreviewReceipt(value: unknown, identity: Applicatio
|
|
|
121
121
|
project_ref: string;
|
|
122
122
|
application_id: string;
|
|
123
123
|
environment_id: string;
|
|
124
|
-
status: "
|
|
124
|
+
status: "ready" | "failed" | "cleaned" | "planned" | "provisioning";
|
|
125
125
|
schema: "supacloud.application-preview.v1";
|
|
126
126
|
resources: {
|
|
127
127
|
build_artifact: {
|
|
128
|
-
status: "pending" | "
|
|
128
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
129
129
|
release_id: string;
|
|
130
130
|
};
|
|
131
131
|
database_branch: {
|
|
132
|
-
status: "pending" | "
|
|
132
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
133
133
|
branch_ref: string;
|
|
134
134
|
data_mode: "schema_only" | "full_clone";
|
|
135
135
|
};
|
|
136
136
|
queue_namespace: {
|
|
137
|
-
status: "pending" | "
|
|
137
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
138
138
|
namespace: string;
|
|
139
139
|
};
|
|
140
140
|
storage_namespace: {
|
|
141
|
-
status: "pending" | "
|
|
141
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
142
142
|
namespace: string;
|
|
143
143
|
};
|
|
144
144
|
test_secret: {
|
|
145
145
|
name: string;
|
|
146
|
-
status: "pending" | "
|
|
146
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
147
147
|
value_issued: false;
|
|
148
148
|
};
|
|
149
149
|
configuration_revision: {
|
|
150
|
-
status: "pending" | "
|
|
150
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
151
151
|
configuration_id: string | null;
|
|
152
152
|
};
|
|
153
153
|
application_activation: {
|
|
154
|
-
status: "pending" | "
|
|
154
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
155
155
|
activation_id: string | null;
|
|
156
156
|
};
|
|
157
157
|
smoke_test: {
|
|
158
|
-
status: "pending" | "
|
|
158
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
159
159
|
checks: string[];
|
|
160
160
|
failed: string[];
|
|
161
161
|
passed: string[];
|
|
162
162
|
};
|
|
163
163
|
};
|
|
164
164
|
release_id: string;
|
|
165
|
-
expires_at: string | null;
|
|
166
165
|
preview_id: string;
|
|
166
|
+
expires_at: string | null;
|
|
167
167
|
cleanup: {
|
|
168
168
|
required: boolean;
|
|
169
169
|
error: string | null;
|
|
@@ -184,49 +184,49 @@ export declare function parsePreviewList(value: unknown, identity: ApplicationWo
|
|
|
184
184
|
project_ref: string;
|
|
185
185
|
application_id: string;
|
|
186
186
|
environment_id: string;
|
|
187
|
-
status: "
|
|
187
|
+
status: "ready" | "failed" | "cleaned" | "planned" | "provisioning";
|
|
188
188
|
schema: "supacloud.application-preview.v1";
|
|
189
189
|
resources: {
|
|
190
190
|
build_artifact: {
|
|
191
|
-
status: "pending" | "
|
|
191
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
192
192
|
release_id: string;
|
|
193
193
|
};
|
|
194
194
|
database_branch: {
|
|
195
|
-
status: "pending" | "
|
|
195
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
196
196
|
branch_ref: string;
|
|
197
197
|
data_mode: "schema_only" | "full_clone";
|
|
198
198
|
};
|
|
199
199
|
queue_namespace: {
|
|
200
|
-
status: "pending" | "
|
|
200
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
201
201
|
namespace: string;
|
|
202
202
|
};
|
|
203
203
|
storage_namespace: {
|
|
204
|
-
status: "pending" | "
|
|
204
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
205
205
|
namespace: string;
|
|
206
206
|
};
|
|
207
207
|
test_secret: {
|
|
208
208
|
name: string;
|
|
209
|
-
status: "pending" | "
|
|
209
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
210
210
|
value_issued: false;
|
|
211
211
|
};
|
|
212
212
|
configuration_revision: {
|
|
213
|
-
status: "pending" | "
|
|
213
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
214
214
|
configuration_id: string | null;
|
|
215
215
|
};
|
|
216
216
|
application_activation: {
|
|
217
|
-
status: "pending" | "
|
|
217
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
218
218
|
activation_id: string | null;
|
|
219
219
|
};
|
|
220
220
|
smoke_test: {
|
|
221
|
-
status: "pending" | "
|
|
221
|
+
status: "pending" | "ready" | "failed" | "cleaned";
|
|
222
222
|
checks: string[];
|
|
223
223
|
failed: string[];
|
|
224
224
|
passed: string[];
|
|
225
225
|
};
|
|
226
226
|
};
|
|
227
227
|
release_id: string;
|
|
228
|
-
expires_at: string | null;
|
|
229
228
|
preview_id: string;
|
|
229
|
+
expires_at: string | null;
|
|
230
230
|
cleanup: {
|
|
231
231
|
required: boolean;
|
|
232
232
|
error: string | null;
|
|
@@ -63,6 +63,6 @@ export declare class HttpTransport {
|
|
|
63
63
|
postMultipart<T = unknown>(path: string, formData: FormData, options?: HttpPostOptions): Promise<HttpResult<T>>;
|
|
64
64
|
patch<T = unknown>(path: string, body?: unknown): Promise<HttpResult<T>>;
|
|
65
65
|
put<T = unknown>(path: string, body?: unknown, options?: HttpPostOptions): Promise<HttpResult<T>>;
|
|
66
|
-
delete<T = unknown>(path: string, body?: unknown): Promise<HttpResult<T>>;
|
|
66
|
+
delete<T = unknown>(path: string, body?: unknown, options?: HttpPostOptions): Promise<HttpResult<T>>;
|
|
67
67
|
ping(): Promise<boolean>;
|
|
68
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@supacloud/cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.84.0",
|
|
4
4
|
"description": "Project-scoped CLI for SupaCloud users",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -53,13 +53,13 @@
|
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
55
|
"@supacloud/compiler": "^0.43.0",
|
|
56
|
-
"@supacloud/delivery": "0.
|
|
56
|
+
"@supacloud/delivery": "0.13.0",
|
|
57
57
|
"@supacloud/db": "0.16.0",
|
|
58
58
|
"typebox": "1.3.34"
|
|
59
59
|
},
|
|
60
60
|
"overrides": {
|
|
61
61
|
"@supacloud/contracts": "0.8.0",
|
|
62
|
-
"@supacloud/delivery": "0.
|
|
62
|
+
"@supacloud/delivery": "0.13.0",
|
|
63
63
|
"@graphql-tools/utils": "^12.0.3"
|
|
64
64
|
},
|
|
65
65
|
"devDependencies": {
|