@supacloud/cli 0.108.0 → 0.108.2

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
@@ -21603,7 +21603,7 @@ var starter_metadata_default = {
21603
21603
  version: "0.11.0"
21604
21604
  },
21605
21605
  contracts: {
21606
- version: "0.14.0"
21606
+ version: "0.15.0"
21607
21607
  },
21608
21608
  db: {
21609
21609
  version: "0.20.0",
@@ -21949,7 +21949,7 @@ function baseFiles(name, sdkDependencies) {
21949
21949
  check: "bun run compile && bun run check:generated && bun run typecheck && bun run test",
21950
21950
  test: "bun run compile && bun --no-env-file scripts/environment.ts test bun test",
21951
21951
  dev: "bun --no-env-file scripts/environment.ts development bun scripts/dev.ts",
21952
- build: "bun run compile && bun run typecheck && bun build src/application.ts --target bun --minify --outdir dist",
21952
+ build: "bun run compile && bun run typecheck && bun build src/application.ts --target bun --minify --outdir output/supacloud",
21953
21953
  "env:development": "bun --no-env-file scripts/environment.ts development",
21954
21954
  "env:test": "bun --no-env-file scripts/environment.ts test",
21955
21955
  "env:staging": "bun --no-env-file scripts/environment.ts staging",
@@ -21990,7 +21990,7 @@ function baseFiles(name, sdkDependencies) {
21990
21990
  }),
21991
21991
  "bunfig.toml": `env = false
21992
21992
  `,
21993
- ".gitignore": ["node_modules/", "dist/", ".env", ".env.*", "!.env.*.example", "!.env.test", ""].join(`
21993
+ ".gitignore": ["node_modules/", "dist/", "output/supacloud/", ".env", ".env.*", "!.env.*.example", "!.env.test", ""].join(`
21994
21994
  `),
21995
21995
  ".env.development.example": `APP_ENV=development
21996
21996
  PORT=3000
@@ -22144,10 +22144,15 @@ do not widen them to \`unknown\` just to accept unvalidated data.
22144
22144
  ## Production Boundary
22145
22145
 
22146
22146
  \`bun run build\` emits an application factory, not a server. Import \`createApp\`
22147
- from \`dist/application.js\` in your trusted host and supply real dependency,
22147
+ from \`output/supacloud/application.js\` in your trusted host and supply real dependency,
22148
22148
  request-context and command-governance adapters. The memory sandbox is
22149
22149
  development/test only.
22150
22150
 
22151
+ Keep backend bundles outside the frontend output directory. Vite normally cleans
22152
+ \`dist/\` before building; server artifacts placed there can be deleted or included
22153
+ in a public frontend archive. Use disjoint output directories, not a disabled
22154
+ frontend clean step. Compiler source artifacts remain in \`generated/\`.
22155
+
22151
22156
  ## Inspection And Repair
22152
22157
 
22153
22158
  \`\`\`sh
@@ -22234,6 +22239,10 @@ sandbox. Bind persistence, authorization and audit to durable adapters before
22234
22239
  invoking it in production. Do not schedule destructive work without an
22235
22240
  idempotency key.
22236
22241
 
22242
+ \`bun run build\` emits \`output/supacloud/application.js\`, an application factory,
22243
+ not a deployed Worker. Keep it outside any frontend output directory such as
22244
+ \`dist/\`; frontend clean steps and public archives must not own server bundles.
22245
+
22237
22246
  ## Inspection And Repair
22238
22247
 
22239
22248
  \`\`\`sh
@@ -22338,6 +22347,10 @@ explicit options; do not install every recipe into this application.
22338
22347
  ## Integration and delivery
22339
22348
 
22340
22349
  createApp requires application-owned trusted identity and durable adapters.
22350
+ \`bun run build\` emits \`output/supacloud/application.js\`, not a deployed server.
22351
+ Keep this backend directory separate from frontend output such as \`dist/\`,
22352
+ which frontend tools may clean and publish. Do not disable frontend cleanup to
22353
+ preserve backend artifacts; use disjoint output directories.
22341
22354
  Database migrations and seed data require an explicitly selected development
22342
22355
  database and a reviewed application script; the CLI never infers a production target.
22343
22356
  Commit generated/ after compilation. At release, check generated drift before
@@ -25096,7 +25109,7 @@ function appStarterFiles(name) {
25096
25109
  test: "bun run compile && bun --no-env-file scripts/environment.ts test bun test",
25097
25110
  dev: "bun --no-env-file scripts/environment.ts development bun scripts/dev.ts",
25098
25111
  "dev:integration": "bun --no-env-file scripts/environment.ts development bun scripts/integration.ts",
25099
- build: "bun run db:check && bun run compile && bun run typecheck && bun build src/application.ts --target bun --minify --outdir dist",
25112
+ build: "bun run db:check && bun run compile && bun run typecheck && bun build src/application.ts --target bun --minify --outdir output/supacloud",
25100
25113
  "env:development": "bun --no-env-file scripts/environment.ts development",
25101
25114
  "env:test": "bun --no-env-file scripts/environment.ts test",
25102
25115
  "env:staging": "bun --no-env-file scripts/environment.ts staging",
@@ -25147,6 +25160,7 @@ function appStarterFiles(name) {
25147
25160
  ".gitignore": [
25148
25161
  "node_modules/",
25149
25162
  "dist/",
25163
+ "output/supacloud/",
25150
25164
  "output/database-audit/",
25151
25165
  "db/migration-candidates/",
25152
25166
  ".env",
@@ -25737,16 +25751,21 @@ must also pin and validate the expected project and API origin.
25737
25751
 
25738
25752
  ## Production Boundary
25739
25753
 
25740
- \`bun run build\` creates dist/application.js, an application factory, not a
25754
+ \`bun run build\` creates output/supacloud/application.js, an application factory, not a
25741
25755
  production server. The compiler is a devDependency and is absent from that
25742
25756
  runtime entry. The memory demo is kept in scripts/ and refuses staging/production.
25743
25757
 
25744
- Import createApp from dist/application.js in your trusted host and supply:
25758
+ Import createApp from output/supacloud/application.js in your trusted host and supply:
25745
25759
 
25746
25760
  - deps.dbClient implementing ReviewStore, with reads/writes bound to a real transaction;
25747
25761
  - requestContext from verified identity, never a body-supplied actor;
25748
25762
  - commandGovernance authorization, durable idempotency, transaction and audit adapters.
25749
25763
 
25764
+ Keep backend bundles outside the frontend output directory. Vite normally cleans
25765
+ dist/ before building; server artifacts placed there can be deleted or included
25766
+ in a public frontend archive. Use disjoint output directories, not a disabled
25767
+ frontend clean step. Compiler source artifacts remain in generated/.
25768
+
25750
25769
  The starter also includes src/host/review-postgres.ts and src/delivery-host.ts.
25751
25770
  The PostgreSQL adapter executes the same compiled approval handler with durable
25752
25771
  receipts, audit, current membership/ownership checks on replay and transaction-bound
@@ -25837,7 +25856,7 @@ startup before any request is served.
25837
25856
  ## Unified User Center
25838
25857
 
25839
25858
  For enterprise unified login, use SupAuth as the external user center. This
25840
- starter exports createSupAuthApp(identity, adapters) from dist/application.js.
25859
+ starter exports createSupAuthApp(identity, adapters) from output/supacloud/application.js.
25841
25860
  Supply issuer, audience, clientId, projectId, an explicit HTTPS jwksUrl and resolveAccess
25842
25861
  that reads current application-local access. The runtime verifies credential
25843
25862
  signatures, configured issuer and audience, allowed asymmetric algorithms/keys
@@ -26997,125 +27016,152 @@ import { ${className}Fixture } from "./${name}.fixture";
26997
27016
  const baseUrl = process.env["SUPACLOUD_FEATURE_E2E_URL"];
26998
27017
  const authorization = process.env["SUPACLOUD_FEATURE_E2E_AUTHORIZATION"];
26999
27018
  const otherAuthorization = process.env["SUPACLOUD_FEATURE_E2E_OTHER_AUTHORIZATION"];
27000
- const fixtureId = process.env["SUPACLOUD_FEATURE_E2E_ID"] ?? ${className}Fixture.id;
27019
+ const fixtureId = process.env["SUPACLOUD_FEATURE_E2E_ID"];
27020
+ const raceId = process.env["SUPACLOUD_FEATURE_E2E_RACE_ID"];
27001
27021
  const idempotencyKey = process.env["SUPACLOUD_FEATURE_E2E_IDEMPOTENCY_KEY"];
27002
- const enabled = Boolean(baseUrl && authorization && idempotencyKey);
27003
- const tenantIsolationEnabled = Boolean(enabled && otherAuthorization);
27004
-
27005
- function requireConfig(): { baseUrl: string; authorization: string; idempotencyKey: string } {
27006
- if (!baseUrl || !authorization || !idempotencyKey) {
27007
- throw new Error(
27008
- "Set SUPACLOUD_FEATURE_E2E_URL, SUPACLOUD_FEATURE_E2E_AUTHORIZATION and " +
27009
- "SUPACLOUD_FEATURE_E2E_IDEMPOTENCY_KEY before running this generated E2E test.",
27010
- );
27022
+ const required = process.env["SUPACLOUD_FEATURE_E2E_REQUIRED"] === "1";
27023
+ const enabled = required || [baseUrl, authorization, otherAuthorization, fixtureId, raceId, idempotencyKey]
27024
+ .some(value => value !== undefined);
27025
+
27026
+ function requireConfig() {
27027
+ if (![baseUrl, authorization, otherAuthorization, fixtureId, raceId, idempotencyKey]
27028
+ .every(value => typeof value === "string" && value.trim().length > 0)) {
27029
+ throw new Error("Feature acceptance requires URL, AUTHORIZATION, OTHER_AUTHORIZATION, ID, RACE_ID and IDEMPOTENCY_KEY (SUPACLOUD_FEATURE_E2E_*).");
27030
+ }
27031
+ if (fixtureId === raceId) throw new Error("Feature acceptance requires two distinct draft fixtures.");
27032
+ const url = new URL(baseUrl!);
27033
+ if (url.username || url.password || url.search || url.hash
27034
+ || (url.protocol !== "https:" && !(url.protocol === "http:"
27035
+ && ["127.0.0.1", "localhost", "[::1]"].includes(url.hostname)))) {
27036
+ throw new Error("Feature acceptance requires HTTPS or a loopback HTTP endpoint without embedded credentials.");
27011
27037
  }
27012
- return { baseUrl, authorization, idempotencyKey };
27038
+ return { baseUrl: url, authorization: authorization!, otherAuthorization: otherAuthorization!,
27039
+ fixtureId: fixtureId!, raceId: raceId!, idempotencyKey: idempotencyKey! };
27013
27040
  }
27014
27041
 
27015
- async function json(response: Response): Promise<unknown> {
27016
- const text = await response.text();
27017
- if (!text) return undefined;
27018
- try {
27019
- return JSON.parse(text) as unknown;
27020
- } catch {
27021
- return text;
27022
- }
27042
+ function request(config: ReturnType<typeof requireConfig>, path: string, init: RequestInit = {}) {
27043
+ return fetch(new URL(path, config.baseUrl), {
27044
+ ...init, redirect: "error", signal: AbortSignal.timeout(10_000),
27045
+ });
27023
27046
  }
27024
27047
 
27025
- function containsFixture(value: unknown): boolean {
27026
- return JSON.stringify(value).includes(fixtureId);
27048
+ async function object(response: Response): Promise<Record<string, unknown>> {
27049
+ const value: unknown = await response.json();
27050
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
27051
+ throw new Error("Feature acceptance expected a JSON object.");
27052
+ }
27053
+ return value as Record<string, unknown>;
27027
27054
  }
27028
27055
 
27029
- test.skipIf(!enabled)("${name} authenticated list/detail/approval E2E", async () => {
27056
+ test.skipIf(!enabled)("${name} authenticated approval, replay, recovery and concurrency acceptance", async () => {
27030
27057
  const config = requireConfig();
27031
27058
  const headers = { authorization: config.authorization, "content-type": "application/json" };
27032
- const list = await fetch(new URL("/${name}", config.baseUrl), { headers });
27059
+ const path = (id: string) => "/${name}/" + encodeURIComponent(id);
27060
+ const list = await request(config, "/${name}", { headers });
27033
27061
  expect(list.ok).toBe(true);
27034
- const detail = await fetch(
27035
- new URL("/${name}/" + encodeURIComponent(fixtureId), config.baseUrl),
27036
- { headers },
27037
- );
27062
+ const listed: unknown = await list.json();
27063
+ expect(Array.isArray(listed)).toBe(true);
27064
+ expect(listed).toContainEqual(expect.objectContaining({ id: config.fixtureId }));
27065
+ const detail = await request(config, path(config.fixtureId), { headers });
27038
27066
  expect(detail.ok).toBe(true);
27039
- const approve = (key: string, body = ${className}Fixture.approve) => fetch(
27040
- new URL("/${name}/" + encodeURIComponent(fixtureId) + "/approve", config.baseUrl),
27067
+ const before = await object(detail);
27068
+ expect(before).toMatchObject({ id: config.fixtureId, state: "draft" });
27069
+ expect(Number.isSafeInteger(before["version"])).toBe(true);
27070
+ expect(Number(before["version"])).toBeGreaterThanOrEqual(1);
27071
+ const body = { ...${className}Fixture.approve, expectedVersion: Number(before["version"]) };
27072
+ const approve = (id: string, key: string, input = body) => request(
27073
+ config, path(id) + "/approve",
27041
27074
  {
27042
- method: "POST",
27043
- headers: { ...headers, "idempotency-key": key },
27044
- body: JSON.stringify(body),
27075
+ method: "POST", headers: { ...headers, "idempotency-key": key },
27076
+ body: JSON.stringify(input),
27045
27077
  },
27046
27078
  );
27047
- const first = await approve(config.idempotencyKey);
27048
- const firstBody = await json(first);
27049
- expect([200, 409, 422]).toContain(first.status);
27050
-
27051
- // A lost response is recovered through the durable receipt, never by
27052
- // submitting the approval again.
27053
- const recovered = await fetch(
27054
- new URL("/${name}/" + encodeURIComponent(fixtureId) + "/operations/" + encodeURIComponent(config.idempotencyKey), config.baseUrl),
27055
- { headers },
27056
- );
27079
+ const first = await approve(config.fixtureId, config.idempotencyKey);
27080
+ expect(first.status).toBe(200);
27081
+ const firstBody = await object(first);
27082
+ expect(firstBody).toMatchObject({ id: config.fixtureId, state: "approved" });
27083
+ expect(Number.isSafeInteger(firstBody["version"])).toBe(true);
27084
+ expect(Number(firstBody["version"])).toBeGreaterThan(Number(before["version"]));
27085
+
27086
+ // Read-only reconciliation is exercised here; this is not a network-loss or worker-crash test.
27087
+ const operationPath = path(config.fixtureId) + "/operations/" + encodeURIComponent(config.idempotencyKey);
27088
+ const recovered = await request(config, operationPath, { headers });
27057
27089
  expect(recovered.ok).toBe(true);
27058
- const recoveredBody = await json(recovered);
27059
- expect(recoveredBody).toMatchObject({ operationId: config.idempotencyKey });
27060
- const jobStatus = await fetch(
27061
- new URL("/${name}/" + encodeURIComponent(fixtureId) + "/operations/" + encodeURIComponent(config.idempotencyKey) + "/status", config.baseUrl),
27062
- { headers },
27063
- );
27090
+ expect(await object(recovered)).toMatchObject({
27091
+ id: config.fixtureId, operationId: config.idempotencyKey,
27092
+ status: "confirmed", state: firstBody["state"], version: firstBody["version"],
27093
+ });
27094
+ const jobStatus = await request(config, operationPath + "/status", { headers });
27064
27095
  expect(jobStatus.ok).toBe(true);
27065
- expect(await json(jobStatus)).toMatchObject({ operationId: config.idempotencyKey });
27096
+ const job = await object(jobStatus);
27097
+ expect(job).toMatchObject({ id: config.fixtureId, operationId: config.idempotencyKey });
27098
+ expect(typeof job["status"]).toBe("string");
27099
+ expect(["queued", "running", "completed"].some(status => status === job["status"])).toBe(true);
27066
27100
 
27067
- // Replaying an identical command may return the original success or a
27068
- // domain conflict, but it must never create a second successful transition.
27069
- const replay = await approve(config.idempotencyKey);
27070
- const replayBody = await json(replay);
27101
+ const replay = await approve(config.fixtureId, config.idempotencyKey);
27071
27102
  expect(replay.status).toBe(first.status);
27072
- expect(replayBody).toEqual(firstBody);
27103
+ expect(await object(replay)).toEqual(firstBody);
27073
27104
 
27074
- // Reusing a key with a different payload must be rejected by the receipt
27075
- // boundary instead of being treated as a new approval.
27105
+ // Conflicting replay and stale version must fail without changing the authoritative row.
27076
27106
  const conflicting = await approve(
27077
- config.idempotencyKey,
27078
- { ...${className}Fixture.approve, reason: "conflicting replay" },
27107
+ config.fixtureId, config.idempotencyKey, { ...body, reason: "conflicting replay" },
27079
27108
  );
27080
27109
  expect([400, 409, 422]).toContain(conflicting.status);
27081
-
27082
- // Two distinct keys racing on one version may commit at most one state
27083
- // transition. A fixture that is already terminal may reject both.
27110
+ const stale = await approve(config.fixtureId, config.idempotencyKey + "-stale");
27111
+ expect([409, 422]).toContain(stale.status);
27112
+ const after = await request(config, path(config.fixtureId), { headers });
27113
+ expect(after.ok).toBe(true);
27114
+ expect(await object(after)).toMatchObject(firstBody);
27115
+
27116
+ // Race on a separate fresh draft; racing the already-approved row proves nothing.
27117
+ const raceDetail = await request(config, path(config.raceId), { headers });
27118
+ expect(raceDetail.ok).toBe(true);
27119
+ const raceBefore = await object(raceDetail);
27120
+ expect(raceBefore).toMatchObject({ id: config.raceId, state: "draft" });
27121
+ expect(Number.isSafeInteger(raceBefore["version"])).toBe(true);
27122
+ expect(Number(raceBefore["version"])).toBeGreaterThanOrEqual(1);
27123
+ const raceBody = { ...body, expectedVersion: Number(raceBefore["version"]) };
27084
27124
  const [raceA, raceB] = await Promise.all([
27085
- approve(config.idempotencyKey + "-race-a"),
27086
- approve(config.idempotencyKey + "-race-b"),
27125
+ approve(config.raceId, config.idempotencyKey + "-race-a", raceBody),
27126
+ approve(config.raceId, config.idempotencyKey + "-race-b", raceBody),
27087
27127
  ]);
27088
- expect([raceA.status, raceB.status].filter((status) => status >= 200 && status < 300).length)
27089
- .toBeLessThanOrEqual(1);
27090
- });
27091
-
27092
- test.skipIf(!tenantIsolationEnabled)("${name} rejects cross-tenant access", async () => {
27128
+ const statuses = [raceA.status, raceB.status];
27129
+ expect(statuses.filter(status => status === 200)).toHaveLength(1);
27130
+ expect(statuses.filter(status => status === 409 || status === 422)).toHaveLength(1);
27131
+ const winner = await object(raceA.status === 200 ? raceA : raceB);
27132
+ expect(winner).toMatchObject({ id: config.raceId, state: "approved" });
27133
+ expect(Number.isSafeInteger(winner["version"])).toBe(true);
27134
+ expect(Number(winner["version"])).toBeGreaterThan(Number(raceBefore["version"]));
27135
+ const raceAfter = await request(config, path(config.raceId), { headers });
27136
+ expect(raceAfter.ok).toBe(true);
27137
+ expect(await object(raceAfter)).toMatchObject(winner);
27138
+ }, { timeout: 120_000 });
27139
+
27140
+ test.skipIf(!enabled)("${name} rejects cross-tenant reads, writes and receipt disclosure", async () => {
27093
27141
  const config = requireConfig();
27094
- if (!otherAuthorization) throw new Error("Missing SUPACLOUD_FEATURE_E2E_OTHER_AUTHORIZATION");
27095
27142
  const headers = {
27096
- authorization: otherAuthorization,
27143
+ authorization: config.otherAuthorization,
27097
27144
  "content-type": "application/json",
27098
27145
  };
27099
- const list = await fetch(new URL("/${name}", config.baseUrl), { headers });
27146
+ const list = await request(config, "/${name}", { headers });
27100
27147
  expect(list.ok).toBe(true);
27101
- expect(containsFixture(await json(list))).toBe(false);
27102
-
27103
- const detail = await fetch(
27104
- new URL("/${name}/" + encodeURIComponent(fixtureId), config.baseUrl),
27105
- { headers },
27106
- );
27107
- expect([403, 404]).toContain(detail.status);
27108
-
27109
- const approval = await fetch(
27110
- new URL("/${name}/" + encodeURIComponent(fixtureId) + "/approve", config.baseUrl),
27111
- {
27112
- method: "POST",
27113
- headers: { ...headers, "idempotency-key": config.idempotencyKey + "-other-tenant" },
27114
- body: JSON.stringify(${className}Fixture.approve),
27115
- },
27116
- );
27148
+ const listed: unknown = await list.json();
27149
+ expect(Array.isArray(listed)).toBe(true);
27150
+ expect(listed).not.toContainEqual(expect.objectContaining({ id: config.fixtureId }));
27151
+ expect(listed).not.toContainEqual(expect.objectContaining({ id: config.raceId }));
27152
+ const path = "/${name}/" + encodeURIComponent(config.fixtureId);
27153
+ const operationPath = path + "/operations/" + encodeURIComponent(config.idempotencyKey);
27154
+ for (const target of [path, operationPath, operationPath + "/status"]) {
27155
+ const response = await request(config, target, { headers });
27156
+ expect([403, 404]).toContain(response.status);
27157
+ }
27158
+ // Reuse the successful key: authorization must run before a cached success is disclosed.
27159
+ const approval = await request(config, path + "/approve", {
27160
+ method: "POST", headers: { ...headers, "idempotency-key": config.idempotencyKey },
27161
+ body: JSON.stringify(${className}Fixture.approve),
27162
+ });
27117
27163
  expect([403, 404]).toContain(approval.status);
27118
- });
27164
+ }, { timeout: 120_000 });
27119
27165
  `,
27120
27166
  [`${name}.deployment.md`]: `# ${className} feature delivery checklist
27121
27167
 
@@ -27143,10 +27189,16 @@ Add request fields in the contract, not a second handwritten Writer interface.
27143
27189
  Typecheck application adapters after changing a field type; the derived Port
27144
27190
  must expose incompatible assumptions in business code.
27145
27191
 
27146
- For authenticated tenant-isolation acceptance, also provide
27147
- \`SUPACLOUD_FEATURE_E2E_OTHER_AUTHORIZATION\` for a principal from another tenant.
27148
- The generated E2E then verifies that the fixture is absent from list results and that
27149
- cross-tenant detail and approval are rejected.
27192
+ For release acceptance, set \`SUPACLOUD_FEATURE_E2E_REQUIRED=1\` and supply URL,
27193
+ AUTHORIZATION, OTHER_AUTHORIZATION, ID, RACE_ID and IDEMPOTENCY_KEY under the
27194
+ \`SUPACLOUD_FEATURE_E2E_\` prefix. Use two distinct fresh draft fixtures and a fresh
27195
+ key on every run. Missing or partial configuration fails; only an entirely
27196
+ unconfigured developer run skips. Use HTTPS, or loopback HTTP for local tests.
27197
+ The first approval must succeed, its receipt must match, replay must preserve the
27198
+ result, and exactly one of two concurrent writes on the second draft must succeed.
27199
+ Cross-tenant detail, receipt, job status and replay must be denied. This HTTP test
27200
+ does not prove audit/outbox counts, worker completion, crashes, browser interaction,
27201
+ revoked membership or deployment; verify those separately against durable sources.
27150
27202
 
27151
27203
  The named RPC adapter must invoke the continuation in the same database transaction
27152
27204
  used by the request-scoped Writer, or own the complete command instead; never execute
@@ -33086,7 +33138,7 @@ async function runProjectDeployment(http, args) {
33086
33138
  // package.json
33087
33139
  var package_default = {
33088
33140
  name: "@supacloud/cli",
33089
- version: "0.108.0",
33141
+ version: "0.108.2",
33090
33142
  description: "Project-scoped CLI for SupaCloud users",
33091
33143
  type: "module",
33092
33144
  main: "./dist/index.js",
@@ -33144,7 +33196,7 @@ var package_default = {
33144
33196
  typebox: "1.3.37"
33145
33197
  },
33146
33198
  overrides: {
33147
- "@supacloud/contracts": "0.14.0",
33199
+ "@supacloud/contracts": "0.15.0",
33148
33200
  "@supacloud/delivery": "0.21.0",
33149
33201
  "@graphql-tools/utils": "^12.0.4"
33150
33202
  },
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.108.0",
3
+ "version": "0.108.2",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -58,7 +58,7 @@
58
58
  "typebox": "1.3.37"
59
59
  },
60
60
  "overrides": {
61
- "@supacloud/contracts": "0.14.0",
61
+ "@supacloud/contracts": "0.15.0",
62
62
  "@supacloud/delivery": "0.21.0",
63
63
  "@graphql-tools/utils": "^12.0.4"
64
64
  },