@supacloud/cli 0.65.0 → 0.65.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.
Files changed (2) hide show
  1. package/dist/index.js +56 -21
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -229497,6 +229497,15 @@ function renderClient(graph, options) {
229497
229497
  const command = route.command === undefined ? undefined : commandByClassName.get(route.command);
229498
229498
  const procedureKind = route.method === "GET" || route.method === "HEAD" ? "query" : "mutation";
229499
229499
  const idempotencyMode = command?.idempotency ?? "none";
229500
+ const procedureMetadata = {
229501
+ key: `${controller.className}.${route.handler}`,
229502
+ method: route.method,
229503
+ path: fullPath,
229504
+ controller: controller.className,
229505
+ handler: route.handler,
229506
+ kind: procedureKind,
229507
+ idempotency: idempotencyMode
229508
+ };
229500
229509
  allProcedures.push({
229501
229510
  method: route.method,
229502
229511
  path: fullPath,
@@ -229508,7 +229517,7 @@ function renderClient(graph, options) {
229508
229517
  idempotency: idempotencyMode
229509
229518
  });
229510
229519
  routeMethods.push(`
229511
- ${route.handler}: makeRoute<${requestTypeName}, ${responseType === "never" ? "never" : responseTypeName}, ${JSON.stringify(procedureKind)}, ${JSON.stringify(idempotencyMode)}>(${JSON.stringify(route.method)}, ${JSON.stringify(fullPath)}, ${responseSchemaArgument}, ${responseKindArgument}, ${route.parse === "none"}, ${JSON.stringify(procedureKind)}, ${JSON.stringify(idempotencyMode)}),`);
229520
+ ${route.handler}: makeRoute<${requestTypeName}, ${responseType === "never" ? "never" : responseTypeName}, ${JSON.stringify(procedureKind)}, ${JSON.stringify(idempotencyMode)}>(${JSON.stringify(route.method)}, ${JSON.stringify(fullPath)}, ${responseSchemaArgument}, ${responseKindArgument}, ${route.parse === "none"}, ${JSON.stringify(procedureKind)}, ${JSON.stringify(idempotencyMode)}, ${JSON.stringify(procedureMetadata)}),`);
229512
229521
  }
229513
229522
  controllerEntries.push(`
229514
229523
  ${controllerKey}: {${routeMethods.join("")}
@@ -229542,6 +229551,19 @@ function renderClient(graph, options) {
229542
229551
  'export type ProcedureKind = "query" | "mutation";',
229543
229552
  'export type IdempotencyMode = "required" | "none";',
229544
229553
  "",
229554
+ "export interface ProcedureMetadata<",
229555
+ " Kind extends ProcedureKind = ProcedureKind,",
229556
+ " Idempotency extends IdempotencyMode = IdempotencyMode,",
229557
+ "> {",
229558
+ " key: string;",
229559
+ " method: string;",
229560
+ " path: string;",
229561
+ " controller: string;",
229562
+ " handler: string;",
229563
+ " kind: Kind;",
229564
+ " idempotency: Idempotency;",
229565
+ "}",
229566
+ "",
229545
229567
  "export interface ProcedureExecutionOptions {",
229546
229568
  " /** Reuse the same key when retrying an uncertain mutation. */",
229547
229569
  " idempotencyKey?: string;",
@@ -229567,14 +229589,24 @@ function renderClient(graph, options) {
229567
229589
  ' Idempotency extends IdempotencyMode = "none",',
229568
229590
  "> = (...args: ProcedureArgs<Options, Idempotency>) => Promise<ProcedureResult<Result>>;",
229569
229591
  "",
229592
+ "export type QueryableProcedure<",
229593
+ " Options extends ClientRequestOptions,",
229594
+ " Result,",
229595
+ " Idempotency extends IdempotencyMode,",
229596
+ " Kind extends ProcedureKind,",
229597
+ "> = ProcedureCall<Options, Result, Idempotency> & {",
229598
+ " readonly __supacloudProcedure: ProcedureMetadata<Kind, Idempotency>;",
229599
+ " readonly __supacloudInput?: Options;",
229600
+ "};",
229601
+ "",
229570
229602
  "export type ProcedureMember<",
229571
229603
  " Options extends ClientRequestOptions,",
229572
229604
  " Result,",
229573
229605
  " Kind extends ProcedureKind,",
229574
229606
  " Idempotency extends IdempotencyMode,",
229575
229607
  '> = Kind extends "query"',
229576
- " ? { query: ProcedureCall<Options, Result, Idempotency> }",
229577
- " : { mutate: ProcedureCall<Options, Result, Idempotency> };",
229608
+ ' ? { query: QueryableProcedure<Options, Result, Idempotency, "query"> }',
229609
+ ' : { mutate: QueryableProcedure<Options, Result, Idempotency, "mutation"> };',
229578
229610
  "",
229579
229611
  'export type ApiClientErrorCode = "API_HTTP_ERROR" | "API_RESPONSE_INVALID" | "API_RESPONSE_UNDECLARED";',
229580
229612
  "",
@@ -229594,7 +229626,7 @@ function renderClient(graph, options) {
229594
229626
  " readonly path: string;",
229595
229627
  " readonly status: number;",
229596
229628
  " readonly requestId: string | undefined;",
229597
- " /** Undeclared HTTP response for explicit inspection; excluded from JSON serialization. */",
229629
+ " /** HTTP response for inspection; successful response bodies may already be consumed. */",
229598
229630
  " readonly response: Response | undefined;",
229599
229631
  " constructor(message: string, details: ApiClientErrorDetails) {",
229600
229632
  " super(message);",
@@ -229941,25 +229973,27 @@ function renderClient(graph, options) {
229941
229973
  " const declaredSchema = responseSchemas ? selectResponseSchema(response.status, responseSchemas) : undefined;",
229942
229974
  " const failure = (code: ApiClientErrorCode, message: string) => new ApiClientError(message, {",
229943
229975
  ' code, method, path, status: response.status, requestId: response.headers.get("x-request-id"),',
229944
- ' ...(code === "API_HTTP_ERROR" ? { response } : {}),',
229976
+ " response,",
229945
229977
  " });",
229946
229978
  " if (!response.ok && declaredSchema === undefined) {",
229947
229979
  ' throw failure("API_HTTP_ERROR", `API request failed: ${method} ${path} -> ${response.status}`);',
229948
229980
  " }",
229981
+ " // Preserve the original HTTP error response if a declared error body fails validation.",
229982
+ " const bodyResponse = response.ok ? response : response.clone();",
229949
229983
  ' const contentType = response.headers?.get("content-type") ?? "";',
229950
229984
  " let value: unknown;",
229951
229985
  " if ([204, 205, 304].includes(response.status)) {",
229952
229986
  " value = undefined;",
229953
229987
  ' } else if (contentType.includes("application/json") || contentType.includes("+json")) {',
229954
- " const responseText = await response.text();",
229988
+ " const responseText = await bodyResponse.text();",
229955
229989
  " try { value = JSON.parse(responseText); }",
229956
229990
  ' catch { throw failure("API_RESPONSE_INVALID", "Response is not valid JSON"); }',
229957
229991
  ' } else if (responseKind === "binary" || contentType.includes("application/octet-stream")) {',
229958
- " value = await response.arrayBuffer();",
229992
+ " value = await bodyResponse.arrayBuffer();",
229959
229993
  ' } else if (responseKind === "stream") {',
229960
- " value = response.body;",
229994
+ " value = bodyResponse.body;",
229961
229995
  " } else {",
229962
- " value = await response.text();",
229996
+ " value = await bodyResponse.text();",
229963
229997
  " }",
229964
229998
  " if (!responseSchemas) return decode ? decode(value) : value;",
229965
229999
  " if (declaredSchema === undefined) {",
@@ -229986,9 +230020,10 @@ function renderClient(graph, options) {
229986
230020
  " ): ClientRequestOptions {",
229987
230021
  " const headers = { ...(options.headers as Record<string, string> | undefined) };",
229988
230022
  " if (execution?.idempotencyKey !== undefined) {",
229989
- " if (!/^[A-Za-z0-9._:-]{1,512}$/.test(execution.idempotencyKey)) {",
230023
+ ' if (typeof execution.idempotencyKey !== "string" || !/^[A-Za-z0-9._:-]{1,512}$/.test(execution.idempotencyKey)) {',
229990
230024
  ' throw new TypeError("idempotencyKey must contain only safe header characters and be at most 512 characters");',
229991
230025
  " }",
230026
+ ' for (const key of Object.keys(headers)) if (key.toLowerCase() === "idempotency-key") delete headers[key];',
229992
230027
  ' headers["idempotency-key"] = execution.idempotencyKey;',
229993
230028
  " }",
229994
230029
  ' if (idempotency === "required" && !hasHeader(headers, "idempotency-key")) {',
@@ -230002,17 +230037,17 @@ function renderClient(graph, options) {
230002
230037
  ' return Object.hasOwn(value, "idempotencyKey") || Object.hasOwn(value, "signal");',
230003
230038
  " }",
230004
230039
  "",
230005
- ` function makeProcedure<Options extends ClientRequestOptions, Result = never, Idempotency extends IdempotencyMode = "none">(method: string, path: string, responseSchemas?: Readonly<Record<string, ${responseSchemaType}>>, responseKind?: string, raw = false, idempotency: Idempotency = "none" as Idempotency): ProcedureCall<Options, Result, Idempotency> {`,
230040
+ ` function makeProcedure<Options extends ClientRequestOptions, Result = never, Idempotency extends IdempotencyMode = "none", Kind extends ProcedureKind = ProcedureKind>(metadata: ProcedureMetadata<Kind, Idempotency>, responseSchemas?: Readonly<Record<string, ${responseSchemaType}>>, responseKind?: string, raw = false): QueryableProcedure<Options, Result, Idempotency, Kind> {`,
230006
230041
  " const procedure = async (first?: Options | ProcedureExecutionOptions, second?: ProcedureExecutionOptions): Promise<unknown> => {",
230007
230042
  " const execution = second ?? (isProcedureExecution(first) ? first : undefined);",
230008
230043
  " const input = (execution === first ? undefined : first) ?? {};",
230009
- " const requestOptions = withProcedureExecution(input as ClientRequestOptions, execution, idempotency);",
230010
- " return request(method, path, requestOptions, undefined, responseSchemas, responseKind, raw, execution);",
230044
+ " const requestOptions = withProcedureExecution(input as ClientRequestOptions, execution, metadata.idempotency);",
230045
+ " return request(metadata.method, metadata.path, requestOptions, undefined, responseSchemas, responseKind, raw, execution);",
230011
230046
  " };",
230012
- " return procedure as ProcedureCall<Options, Result, Idempotency>;",
230047
+ " return Object.assign(procedure, { __supacloudProcedure: Object.freeze(metadata) }) as QueryableProcedure<Options, Result, Idempotency, Kind>;",
230013
230048
  " }",
230014
230049
  "",
230015
- ` function makeRoute<Options extends ClientRequestOptions, Result = never, Kind extends ProcedureKind = never, Idempotency extends IdempotencyMode = "none">(method: string, path: string, responseSchemas?: Readonly<Record<string, ${responseSchemaType}>>, responseKind?: string, raw = false, kind?: Kind, idempotency: Idempotency = "none" as Idempotency): RouteMethod<Options, Result> & ProcedureMember<Options, Result, Kind, Idempotency> {`,
230050
+ ` function makeRoute<Options extends ClientRequestOptions, Result = never, Kind extends ProcedureKind = never, Idempotency extends IdempotencyMode = "none">(method: string, path: string, responseSchemas?: Readonly<Record<string, ${responseSchemaType}>>, responseKind?: string, raw = false, kind?: Kind, idempotency: Idempotency = "none" as Idempotency, metadata?: ProcedureMetadata<Kind, Idempotency>): RouteMethod<Options, Result> & ProcedureMember<Options, Result, Kind, Idempotency> {`,
230016
230051
  " function route<T>(options: Options, decode: ResponseDecoder<T>): Promise<T>;",
230017
230052
  " function route(options: Options): Promise<Result>;",
230018
230053
  " function route(options?: Options): Promise<unknown>;",
@@ -230020,8 +230055,8 @@ function renderClient(graph, options) {
230020
230055
  " const requestOptions = options ?? {};",
230021
230056
  " return request(method, path, requestOptions, decode, responseSchemas, responseKind, raw);",
230022
230057
  " }",
230023
- ' if (kind === "query") Object.assign(route, { query: makeProcedure<Options, Result, Idempotency>(method, path, responseSchemas, responseKind, raw, idempotency) });',
230024
- ' if (kind === "mutation") Object.assign(route, { mutate: makeProcedure<Options, Result, Idempotency>(method, path, responseSchemas, responseKind, raw, idempotency) });',
230058
+ ' if (kind === "query" && metadata) Object.assign(route, { query: makeProcedure<Options, Result, Idempotency, "query">(metadata as ProcedureMetadata<"query", Idempotency>, responseSchemas, responseKind, raw) });',
230059
+ ' if (kind === "mutation" && metadata) Object.assign(route, { mutate: makeProcedure<Options, Result, Idempotency, "mutation">(metadata as ProcedureMetadata<"mutation", Idempotency>, responseSchemas, responseKind, raw) });',
230025
230060
  " return route as RouteMethod<Options, Result> & ProcedureMember<Options, Result, Kind, Idempotency>;",
230026
230061
  " }",
230027
230062
  "",
@@ -247230,7 +247265,7 @@ var starter_metadata_default = {
247230
247265
  generatedBy: "supacloud/starter-metadata-v1",
247231
247266
  packages: {
247232
247267
  compiler: {
247233
- version: "0.33.0"
247268
+ version: "0.35.0"
247234
247269
  },
247235
247270
  app: {
247236
247271
  version: "0.22.0",
@@ -247257,7 +247292,7 @@ var starter_metadata_default = {
247257
247292
  }
247258
247293
  },
247259
247294
  sdk: {
247260
- version: "0.37.0",
247295
+ version: "0.39.0",
247261
247296
  peerDependencies: {
247262
247297
  "@supabase/supabase-js": "^2.115.0"
247263
247298
  }
@@ -254961,7 +254996,7 @@ function registerRemoteDevTools(server2, options = {}) {
254961
254996
  // package.json
254962
254997
  var package_default = {
254963
254998
  name: "@supacloud/cli",
254964
- version: "0.65.0",
254999
+ version: "0.65.2",
254965
255000
  description: "Project-scoped CLI for SupaCloud users",
254966
255001
  type: "module",
254967
255002
  main: "./dist/index.js",
@@ -254996,7 +255031,7 @@ var package_default = {
254996
255031
  },
254997
255032
  dependencies: {
254998
255033
  "@sinclair/typebox": "^0.34.52",
254999
- "@supacloud/compiler": "^0.33.0",
255034
+ "@supacloud/compiler": "^0.35.0",
255000
255035
  "@supacloud/delivery": "0.7.0",
255001
255036
  "@supacloud/db": "^0.2.0",
255002
255037
  fflate: "^0.8.3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@supacloud/cli",
3
- "version": "0.65.0",
3
+ "version": "0.65.2",
4
4
  "description": "Project-scoped CLI for SupaCloud users",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@sinclair/typebox": "^0.34.52",
38
- "@supacloud/compiler": "^0.33.0",
38
+ "@supacloud/compiler": "^0.35.0",
39
39
  "@supacloud/delivery": "0.7.0",
40
40
  "@supacloud/db": "^0.2.0",
41
41
  "fflate": "^0.8.3",