@supacloud/cli 0.79.0 → 0.80.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/dist/index.js CHANGED
@@ -179093,11 +179093,12 @@ function resolveSupaCloudContext(env = process.env, cwd = process.cwd(), selecti
179093
179093
  var ACTION_POLICY = {
179094
179094
  deploy: { write: ["deploy"] },
179095
179095
  applications: {
179096
- read: ["list_releases", "get_release", "get_runtime", "get_deployment_evidence", "get_configuration", "get_rollback_snapshot", "logs", "get_preview_plan"],
179096
+ read: ["list_releases", "get_release", "get_runtime", "get_deployment_evidence", "get_configuration", "get_rollback_snapshot", "get_history", "get_deploy_plan", "logs", "get_preview_plan"],
179097
179097
  write: [
179098
179098
  "upload_release",
179099
179099
  "put_configuration",
179100
179100
  "activate_release",
179101
+ "deploy_release",
179101
179102
  "rollback_release",
179102
179103
  "reconcile_activation",
179103
179104
  "retire_activation",
@@ -179200,7 +179201,7 @@ var ACTION_POLICY = {
179200
179201
  ai: { local: ["show_skill", "install_skill"] },
179201
179202
  app: {
179202
179203
  local: ["init", "generate", "dev", "watch", "verify-plan", "compile", "check", "graph", "explain", "export-tools", "context", "doctor", "fix", "plan", "build"],
179203
- read: ["status", "logs", "rollback-plan", "preview-plan"],
179204
+ read: ["status", "logs", "rollback-plan", "history", "deploy-plan", "diff", "preview-plan"],
179204
179205
  write: ["upload", "configure", "deploy", "rollback", "reconcile", "retire", "preview", "previews", "preview-status", "preview-cleanup"]
179205
179206
  },
179206
179207
  db: {
@@ -180294,6 +180295,130 @@ var ApplicationRollbackSnapshotSchema = _Object_({
180294
180295
  active: Union([RollbackActivationSchema, Null()]),
180295
180296
  previous: Union([RollbackActivationSchema, Null()])
180296
180297
  }, { additionalProperties: false });
180298
+ // node_modules/@supacloud/delivery/src/application-deploy-plan.ts
180299
+ var CandidateSchema = _Object_({
180300
+ release_id: ApplicationReleaseIdSchema,
180301
+ configuration_id: ApplicationConfigurationIdSchema
180302
+ }, { additionalProperties: false });
180303
+ var ApplicationDeployPlanSchema = _Object_({
180304
+ schema: Literal("supacloud.application-deploy-plan.v1"),
180305
+ project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
180306
+ application_id: ApplicationIdSchema,
180307
+ environment_id: ApplicationIdSchema,
180308
+ candidate: CandidateSchema,
180309
+ current: Union([_Object_({
180310
+ ...CandidateSchema.properties,
180311
+ activation_id: ApplicationActivationIdSchema
180312
+ }, { additionalProperties: false }), Null()]),
180313
+ expected_activation_id: Union([ApplicationActivationIdSchema, Null()]),
180314
+ action: Union([Literal("activate"), Literal("no-op")]),
180315
+ changes: _Object_({
180316
+ release: Boolean2(),
180317
+ configuration: Boolean2(),
180318
+ targets: _Object_({
180319
+ added: _Array_(String2()),
180320
+ removed: _Array_(String2()),
180321
+ changed: _Array_(String2())
180322
+ }, { additionalProperties: false })
180323
+ }, { additionalProperties: false }),
180324
+ migrations: _Object_({
180325
+ ledger_digest: ApplicationReleaseIdSchema,
180326
+ ledger_compatible: Boolean2(),
180327
+ project_migrations_applied: Boolean2(),
180328
+ operator_provisioning: Union([
180329
+ Literal("separate-verification-required"),
180330
+ Literal("not-declared")
180331
+ ])
180332
+ }, { additionalProperties: false }),
180333
+ compatibility: Literal("not-proven"),
180334
+ execution_performed: Literal(false)
180335
+ }, { additionalProperties: false });
180336
+ function parseApplicationDeployPlan(value) {
180337
+ if (!Check2(ApplicationDeployPlanSchema, value) || value.expected_activation_id !== (value.current?.activation_id ?? null) || value.changes.release !== (value.current?.release_id !== value.candidate.release_id) || value.changes.configuration !== (value.current?.configuration_id !== value.candidate.configuration_id) || value.migrations.project_migrations_applied && !value.migrations.ledger_compatible) {
180338
+ throw new Error("Invalid application deploy plan");
180339
+ }
180340
+ const noOp = value.current !== null && !value.changes.release && !value.changes.configuration && Object.values(value.changes.targets).every((names) => names.length === 0) && value.migrations.ledger_compatible && value.migrations.project_migrations_applied && value.migrations.operator_provisioning === "not-declared";
180341
+ if (value.action === "no-op" !== noOp)
180342
+ throw new Error("Invalid application deploy plan action");
180343
+ return value;
180344
+ }
180345
+ // node_modules/@supacloud/delivery/src/application-history.ts
180346
+ var scope = {
180347
+ project_ref: String2({ pattern: "^[a-z0-9-]{1,20}$" }),
180348
+ application_id: ApplicationIdSchema,
180349
+ environment_id: ApplicationIdSchema
180350
+ };
180351
+ var timestamp = String2({ pattern: "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{6}Z$" });
180352
+ var ApplicationActivationHistoryPositionSchema = _Object_({
180353
+ completed_at: timestamp,
180354
+ activation_id: ApplicationActivationIdSchema
180355
+ }, { additionalProperties: false });
180356
+ var cursorSchema = _Object_({
180357
+ ...scope,
180358
+ ...ApplicationActivationHistoryPositionSchema.properties
180359
+ }, { additionalProperties: false });
180360
+ var ApplicationActivationHistoryCursorSchema = String2({
180361
+ pattern: "^[A-Za-z0-9_-]+$",
180362
+ maxLength: 1024,
180363
+ minLength: 1
180364
+ });
180365
+ var entrySchema = _Object_({
180366
+ ...ApplicationActivationHistoryPositionSchema.properties,
180367
+ release_id: ApplicationReleaseIdSchema,
180368
+ configuration_id: Union([ApplicationConfigurationIdSchema, Null()]),
180369
+ previous_activation_id: Union([ApplicationActivationIdSchema, Null()]),
180370
+ is_active: Boolean2()
180371
+ }, { additionalProperties: false });
180372
+ var ApplicationActivationHistorySchema = _Object_({
180373
+ schema: Literal("supacloud.application-activation-history.v1"),
180374
+ ...scope,
180375
+ active_activation_id: Union([ApplicationActivationIdSchema, Null()]),
180376
+ activations: _Array_(entrySchema, { maxItems: 100 }),
180377
+ next_cursor: Union([ApplicationActivationHistoryCursorSchema, Null()])
180378
+ }, { additionalProperties: false });
180379
+ function applicationHistoryTimestampMilliseconds(value) {
180380
+ const milliseconds = `${value.slice(0, 23)}Z`;
180381
+ if (!Check2(timestamp, value) || !Number.isFinite(Date.parse(milliseconds)) || new Date(milliseconds).toISOString() !== milliseconds)
180382
+ throw new Error("Invalid application history timestamp");
180383
+ return milliseconds;
180384
+ }
180385
+ function parseApplicationHistoryCursor(value, scope) {
180386
+ if (!Check2(ApplicationActivationHistoryCursorSchema, value))
180387
+ throw new Error("Invalid application history cursor");
180388
+ const bytes = Buffer.from(value, "base64url");
180389
+ if (bytes.toString("base64url") !== value)
180390
+ throw new Error("Invalid application history cursor");
180391
+ const cursor = JSON.parse(bytes.toString("utf8"));
180392
+ if (!Check2(cursorSchema, cursor) || cursor.project_ref !== scope.project_ref || cursor.application_id !== scope.application_id || cursor.environment_id !== scope.environment_id) {
180393
+ throw new Error("Invalid application history cursor");
180394
+ }
180395
+ applicationHistoryTimestampMilliseconds(cursor.completed_at);
180396
+ return { completed_at: cursor.completed_at, activation_id: cursor.activation_id };
180397
+ }
180398
+ function applicationHistoryPositionBefore(left, right) {
180399
+ return left.completed_at < right.completed_at || left.completed_at === right.completed_at && left.activation_id < right.activation_id;
180400
+ }
180401
+ function parseApplicationActivationHistory(value) {
180402
+ if (!Check2(ApplicationActivationHistorySchema, value))
180403
+ throw new Error("Invalid application activation history");
180404
+ const seen = new Set;
180405
+ let previous;
180406
+ for (const entry of value.activations) {
180407
+ applicationHistoryTimestampMilliseconds(entry.completed_at);
180408
+ if (seen.has(entry.activation_id) || previous && !applicationHistoryPositionBefore(entry, previous) || entry.previous_activation_id === entry.activation_id || entry.is_active !== (entry.activation_id === value.active_activation_id)) {
180409
+ throw new Error("Invalid application activation history");
180410
+ }
180411
+ seen.add(entry.activation_id);
180412
+ previous = entry;
180413
+ }
180414
+ if (value.next_cursor !== null) {
180415
+ const cursor = parseApplicationHistoryCursor(value.next_cursor, value);
180416
+ if (!previous || cursor.activation_id !== previous.activation_id || cursor.completed_at !== previous.completed_at) {
180417
+ throw new Error("Invalid application activation history");
180418
+ }
180419
+ }
180420
+ return structuredClone(value);
180421
+ }
180297
180422
  // node_modules/@supacloud/delivery/src/deployment-evidence.ts
180298
180423
  var closed3 = { additionalProperties: false };
180299
180424
  var sha256 = String2({ pattern: "^[a-f0-9]{64}$" });
@@ -180465,7 +180590,7 @@ function parseApplicationReadinessReport(value) {
180465
180590
  return value;
180466
180591
  }
180467
180592
  // node_modules/@supacloud/delivery/src/delivery-migration-archive.ts
180468
- var entrySchema = _Object_({
180593
+ var entrySchema2 = _Object_({
180469
180594
  version: String2({ pattern: "^[1-9][0-9]{0,18}$" }),
180470
180595
  name: String2({ pattern: "^[A-Za-z][A-Za-z0-9_-]{0,127}$" }),
180471
180596
  executor: Union([Literal("project-migration"), Literal("operator-provisioning")]),
@@ -180479,7 +180604,7 @@ var archiveSchema = _Object_({
180479
180604
  compatibility: Literal("not-proven"),
180480
180605
  executionPerformed: Literal(false),
180481
180606
  dataRecovery: Literal("separate-required"),
180482
- migrations: _Array_(entrySchema, { minItems: 1, maxItems: 128 })
180607
+ migrations: _Array_(entrySchema2, { minItems: 1, maxItems: 128 })
180483
180608
  }, { additionalProperties: false });
180484
180609
  async function readDeliveryMigrationArchive(manifestPath, target) {
180485
180610
  try {
@@ -187267,6 +187392,7 @@ var ApplicationActivationWriteSchema2 = ApplicationActivationWriteSchema;
187267
187392
  var ApplicationActivationResultSchema2 = ApplicationActivationResultSchema;
187268
187393
  var ApplicationActivationRetirementResultSchema2 = ApplicationActivationRetirementResultSchema;
187269
187394
  var ApplicationRollbackSnapshotSchema2 = ApplicationRollbackSnapshotSchema;
187395
+ var ApplicationActivationHistoryCursorSchema2 = ApplicationActivationHistoryCursorSchema;
187270
187396
 
187271
187397
  // src/shared/tools/application-preview-tools.ts
187272
187398
  var APPLICATION_PREVIEW_ACTIONS = [
@@ -187353,14 +187479,14 @@ var actionFields = {
187353
187479
  get_preview: ["preview_id", "wait", "timeout_seconds"],
187354
187480
  cleanup_preview: ["preview_id"]
187355
187481
  };
187356
- function timestamp(value) {
187482
+ function timestamp2(value) {
187357
187483
  return Number.isFinite(Date.parse(value)) && new Date(value).toISOString() === value;
187358
187484
  }
187359
187485
  function receipt(value, identity) {
187360
187486
  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) {
187361
187487
  throw new Error("Invalid preview receipt");
187362
187488
  }
187363
- if (value.expires_at !== null && !timestamp(value.expires_at) || value.created_at !== undefined && !timestamp(value.created_at) || value.updated_at !== undefined && !timestamp(value.updated_at) || value.expires_at !== null && value.created_at !== undefined && !Check2(ttlSecondsSchema, (Date.parse(value.expires_at) - Date.parse(value.created_at)) / 1000)) {
187489
+ if (value.expires_at !== null && !timestamp2(value.expires_at) || value.created_at !== undefined && !timestamp2(value.created_at) || value.updated_at !== undefined && !timestamp2(value.updated_at) || value.expires_at !== null && value.created_at !== undefined && !Check2(ttlSecondsSchema, (Date.parse(value.expires_at) - Date.parse(value.created_at)) / 1000)) {
187364
187490
  throw new Error("Invalid preview expiry");
187365
187491
  }
187366
187492
  if (value.status === "ready") {
@@ -187604,9 +187730,12 @@ var APPLICATION_TOOL_SCHEMA = {
187604
187730
  "get_deployment_evidence",
187605
187731
  "get_configuration",
187606
187732
  "put_configuration",
187733
+ "get_deploy_plan",
187734
+ "deploy_release",
187607
187735
  "activate_release",
187608
187736
  "rollback_release",
187609
187737
  "get_rollback_snapshot",
187738
+ "get_history",
187610
187739
  "reconcile_activation",
187611
187740
  "retire_activation",
187612
187741
  ...APPLICATION_PREVIEW_ACTIONS,
@@ -187614,15 +187743,15 @@ var APPLICATION_TOOL_SCHEMA = {
187614
187743
  ]), "Action"),
187615
187744
  ref: withDescription(String2(), "Project ref"),
187616
187745
  id: withDescription(ApplicationIdSchema2, "Application ID"),
187617
- environment_id: optional(withDescription(ApplicationIdSchema2, "[get_runtime/get_configuration/put_configuration/get_rollback_snapshot/rollback_release] Environment ID")),
187618
- configuration_id: optional(ApplicationConfigurationIdSchema2, "[get_configuration/activate_release/rollback_release] Immutable revision; required for explicit activation"),
187619
- activation_id: optional(ApplicationActivationIdSchema2, "[activate_release/reconcile_activation/retire_activation/rollback_release] Explicit stable activation ID; generated for rollback if omitted"),
187620
- expected_activation_id: optional(Union([ApplicationActivationIdSchema2, Null(), Literal("absent")]), "[activate_release/rollback_release] Current activation ID, or absent for first activation; selected by platform for default rollback"),
187746
+ environment_id: optional(withDescription(ApplicationIdSchema2, "[get_runtime/get_configuration/put_configuration/get_deploy_plan/deploy_release/get_rollback_snapshot/rollback_release/get_history] Environment ID")),
187747
+ configuration_id: optional(ApplicationConfigurationIdSchema2, "[get_configuration/get_deploy_plan/deploy_release/activate_release/rollback_release/get_history] Immutable revision; required for deployment"),
187748
+ activation_id: optional(ApplicationActivationIdSchema2, "[deploy_release/activate_release/reconcile_activation/retire_activation/rollback_release/get_history] Stable activation ID; generated for automatic deployment/rollback if omitted"),
187749
+ expected_activation_id: optional(Union([ApplicationActivationIdSchema2, Null(), Literal("absent")]), "[deploy_release/activate_release/rollback_release] Current activation ID, or absent for first activation; selected from verified plan for automatic deployment"),
187621
187750
  configuration_path: optional(String2(), "[put_configuration] Local configuration write JSON including revision and expected revision"),
187622
187751
  manifest_path: optional(String2(), "[upload_release] Local delivery.manifest.json"),
187623
- release_id: optional(ApplicationReleaseIdSchema2, "[get_release/activate_release/reconcile_activation/rollback_release] Immutable application release ID; platform selects previous for default rollback"),
187624
- cursor: optional(ApplicationReleaseIdSchema2, "[list_releases] Last release ID"),
187625
- limit: optional(Integer({ minimum: 1, maximum: 100 }), "[list_releases] Page size, default 50"),
187752
+ release_id: optional(ApplicationReleaseIdSchema2, "[get_release/get_deploy_plan/deploy_release/activate_release/reconcile_activation/rollback_release] Immutable application release ID; platform selects previous for default rollback"),
187753
+ cursor: optional(Union([ApplicationReleaseIdSchema2, ApplicationActivationHistoryCursorSchema2]), "[list_releases/get_history] Returned page cursor"),
187754
+ limit: optional(Integer({ minimum: 1, maximum: 100 }), "[list_releases/get_history] Page size, default 50/20"),
187626
187755
  offset: optional(Integer({ minimum: 0, maximum: 1e6 }), "[logs] Result offset"),
187627
187756
  service: optional(String2(), "[logs] Application target/service filter"),
187628
187757
  search: optional(String2(), "[logs] Full-text log filter"),
@@ -187653,6 +187782,84 @@ function boundRelease(value, ref, id) {
187653
187782
  throw new Error("Unbound application release");
187654
187783
  return release;
187655
187784
  }
187785
+ async function readDeployPlan(http, args, project) {
187786
+ const ref = text(args, "ref"), id = text(args, "id"), environmentId = text(args, "environment_id");
187787
+ const releaseId = text(args, "release_id"), configurationId = text(args, "configuration_id");
187788
+ if (!Check2(ApplicationIdSchema2, environmentId) || !Check2(ApplicationReleaseIdSchema2, releaseId) || !Check2(ApplicationConfigurationIdSchema2, configurationId))
187789
+ throw new Error("Invalid deployment plan identity");
187790
+ const identity = {
187791
+ project_ref: ref,
187792
+ application_id: id,
187793
+ environment_id: environmentId,
187794
+ release_id: releaseId,
187795
+ configuration_id: configurationId
187796
+ };
187797
+ const query = new URLSearchParams({ release_id: releaseId, configuration_id: configurationId });
187798
+ const response = await http.get(`/v1/projects/${project}/applications/${encodeURIComponent(id)}/environments/${encodeURIComponent(environmentId)}/deploy-plan?${query}`, { maxJsonBytes: 65536, responseTimeoutMs: 30000 });
187799
+ const operation = `applications.${text(args, "action")}`;
187800
+ if (!response.ok)
187801
+ return { failure: releaseControlFailure(operation, "HTTP_ERROR", response.transportError ? null : response.status, identity) };
187802
+ let plan;
187803
+ try {
187804
+ if (response.status !== 200)
187805
+ throw new Error("Incomplete deployment plan response");
187806
+ plan = parseApplicationDeployPlan(response.data);
187807
+ if (plan.project_ref !== ref || plan.application_id !== id || plan.environment_id !== environmentId || plan.candidate.release_id !== releaseId || plan.candidate.configuration_id !== configurationId)
187808
+ throw new Error;
187809
+ } catch {
187810
+ return { failure: releaseControlFailure(operation, "INVALID_RESPONSE", response.status, identity) };
187811
+ }
187812
+ return { plan, identity };
187813
+ }
187814
+ async function deployAction(http, args, project) {
187815
+ const activationId = args["activation_id"], expected = args["expected_activation_id"];
187816
+ if (activationId !== undefined && !Check2(ApplicationActivationIdSchema2, activationId)) {
187817
+ throw new Error("Invalid application activation ID");
187818
+ }
187819
+ if (expected !== undefined && expected !== null && expected !== "absent" && !Check2(ApplicationActivationIdSchema2, expected))
187820
+ throw new Error("Invalid expected activation ID");
187821
+ if (activationId !== undefined && expected !== undefined) {
187822
+ return activationAction(http, { ...args, action: "activate_release" }, project, {
187823
+ operation: "applications.deploy_release",
187824
+ configuration_id: args["configuration_id"],
187825
+ expected_activation_id: expected === "absent" ? null : expected
187826
+ });
187827
+ }
187828
+ const observed = await readDeployPlan(http, args, project);
187829
+ if (observed.failure)
187830
+ return observed.failure;
187831
+ const { plan, identity } = observed;
187832
+ if (expected !== undefined && (expected === "absent" ? null : expected) !== plan.expected_activation_id) {
187833
+ return releaseControlFailure("applications.deploy_release", "HTTP_ERROR", 409, {
187834
+ ...identity,
187835
+ reason: "EXPECTED_ACTIVATION_CONFLICT",
187836
+ expected_activation_id: plan.expected_activation_id
187837
+ });
187838
+ }
187839
+ if (plan.action === "no-op")
187840
+ return releaseControlSuccess("applications.deploy_release", {
187841
+ ...identity,
187842
+ no_op: true,
187843
+ execution_performed: false,
187844
+ activation_id: plan.current.activation_id,
187845
+ expected_activation_id: plan.expected_activation_id,
187846
+ plan,
187847
+ ...activationId === undefined ? {} : { requested_activation_id: activationId }
187848
+ });
187849
+ const selectedId = activationId ?? crypto.randomUUID();
187850
+ if (selectedId === plan.expected_activation_id)
187851
+ throw new Error("Deployment requires a new activation ID");
187852
+ return activationAction(http, {
187853
+ ...args,
187854
+ action: "activate_release",
187855
+ activation_id: selectedId,
187856
+ expected_activation_id: plan.expected_activation_id
187857
+ }, project, {
187858
+ operation: "applications.deploy_release",
187859
+ configuration_id: args["configuration_id"],
187860
+ expected_activation_id: plan.expected_activation_id
187861
+ });
187862
+ }
187656
187863
  async function configurationAction(http, args, project) {
187657
187864
  const action = text(args, "action"), ref = text(args, "ref"), id = text(args, "id");
187658
187865
  const environmentId = text(args, "environment_id"), operation = `applications.${action}`;
@@ -187699,7 +187906,7 @@ async function configurationAction(http, args, project) {
187699
187906
  return releaseControlFailure(operation, action === "put_configuration" ? "OUTCOME_UNKNOWN" : "INVALID_RESPONSE", result.status, identity);
187700
187907
  }
187701
187908
  }
187702
- async function activationAction(http, args, project, rollback) {
187909
+ async function activationAction(http, args, project, selection) {
187703
187910
  const action = text(args, "action"), ref = text(args, "ref"), id = text(args, "id");
187704
187911
  const environmentId = text(args, "environment_id"), activationId = text(args, "activation_id");
187705
187912
  const releaseId = args["release_id"] === undefined ? undefined : text(args, "release_id");
@@ -187709,7 +187916,7 @@ async function activationAction(http, args, project, rollback) {
187709
187916
  if (!Check2(ApplicationIdSchema2, environmentId) || !Check2(ApplicationActivationIdSchema2, activationId) || action !== "retire_activation" && !Check2(ApplicationReleaseIdSchema2, releaseId)) {
187710
187917
  throw new Error("Invalid application activation identity");
187711
187918
  }
187712
- const operation = rollback ? "applications.rollback_release" : `applications.${action}`;
187919
+ const operation = selection?.operation ?? `applications.${action}`;
187713
187920
  const path = `/v1/projects/${project}/applications/${encodeURIComponent(id)}/environments/${encodeURIComponent(environmentId)}/activations`;
187714
187921
  const identity = {
187715
187922
  project_ref: ref,
@@ -187718,7 +187925,11 @@ async function activationAction(http, args, project, rollback) {
187718
187925
  activation_id: activationId,
187719
187926
  ...releaseId ? { release_id: releaseId } : {}
187720
187927
  };
187721
- const safeState = { ...identity, ...rollback ?? {} };
187928
+ const selectedState = selection ? {
187929
+ configuration_id: selection.configuration_id,
187930
+ expected_activation_id: selection.expected_activation_id
187931
+ } : {};
187932
+ const safeState = { ...identity, ...selectedState };
187722
187933
  let body = {};
187723
187934
  if (action === "activate_release") {
187724
187935
  body = {
@@ -187745,7 +187956,7 @@ async function activationAction(http, args, project, rollback) {
187745
187956
  if (!Check2(ApplicationActivationResultSchema2, result.data) || Object.entries(identity).some(([key, value]) => Reflect.get(result.data, key) !== value) || action === "reconcile_activation" && !result.data.replayed) {
187746
187957
  return releaseControlFailure(operation, "OUTCOME_UNKNOWN", result.status, safeState);
187747
187958
  }
187748
- return releaseControlSuccess(operation, { ...result.data, ...rollback ?? {} });
187959
+ return releaseControlSuccess(operation, { ...result.data, ...selectedState });
187749
187960
  }
187750
187961
  async function rollbackAction(http, args, project) {
187751
187962
  const ref = text(args, "ref"), id = text(args, "id"), environmentId = text(args, "environment_id");
@@ -187794,10 +188005,38 @@ async function rollbackAction(http, args, project) {
187794
188005
  configuration_id: configurationId,
187795
188006
  expected_activation_id: expectedActivationId
187796
188007
  }, project, {
188008
+ operation: "applications.rollback_release",
187797
188009
  configuration_id: configurationId,
187798
188010
  expected_activation_id: expectedActivationId === "absent" ? null : expectedActivationId
187799
188011
  });
187800
188012
  }
188013
+ async function historyAction(http, args, project) {
188014
+ const ref = text(args, "ref"), id = text(args, "id"), environmentId = text(args, "environment_id");
188015
+ if (!Check2(ApplicationIdSchema2, environmentId))
188016
+ throw new Error("Invalid environment ID");
188017
+ const limit = args["limit"] ?? 20, cursor = args["cursor"];
188018
+ if (typeof limit !== "number" || !Number.isInteger(limit) || limit < 1 || limit > 100 || cursor !== undefined && typeof cursor !== "string")
188019
+ throw new Error("Invalid history page");
188020
+ const query = new URLSearchParams({ limit: String(limit) });
188021
+ const scope = { project_ref: ref, application_id: id, environment_id: environmentId };
188022
+ const before = typeof cursor === "string" ? parseApplicationHistoryCursor(cursor, scope) : null;
188023
+ if (typeof cursor === "string")
188024
+ query.set("cursor", cursor);
188025
+ const operation = "applications.get_history";
188026
+ const response = await http.get(`/v1/projects/${project}/applications/${encodeURIComponent(id)}/environments/${encodeURIComponent(environmentId)}/history?${query}`, { maxJsonBytes: 262144, responseTimeoutMs: 30000 });
188027
+ if (!response.ok)
188028
+ return releaseControlFailure(operation, "HTTP_ERROR", response.transportError ? null : response.status, scope);
188029
+ try {
188030
+ if (response.status !== 200)
188031
+ throw new Error;
188032
+ const history = parseApplicationActivationHistory(response.data);
188033
+ if (history.project_ref !== ref || history.application_id !== id || history.environment_id !== environmentId || history.activations.length > limit || history.next_cursor !== null && history.activations.length !== limit || before && history.activations.some((entry) => !applicationHistoryPositionBefore(entry, before)))
188034
+ throw new Error;
188035
+ return releaseControlSuccess(operation, { project_ref: ref, application_id: id, environment_id: environmentId, history });
188036
+ } catch {
188037
+ return releaseControlFailure(operation, "INVALID_RESPONSE", response.status, scope);
188038
+ }
188039
+ }
187801
188040
  function registerApplicationTools(server2, http) {
187802
188041
  registerTool(server2, "applications", "Store, inspect and explicitly activate immutable HTTP/Worker application releases. Upload does not activate a release.", APPLICATION_TOOL_SCHEMA, async (args) => {
187803
188042
  const action = text(args, "action"), ref = text(args, "ref"), id = text(args, "id");
@@ -187806,9 +188045,17 @@ function registerApplicationTools(server2, http) {
187806
188045
  throw new Error("Invalid application ID");
187807
188046
  const path = `/v1/projects/${project}/applications/${encodeURIComponent(id)}/releases`;
187808
188047
  const operation = `applications.${action}`;
188048
+ if (action === "get_deploy_plan") {
188049
+ const observed = await readDeployPlan(http, args, project);
188050
+ return observed.failure ?? releaseControlSuccess(operation, { ...observed.identity, plan: observed.plan });
188051
+ }
188052
+ if (action === "deploy_release")
188053
+ return deployAction(http, args, project);
187809
188054
  if (action === "rollback_release" || action === "get_rollback_snapshot") {
187810
188055
  return rollbackAction(http, args, project);
187811
188056
  }
188057
+ if (action === "get_history")
188058
+ return historyAction(http, args, project);
187812
188059
  if (APPLICATION_PREVIEW_ACTIONS.some((value) => value === action)) {
187813
188060
  return applicationPreviewAction(http, args, project);
187814
188061
  }
@@ -194053,10 +194300,13 @@ async function applyScaffoldWrites(plan) {
194053
194300
  var REMOTE_APP_ACTIONS = {
194054
194301
  upload: "upload_release",
194055
194302
  configure: "put_configuration",
194056
- deploy: "activate_release",
194303
+ deploy: "deploy_release",
194304
+ "deploy-plan": "get_deploy_plan",
194305
+ diff: "get_deploy_plan",
194057
194306
  status: "get_runtime",
194058
194307
  rollback: "rollback_release",
194059
194308
  "rollback-plan": "get_rollback_snapshot",
194309
+ history: "get_history",
194060
194310
  reconcile: "reconcile_activation",
194061
194311
  retire: "retire_activation",
194062
194312
  logs: "logs",
@@ -194067,22 +194317,24 @@ var REMOTE_APP_ACTIONS = {
194067
194317
  "preview-cleanup": "cleanup_preview"
194068
194318
  };
194069
194319
  var REMOTE_APP_DESCRIPTIONS = {
194070
- ref: "[upload/configure/deploy/status/rollback/rollback-plan/reconcile/retire/preview-plan/preview/previews/preview-status/preview-cleanup] Project ref (defaults to context)",
194071
- id: "[upload/configure/deploy/status/rollback/rollback-plan/reconcile/retire/preview-plan/preview/previews/preview-status/preview-cleanup] Application ID",
194072
- environment_id: "[configure/deploy/status/rollback/rollback-plan/reconcile/retire/preview-plan/preview/previews/preview-status/preview-cleanup] Environment ID",
194073
- configuration_id: "[deploy/rollback/preview] Required for deploy/preview/explicit rollback; platform selects for default rollback",
194074
- activation_id: "[deploy/rollback/reconcile/retire] Required explicit activation ID; generated for rollback if omitted",
194075
- expected_activation_id: "[deploy/rollback] Required for deploy/explicit rollback; platform selects current CAS for default rollback",
194320
+ ref: "[upload/configure/deploy/deploy-plan/diff/status/rollback/rollback-plan/history/reconcile/retire/preview-plan/preview/previews/preview-status/preview-cleanup] Project ref (defaults to context)",
194321
+ id: "[upload/configure/deploy/deploy-plan/diff/status/rollback/rollback-plan/history/reconcile/retire/preview-plan/preview/previews/preview-status/preview-cleanup] Application ID",
194322
+ environment_id: "[configure/deploy/deploy-plan/diff/status/rollback/rollback-plan/history/reconcile/retire/preview-plan/preview/previews/preview-status/preview-cleanup] Environment ID",
194323
+ configuration_id: "[deploy/deploy-plan/diff/rollback/preview] Required for deployment/preview; platform selects for default rollback",
194324
+ activation_id: "[deploy/rollback/reconcile/retire] Stable activation ID; auto-generated for deploy/rollback if omitted",
194325
+ expected_activation_id: "[deploy/rollback] Auto-selected from verified state; supply with activation_id for an exact retry",
194076
194326
  configuration_path: "[configure] Configuration write JSON including revision and expected revision",
194077
194327
  manifest_path: "[upload] Local delivery.manifest.json",
194078
- release_id: "[deploy/rollback/reconcile/preview-plan/preview] Required for deploy/reconcile/preview; defaults to journal-selected previous for rollback",
194328
+ release_id: "[deploy/deploy-plan/diff/rollback/reconcile/preview-plan/preview] Required for deployment/preview; defaults to journal-selected previous for rollback",
194079
194329
  preview_id: "[preview-status/preview-cleanup] Preview receipt ID",
194080
194330
  branch_ref: "[preview-plan] Proposed branch ref; preview assigns its own",
194081
194331
  branch_name: "[preview] Branch display name",
194082
194332
  data_mode: "[preview-plan/preview] Default schema_only; full_clone copies rows",
194083
194333
  ttl_seconds: "[preview-plan/preview] Lifetime from 300 to 604800 seconds; creation defaults to the platform TTL",
194084
194334
  wait: "[preview/preview-status] Wait for verified readiness of the selected preview",
194085
- timeout_seconds: "[preview/preview-status] Observation budget with --wait, from 1 to 3600 seconds (default 300)"
194335
+ timeout_seconds: "[preview/preview-status] Observation budget with --wait, from 1 to 3600 seconds (default 300)",
194336
+ cursor: "[history] Returned page cursor",
194337
+ limit: "[history] Page size, default 20 (1-100)"
194086
194338
  };
194087
194339
  var { action: _remoteAction, ...remoteFields } = APPLICATION_TOOL_SCHEMA;
194088
194340
  var REMOTE_APP_SCHEMA = Partial(_Object_(remoteFields)).properties;
@@ -194981,6 +195233,75 @@ async function runDelivery(args) {
194981
195233
  const result = await buildDeliveryProject(options, loaded.delivery);
194982
195234
  return textResult(JSON.stringify(result, null, 2), !result.ok);
194983
195235
  }
195236
+ var historyReceiptSchema = _Object_({
195237
+ schema: Literal(RELEASE_CONTROL_RESPONSE_SCHEMA),
195238
+ ok: Literal(true),
195239
+ operation: Literal("applications.get_history"),
195240
+ project_ref: String2(),
195241
+ application_id: String2(),
195242
+ environment_id: String2(),
195243
+ history: ApplicationActivationHistorySchema
195244
+ }, { additionalProperties: false });
195245
+ function historyText(result, request, projectRef) {
195246
+ if (result.isError)
195247
+ return result;
195248
+ try {
195249
+ if (result.content.length !== 1 || result.content[0].text.length > 262144)
195250
+ throw new Error;
195251
+ const receipt = JSON.parse(result.content[0].text);
195252
+ if (!Check2(historyReceiptSchema, receipt))
195253
+ throw new Error;
195254
+ const history = parseApplicationActivationHistory(receipt.history);
195255
+ if (history.project_ref !== projectRef || history.application_id !== request.id || history.environment_id !== request.environment_id || receipt.project_ref !== history.project_ref || receipt.application_id !== history.application_id || receipt.environment_id !== history.environment_id)
195256
+ throw new Error;
195257
+ const lines = [
195258
+ `Activation History: ${history.project_ref}/${history.application_id}/${history.environment_id}`,
195259
+ `Active activation: ${history.active_activation_id ?? "none"}`,
195260
+ ""
195261
+ ];
195262
+ if (history.activations.length === 0)
195263
+ lines.push("No successful activations on this page.");
195264
+ else {
195265
+ lines.push(`${"Completed (UTC)".padEnd(29)} ${"State".padEnd(7)} ${"Activation ID".padEnd(36)} Release (12)`);
195266
+ for (const entry of history.activations)
195267
+ lines.push(`${entry.completed_at.padEnd(29)} ${(entry.is_active ? "current" : "-").padEnd(7)} ${entry.activation_id} ${entry.release_id.slice(0, 12)}`);
195268
+ }
195269
+ if (history.next_cursor)
195270
+ lines.push("", `Next cursor: ${history.next_cursor}`);
195271
+ return textResult(lines.join(`
195272
+ `));
195273
+ } catch {
195274
+ return releaseControlFailure("applications.get_history", "INVALID_RESPONSE", null);
195275
+ }
195276
+ }
195277
+ function formatRemoteDeployPlan(result) {
195278
+ if (result.isError)
195279
+ return result;
195280
+ try {
195281
+ const payload = JSON.parse(result.content[0]?.text ?? "");
195282
+ if (!payload || typeof payload !== "object" || !("ok" in payload) || payload.ok !== true || !("plan" in payload))
195283
+ return result;
195284
+ const plan = parseApplicationDeployPlan(payload.plan);
195285
+ const names = (values, prefix) => values.map((name) => `${prefix}${name}`);
195286
+ const targets = [
195287
+ ...names(plan.changes.targets.added, "+"),
195288
+ ...names(plan.changes.targets.removed, "-"),
195289
+ ...names(plan.changes.targets.changed, "~")
195290
+ ];
195291
+ return textResult([
195292
+ `${plan.project_ref}/${plan.application_id} [${plan.environment_id}]: ${plan.action === "no-op" ? "No changes" : "Activation required"}`,
195293
+ `Release: ${plan.candidate.release_id} (${plan.changes.release ? "changed" : "unchanged"})`,
195294
+ `Configuration: ${plan.candidate.configuration_id} (${plan.changes.configuration ? "changed" : "unchanged"})`,
195295
+ `Targets: ${targets.length ? targets.join(", ") : "unchanged"}`,
195296
+ `Migrations: ${!plan.migrations.ledger_compatible ? "ledger conflict" : plan.migrations.project_migrations_applied ? "applied" : "pending"}`,
195297
+ `Provisioning: ${plan.migrations.operator_provisioning}`,
195298
+ `Expected activation: ${plan.expected_activation_id ?? "absent"}`
195299
+ ].join(`
195300
+ `));
195301
+ } catch {
195302
+ return result;
195303
+ }
195304
+ }
194984
195305
  async function runAppTool(request, options = {}) {
194985
195306
  if (request.dry_run !== undefined && request["dry-run"] !== undefined || request.register_in !== undefined && request["register-in"] !== undefined || request.database_url !== undefined && request["database-url"] !== undefined) {
194986
195307
  throw new ScaffoldError("SCAFFOLD_OPTION_INVALID", "Do not combine hyphenated and underscored aliases of the same flag");
@@ -194997,18 +195318,26 @@ async function runAppTool(request, options = {}) {
194997
195318
  if (request.database_url !== undefined && request.action !== "dev" && request.action !== "watch") {
194998
195319
  throw new ScaffoldError("SCAFFOLD_OPTION_INVALID", "--database-url applies only to app dev --profile integration");
194999
195320
  }
195321
+ if (request.json !== undefined && (request.action !== "history" || request.json !== true || request.format === "text")) {
195322
+ throw new Error("--json applies only to app history and cannot be combined with --format text");
195323
+ }
195000
195324
  if (Object.hasOwn(REMOTE_APP_ACTIONS, request.action)) {
195001
195325
  const delegate = options.getApplications?.();
195002
195326
  if (!delegate)
195003
195327
  return textResult("App remote actions require a Management API context.", true);
195004
195328
  const action = REMOTE_APP_ACTIONS[request.action];
195329
+ const { format, json, ...remoteRequest } = request;
195005
195330
  const args = {
195006
- ...request,
195331
+ ...remoteRequest,
195007
195332
  action,
195008
195333
  ref: request.ref ?? options.projectRef
195009
195334
  };
195010
195335
  validateToolArguments(APPLICATION_TOOL_SCHEMA, args);
195011
- return delegate(args);
195336
+ const result = await delegate(args);
195337
+ if (request.action === "history" && format !== "json" && json !== true) {
195338
+ return historyText(result, request, args.ref);
195339
+ }
195340
+ return (request.action === "deploy-plan" || request.action === "diff") && format !== "json" ? formatRemoteDeployPlan(result) : result;
195012
195341
  }
195013
195342
  switch (request.action) {
195014
195343
  case "verify-plan": {
@@ -195083,9 +195412,12 @@ function registerAppTools(server2, options = {}) {
195083
195412
  "upload",
195084
195413
  "configure",
195085
195414
  "deploy",
195415
+ "deploy-plan",
195416
+ "diff",
195086
195417
  "status",
195087
195418
  "rollback",
195088
195419
  "rollback-plan",
195420
+ "history",
195089
195421
  "reconcile",
195090
195422
  "retire",
195091
195423
  "logs",
@@ -195094,7 +195426,7 @@ function registerAppTools(server2, options = {}) {
195094
195426
  "previews",
195095
195427
  "preview-status",
195096
195428
  "preview-cleanup"
195097
- ]), "App action; upload/configure only prepare, rollback activates the journal-selected previous release without schema downgrade"),
195429
+ ]), "App action; local plan is topology-only, deploy-plan/diff observe remote state, deploy skips verified no-op, rollback never downgrades schema"),
195098
195430
  kind: optional(stringEnum(["module", "command", "query", "controller", "job", "contract", "resource"]), "[generate] Scaffold kind"),
195099
195431
  template: optional(stringEnum(["minimal", "http", "command", "edge"]), "[init] Minimal application by default; explicit http/command/edge recipes"),
195100
195432
  name: optional(String2(), "[init/generate] Project or object name"),
@@ -195109,7 +195441,8 @@ function registerAppTools(server2, options = {}) {
195109
195441
  include: optional(String2(), "[dev/compile/check] Comma-separated glob patterns for source files"),
195110
195442
  out_dir: optional(String2(), "[dev/compile/plan/build/export-tools] Output directory (default: configured outDir)"),
195111
195443
  strict: optional(Boolean2(), "[dev/compile/check] Promote warnings to errors"),
195112
- format: optional(stringEnum(["text", "json"]), "[dev/generate/compile/check/plan/graph/export-tools] Output format (default: text)"),
195444
+ format: optional(stringEnum(["text", "json"]), "[dev/generate/compile/check/plan/deploy-plan/diff/history/graph/export-tools] Output format (default: text)"),
195445
+ json: optional(Literal(true), "[history] Return the validated JSON receipt"),
195113
195446
  profile: optional(stringEnum(["fast", "integration"]), "[dev] Run dev or dev:integration; integration verifies an explicit loopback database"),
195114
195447
  once: optional(Boolean2(), "[dev] Validate and report once without watching"),
195115
195448
  watch: optional(Boolean2(), "[dev] Watch for changes (default: true; --once disables)"),
@@ -198661,7 +198994,7 @@ function registerRemoteDevTools(server2, options = {}) {
198661
198994
  // package.json
198662
198995
  var package_default = {
198663
198996
  name: "@supacloud/cli",
198664
- version: "0.79.0",
198997
+ version: "0.80.0",
198665
198998
  description: "Project-scoped CLI for SupaCloud users",
198666
198999
  type: "module",
198667
199000
  main: "./dist/index.js",
@@ -198713,14 +199046,14 @@ var package_default = {
198713
199046
  },
198714
199047
  dependencies: {
198715
199048
  "@supacloud/compiler": "^0.43.0",
198716
- "@supacloud/delivery": "0.9.0",
199049
+ "@supacloud/delivery": "0.10.0",
198717
199050
  "@supacloud/db": "0.16.0",
198718
199051
  fflate: "^0.8.3",
198719
199052
  typebox: "1.3.34"
198720
199053
  },
198721
199054
  overrides: {
198722
199055
  "@supacloud/contracts": "0.8.0",
198723
- "@supacloud/delivery": "0.9.0",
199056
+ "@supacloud/delivery": "0.10.0",
198724
199057
  "@graphql-tools/utils": "^12.0.3"
198725
199058
  },
198726
199059
  devDependencies: {
@@ -198981,7 +199314,9 @@ EXAMPLES
198981
199314
  ${preferredCommand} app build --root .
198982
199315
  ${preferredCommand} app upload --ref abc123 --id orders --manifest_path generated/delivery/delivery.manifest.json
198983
199316
  ${preferredCommand} app configure --ref abc123 --id orders --environment_id test --configuration_path configuration.json
198984
- ${preferredCommand} app deploy --ref abc123 --id orders --environment_id test --release_id <sha256> --configuration_id <uuid> --activation_id <uuid> --expected_activation_id absent
199317
+ ${preferredCommand} app deploy-plan --ref abc123 --id orders --environment_id test --release_id <sha256> --configuration_id <uuid>
199318
+ ${preferredCommand} app diff --ref abc123 --id orders --environment_id test --release_id <sha256> --configuration_id <uuid>
199319
+ ${preferredCommand} app deploy --ref abc123 --id orders --environment_id test --release_id <sha256> --configuration_id <uuid>
198985
199320
  ${preferredCommand} app status --ref abc123 --id orders --environment_id test
198986
199321
  ${preferredCommand} app preview-plan --ref abc123 --id orders --environment_id test --release_id <sha256> --branch_ref preview-orders
198987
199322
  ${preferredCommand} app preview --ref abc123 --id orders --environment_id test --release_id <sha256> --configuration_id <uuid> --ttl_seconds 3600 --wait
@@ -3,10 +3,13 @@ import { type AppManifest } from "./app-tool-export";
3
3
  declare const REMOTE_APP_ACTIONS: {
4
4
  readonly upload: "upload_release";
5
5
  readonly configure: "put_configuration";
6
- readonly deploy: "activate_release";
6
+ readonly deploy: "deploy_release";
7
+ readonly "deploy-plan": "get_deploy_plan";
8
+ readonly diff: "get_deploy_plan";
7
9
  readonly status: "get_runtime";
8
10
  readonly rollback: "rollback_release";
9
11
  readonly "rollback-plan": "get_rollback_snapshot";
12
+ readonly history: "get_history";
10
13
  readonly reconcile: "reconcile_activation";
11
14
  readonly retire: "retire_activation";
12
15
  readonly logs: "logs";
@@ -35,6 +38,8 @@ export interface AppToolArguments {
35
38
  configuration_path?: string;
36
39
  manifest_path?: string;
37
40
  release_id?: string;
41
+ cursor?: string;
42
+ limit?: number;
38
43
  preview_id?: string;
39
44
  branch_ref?: string;
40
45
  branch_name?: string;
@@ -57,6 +62,7 @@ export interface AppToolArguments {
57
62
  out_dir?: string;
58
63
  strict?: boolean;
59
64
  format?: "text" | "json";
65
+ json?: true;
60
66
  target?: string;
61
67
  fix?: string;
62
68
  write?: boolean;
@@ -0,0 +1 @@
1
+ export {};
@@ -89,3 +89,4 @@ export declare const ApplicationRollbackSnapshotSchema: import("typebox").TObjec
89
89
  activation_id: import("typebox").TString;
90
90
  }>, import("typebox").TNull]>;
91
91
  }>;
92
+ export declare const ApplicationActivationHistoryCursorSchema: import("typebox").TString;
@@ -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_rollback_snapshot" | "get_preview_plan" | "put_configuration" | "rollback_release" | "reconcile_activation" | "retire_activation" | "create_preview" | "list_previews" | "get_preview" | "cleanup_preview")[]>;
12
+ action: Type.TEnum<("list_releases" | "get_release" | "upload_release" | "activate_release" | "logs" | "get_runtime" | "get_deployment_evidence" | "get_configuration" | "get_rollback_snapshot" | "get_history" | "get_deploy_plan" | "get_preview_plan" | "put_configuration" | "deploy_release" | "rollback_release" | "reconcile_activation" | "retire_activation" | "create_preview" | "list_previews" | "get_preview" | "cleanup_preview")[]>;
13
13
  ref: Type.TString;
14
14
  id: Type.TString;
15
15
  environment_id: Type.TOptional<Type.TString>;
@@ -19,7 +19,7 @@ export declare const APPLICATION_TOOL_SCHEMA: {
19
19
  configuration_path: Type.TOptional<Type.TString>;
20
20
  manifest_path: Type.TOptional<Type.TString>;
21
21
  release_id: Type.TOptional<Type.TString>;
22
- cursor: Type.TOptional<Type.TString>;
22
+ cursor: Type.TOptional<Type.TUnion<[Type.TString, Type.TString]>>;
23
23
  limit: Type.TOptional<Type.TInteger>;
24
24
  offset: Type.TOptional<Type.TInteger>;
25
25
  service: Type.TOptional<Type.TString>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.79.0",
3
+ "version": "0.80.0",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -52,14 +52,14 @@
52
52
  },
53
53
  "dependencies": {
54
54
  "@supacloud/compiler": "^0.43.0",
55
- "@supacloud/delivery": "0.9.0",
55
+ "@supacloud/delivery": "0.10.0",
56
56
  "@supacloud/db": "0.16.0",
57
57
  "fflate": "^0.8.3",
58
58
  "typebox": "1.3.34"
59
59
  },
60
60
  "overrides": {
61
61
  "@supacloud/contracts": "0.8.0",
62
- "@supacloud/delivery": "0.9.0",
62
+ "@supacloud/delivery": "0.10.0",
63
63
  "@graphql-tools/utils": "^12.0.3"
64
64
  },
65
65
  "devDependencies": {