@sdk-it/typescript 0.42.1 → 0.44.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
@@ -4,7 +4,7 @@ import { readdir } from "node:fs/promises";
4
4
  import { join as join2 } from "node:path";
5
5
  import { npmRunPathEnv } from "npm-run-path";
6
6
  import { camelcase as camelcase6, spinalcase as spinalcase4 } from "stringcase";
7
- import { methods, pascalcase as pascalcase5, toLitObject as toLitObject2 } from "@sdk-it/core";
7
+ import { pascalcase as pascalcase5, toLitObject as toLitObject2 } from "@sdk-it/core";
8
8
  import {
9
9
  createWriterProxy,
10
10
  getFolderExports,
@@ -14,7 +14,7 @@ import {
14
14
  cleanFiles,
15
15
  readWriteMetadata,
16
16
  sanitizeTag as sanitizeTag4,
17
- securityToOptions as securityToOptions2,
17
+ security,
18
18
  toIR
19
19
  } from "@sdk-it/spec";
20
20
 
@@ -117,7 +117,7 @@ function createTool2(entry, operation) {
117
117
  }
118
118
 
119
119
  // packages/typescript/src/lib/agent/utils.txt
120
- var utils_default = "function coerceContext(context?: any) {\n if (!context) {\n throw new Error('Context is required');\n }\n return context as {\n client: any\n };\n}\n/**\n * Takes a Zod object schema and makes all optional properties nullable as well.\n * This is useful for APIs where optional fields can be explicitly set to null.\n *\n * @param schema - The Zod object schema to transform\n * @returns A new Zod schema with optional properties made nullable\n */\nfunction makeOptionalPropsNullable<T extends z.ZodRawShape>(\n schema: z.ZodObject<T>,\n) {\n const shape = schema.shape;\n const newShape = {} as Record<string, z.ZodTypeAny>;\n\n for (const [key, value] of Object.entries(shape)) {\n if (value instanceof z.ZodOptional) {\n // Make optional properties also nullable\n newShape[key] = value._def.innerType.nullable().optional();\n } else {\n // Keep non-optional properties as they are\n newShape[key] = value;\n }\n }\n\n return z.object(newShape);\n}";
120
+ var utils_default = "function coerceContext(context?: any) {\n if (!context) {\n throw new Error('Context is required');\n }\n return context as {\n client: any\n };\n}\n/**\n * Takes a Zod object schema and makes all optional properties nullable as well.\n * This is useful for APIs where optional fields can be explicitly set to null.\n *\n * @param schema - The Zod object schema to transform\n * @returns A new Zod schema with optional properties made nullable\n */\nfunction makeOptionalPropsNullable<T extends z.ZodRawShape>(\n schema: z.ZodObject<T>,\n) {\n const shape = schema.shape;\n const newShape = {} as Record<string, z.ZodType>;\n\n for (const [key, value] of Object.entries(shape)) {\n if (value instanceof z.ZodOptional) {\n // Make optional properties also nullable\n newShape[key] = value.unwrap().nullable().optional();\n } else {\n // Keep non-optional properties as they are\n newShape[key] = value;\n }\n }\n\n return z.object(newShape);\n}";
121
121
 
122
122
  // packages/typescript/src/lib/client.ts
123
123
  import { toLitObject } from "@sdk-it/core";
@@ -182,7 +182,7 @@ var ZodEmitter = class {
182
182
  return `${base}${this.#suffixes(defaultValue, required, nullable)}`;
183
183
  }
184
184
  case "boolean":
185
- return `${schema["x-zod-type"] === "coerce-boolean" ? "z.coerce.boolean()" : "z.boolean()"}${this.#suffixes(schema.default, required, nullable)}`;
185
+ return `${schema["x-zod-type"] === "coerce-boolean" ? "z.union([z.boolean(), z.stringbool()])" : "z.boolean()"}${this.#suffixes(schema.default, required, nullable)}`;
186
186
  case "object":
187
187
  return `${this.#object(schema)}${this.#suffixes(JSON.stringify(schema.default), required, nullable)}`;
188
188
  // required always
@@ -238,16 +238,16 @@ var ZodEmitter = class {
238
238
  if (oneOfSchemas.length === 1) {
239
239
  return `${oneOfSchemas[0]}${appendOptional(required)}`;
240
240
  }
241
- return `z.union([${oneOfSchemas.join(", ")}])${appendOptional(required)}`;
241
+ return `z.xor([${oneOfSchemas.join(", ")}])${appendOptional(required)}`;
242
242
  }
243
243
  enum(type, values) {
244
244
  if (values.length === 1) {
245
245
  return `z.literal(${values.join(", ")})`;
246
246
  }
247
- if (type === "integer") {
248
- return `z.union([${values.map((val) => `z.literal(${val})`).join(", ")}])`;
247
+ if (values.every((value) => String(value).startsWith('"'))) {
248
+ return `z.enum([${values.join(", ")}])`;
249
249
  }
250
- return `z.enum([${values.join(", ")}])`;
250
+ return `z.literal([${values.join(", ")}])`;
251
251
  }
252
252
  /**
253
253
  * Handle a `string` schema with possible format keywords (JSON Schema).
@@ -258,6 +258,8 @@ var ZodEmitter = class {
258
258
  base = "z.custom<Blob>()";
259
259
  return base;
260
260
  }
261
+ const coerced = schema["x-zod-type"] === "coerce-string";
262
+ const withFormat = (format) => coerced ? `${base}.pipe(${format})` : format;
261
263
  switch (schema.format) {
262
264
  case "date-time":
263
265
  case "datetime":
@@ -266,30 +268,38 @@ var ZodEmitter = class {
266
268
  } else if (schema["x-zod-type"] === "date") {
267
269
  base = "z.date()";
268
270
  } else {
269
- base += ".datetime()";
271
+ base = withFormat("z.iso.datetime({ offset: true })");
270
272
  }
271
273
  break;
272
274
  case "date":
273
- base += ".date()";
275
+ base = withFormat("z.iso.date()");
274
276
  break;
275
277
  case "time":
276
- base += " /* optionally add .regex(...) for HH:MM:SS format */";
278
+ base = withFormat(
279
+ "z.string().regex(/^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d(\\.\\d+)?)?(Z|[+-]([01]\\d|2[0-3]):[0-5]\\d)?$/)"
280
+ );
277
281
  break;
278
282
  case "email":
279
- base += ".email()";
283
+ base = withFormat("z.email()");
280
284
  break;
281
285
  case "uuid":
282
- base += ".uuid()";
286
+ base = withFormat("z.guid()");
283
287
  break;
284
288
  case "url":
285
289
  case "uri":
286
- base += ".url()";
290
+ base = withFormat("z.url()");
287
291
  break;
288
292
  case "ipv4":
289
- base += '.ip({version: "v4"})';
293
+ base = withFormat("z.ipv4()");
290
294
  break;
291
295
  case "ipv6":
292
- base += '.ip({version: "v6"})';
296
+ base = withFormat("z.ipv6()");
297
+ break;
298
+ case "cidrv4":
299
+ base = withFormat("z.cidrv4()");
300
+ break;
301
+ case "cidrv6":
302
+ base = withFormat("z.cidrv6()");
293
303
  break;
294
304
  case "phone":
295
305
  base += " /* or add .regex(...) for phone formats */";
@@ -298,9 +308,6 @@ var ZodEmitter = class {
298
308
  case "binary":
299
309
  base = "z.custom<Blob>()";
300
310
  break;
301
- case "int64":
302
- base += " /* or z.bigint() if your app can handle it */";
303
- break;
304
311
  default:
305
312
  break;
306
313
  }
@@ -312,17 +319,8 @@ var ZodEmitter = class {
312
319
  * rather than a boolean toggling `minimum`/`maximum`.
313
320
  */
314
321
  #number(schema) {
315
- let defaultValue = schema.default;
316
- let base;
317
- if (schema.format === "int64") {
318
- base = schema["x-zod-type"] === "coerce-bigint" ? "z.coerce.bigint()" : "z.bigint()";
319
- if (schema.default !== void 0) {
320
- defaultValue = `BigInt(${schema.default})`;
321
- }
322
- } else {
323
- base = schema["x-zod-type"] === "coerce-number" ? "z.coerce.number()" : "z.number()";
324
- }
325
- if (schema.type === "integer" && schema.format !== "int64") {
322
+ let base = schema["x-zod-type"] === "coerce-number" ? "z.coerce.number()" : "z.number()";
323
+ if (schema.type === "integer") {
326
324
  base += ".int()";
327
325
  }
328
326
  if (typeof schema.exclusiveMinimum === "number") {
@@ -332,15 +330,15 @@ var ZodEmitter = class {
332
330
  base += `.lt(${schema.exclusiveMaximum})`;
333
331
  }
334
332
  if (typeof schema.minimum === "number") {
335
- base += schema.format === "int64" ? `.min(BigInt(${schema.minimum}))` : `.min(${schema.minimum})`;
333
+ base += `.min(${schema.minimum})`;
336
334
  }
337
335
  if (typeof schema.maximum === "number") {
338
- base += schema.format === "int64" ? `.max(BigInt(${schema.maximum}))` : `.max(${schema.maximum})`;
336
+ base += `.max(${schema.maximum})`;
339
337
  }
340
338
  if (typeof schema.multipleOf === "number") {
341
339
  base += `.refine((val) => Number.isInteger(val / ${schema.multipleOf}), "Must be a multiple of ${schema.multipleOf}")`;
342
340
  }
343
- return { base, defaultValue };
341
+ return { base, defaultValue: schema.default };
344
342
  }
345
343
  handle(schema, required) {
346
344
  if (isRef(schema)) {
@@ -402,7 +400,8 @@ function toZod(schema, required) {
402
400
 
403
401
  // packages/typescript/src/lib/client.ts
404
402
  var client_default = (spec) => {
405
- const baseUrlSchema = `z.union([z.string(),z.function().returns(z.union([z.string(), z.promise(z.string())])),])${spec.servers.length ? ".default(servers[0])" : ""}`;
403
+ const callableString = `z.custom<() => string | Promise<string>>((value) => typeof value === 'function')`;
404
+ const baseUrlSchema = `z.union([z.string(),${callableString},])${spec.servers.length ? ".default(servers[0])" : ""}`;
406
405
  const defaultHeaders = `{${spec.options.filter((value) => value.in === "header").map(
407
406
  (value) => `'${value.name}': options['${value["x-optionName"] ?? value.name}']`
408
407
  ).join(",\n")}}`;
@@ -419,13 +418,15 @@ var client_default = (spec) => {
419
418
  ...globalOptions,
420
419
  ...globalOptions["'token'"] ? {
421
420
  "'token'": {
422
- schema: `z.union([z.string(),z.function().returns(z.union([z.string(), z.promise(z.string())])),]).optional()
423
- .transform(async (token) => {
421
+ schema: `z.union([z.string(),${callableString},]).optional()
422
+ .transform(async (token, ctx) => {
424
423
  if (!token) return undefined;
425
- if (typeof token === 'function') {
426
- token = await Promise.resolve(token());
424
+ const value = typeof token === 'function' ? await token() : token;
425
+ if (typeof value !== 'string') {
426
+ ctx.addIssue({ code: 'custom', message: 'token must resolve to a string' });
427
+ return z.NEVER;
427
428
  }
428
- return \`Bearer \${token}\`;
429
+ return \`Bearer \${value}\`;
429
430
  }).describe('Bearer token for authentication. Can be a string or a function that returns a string.')`
430
431
  }
431
432
  } : {},
@@ -433,15 +434,17 @@ var client_default = (spec) => {
433
434
  schema: `fetchType.describe('Custom fetch implementation. Defaults to globalThis.fetch.')`
434
435
  },
435
436
  baseUrl: {
436
- schema: `${baseUrlSchema}.transform(async (baseUrl) => {
437
- if (typeof baseUrl === 'function') {
438
- return Promise.resolve(baseUrl());
437
+ schema: `${baseUrlSchema}.transform(async (baseUrl, ctx) => {
438
+ const value = typeof baseUrl === 'function' ? await baseUrl() : baseUrl;
439
+ if (typeof value !== 'string') {
440
+ ctx.addIssue({ code: 'custom', message: 'baseUrl must resolve to a string' });
441
+ return z.NEVER;
439
442
  }
440
- return baseUrl;
443
+ return value;
441
444
  }).describe('Base URL of the API server. Can be a string or a function that returns a string.')`
442
445
  },
443
446
  headers: {
444
- schema: `z.record(z.string()).optional().describe('Default headers to include in all requests.')`
447
+ schema: `z.record(z.string(), z.string()).optional().describe('Default headers to include in all requests.')`
445
448
  },
446
449
  skipValidation: {
447
450
  schema: `z.boolean().optional().describe('Skip request input validation. Client options and TypeScript types still enforce correct usage.')`
@@ -478,7 +481,9 @@ export class ${spec.name} {
478
481
  input: z.input<(typeof schemas)[E]['schema']>,
479
482
  options?: { signal?: AbortSignal; headers?: HeadersInit },
480
483
  ) {
481
- return request(this, endpoint, input, options).then(function unwrap(it) {
484
+ return request(this, endpoint, input, options).then(function unwrap(
485
+ it: unknown,
486
+ ) {
482
487
  if (it instanceof APIResponse) {
483
488
  return it.data as InferData<E>;
484
489
  }
@@ -614,7 +619,7 @@ export async function prepare<const E extends keyof typeof schemas>(
614
619
  };
615
620
 
616
621
  // packages/typescript/src/lib/emitters/interface.ts
617
- import { followRef as followRef2, isRef as isRef2, parseRef as parseRef2, pascalcase as pascalcase2 } from "@sdk-it/core";
622
+ import { followRef as followRef2, isRef as isRef2, parseRef as parseRef2, pascalcase as pascalcase2, resolveRef } from "@sdk-it/core";
618
623
  import { isPrimitiveSchema as isPrimitiveSchema2, sanitizeTag as sanitizeTag2 } from "@sdk-it/spec";
619
624
  var TypeScriptEmitter = class {
620
625
  #spec;
@@ -692,7 +697,23 @@ var TypeScriptEmitter = class {
692
697
  return allOfTypes.length > 1 ? `${allOfTypes.join(" & ")}` : allOfTypes[0];
693
698
  }
694
699
  oneOf(schemas, required) {
695
- const oneOfTypes = schemas.map((sub) => this.handle(sub, true));
700
+ const isBareString = (s) => {
701
+ const r = resolveRef(this.#spec, s);
702
+ return r.type === "string" && !r.enum && !r.const && !r.format;
703
+ };
704
+ const isStringLiteral = (s) => {
705
+ const r = resolveRef(this.#spec, s);
706
+ return Array.isArray(r.enum) && r.enum.every((v) => typeof v === "string") || typeof r.const === "string";
707
+ };
708
+ const hasStringLiteral = schemas.some(isStringLiteral);
709
+ const seen = /* @__PURE__ */ new Set();
710
+ const oneOfTypes = [];
711
+ for (const sub of schemas) {
712
+ const part = hasStringLiteral && isBareString(sub) ? "(string & {})" : this.handle(sub, true);
713
+ if (seen.has(part)) continue;
714
+ seen.add(part);
715
+ oneOfTypes.push(part);
716
+ }
696
717
  return appendOptional2(
697
718
  oneOfTypes.length > 1 ? `${oneOfTypes.join(" | ")}` : oneOfTypes[0],
698
719
  required
@@ -723,9 +744,6 @@ var TypeScriptEmitter = class {
723
744
  case "byte":
724
745
  type = "Blob";
725
746
  break;
726
- case "int64":
727
- type = "bigint";
728
- break;
729
747
  default:
730
748
  type = "string";
731
749
  }
@@ -734,9 +752,8 @@ var TypeScriptEmitter = class {
734
752
  /**
735
753
  * Handle number/integer types with formats
736
754
  */
737
- number(schema, required) {
738
- const type = schema.format === "int64" ? "bigint" : "number";
739
- return appendOptional2(type, required);
755
+ number(_schema, required) {
756
+ return appendOptional2("number", required);
740
757
  }
741
758
  handle(schema, required) {
742
759
  if (isRef2(schema)) {
@@ -784,7 +801,7 @@ function appendOptional2(type, isRequired) {
784
801
  import { merge, template } from "lodash-es";
785
802
  import { join } from "node:path";
786
803
  import { camelcase as camelcase4, spinalcase as spinalcase2 } from "stringcase";
787
- import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef, sortArray } from "@sdk-it/core";
804
+ import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef as resolveRef2, sortArray } from "@sdk-it/core";
788
805
  import {
789
806
  forEachOperation as forEachOperation3
790
807
  } from "@sdk-it/spec";
@@ -804,6 +821,69 @@ import {
804
821
  // packages/typescript/src/lib/import-utilities.ts
805
822
  import { removeDuplicates } from "@sdk-it/core";
806
823
 
824
+ // packages/typescript/src/lib/pagination-emit.ts
825
+ function describe(p) {
826
+ switch (p.type) {
827
+ case "offset":
828
+ return {
829
+ className: "OffsetPagination",
830
+ items: p.items,
831
+ hasMore: p.hasMore,
832
+ statusCode: p.statusCode,
833
+ sameInputNames: p.limitParamName === "limit" && p.offsetParamName === "offset",
834
+ initialOverride: `limit: input.${p.limitParamName}, offset: input.${p.offsetParamName}`,
835
+ nextPageMapping: `${p.offsetParamName}: nextPageParams.offset, ${p.limitParamName}: nextPageParams.limit`
836
+ };
837
+ case "cursor":
838
+ return {
839
+ className: "CursorPagination",
840
+ items: p.items,
841
+ hasMore: p.hasMore,
842
+ statusCode: p.statusCode,
843
+ sameInputNames: p.cursorParamName === "cursor",
844
+ initialOverride: `cursor: input.${p.cursorParamName}`,
845
+ nextPageMapping: `${p.cursorParamName}: nextPageParams.cursor`
846
+ };
847
+ case "page":
848
+ return {
849
+ className: "Pagination",
850
+ items: p.items,
851
+ hasMore: p.hasMore,
852
+ statusCode: p.statusCode,
853
+ sameInputNames: p.pageNumberParamName === "page" && p.pageSizeParamName === "pageSize",
854
+ initialOverride: `page: input.${p.pageNumberParamName}, pageSize: input.${p.pageSizeParamName}`,
855
+ nextPageMapping: `${p.pageNumberParamName}: nextPageParams.page, ${p.pageSizeParamName}: nextPageParams.pageSize`
856
+ };
857
+ }
858
+ throw new Error(
859
+ `Unknown pagination type: ${p.type}`
860
+ );
861
+ }
862
+ function paginationOperation(pagination) {
863
+ const shape = describe(pagination);
864
+ const initialParams = shape.sameInputNames ? "input" : `{...input, ${shape.initialOverride}}`;
865
+ const nextPageParams = shape.sameInputNames ? "...nextPageParams" : shape.nextPageMapping;
866
+ return `{
867
+ const pagination = new ${shape.className}(${initialParams}, async (nextPageParams, requestOptions) => {
868
+ const dispatcher = new Dispatcher(options.interceptors, options.fetch);
869
+ const result = await dispatcher.send(
870
+ this.toRequest({...input, ${nextPageParams}}),
871
+ this.output,
872
+ requestOptions?.signal ?? options.signal,
873
+ );
874
+ if (result.status !== ${shape.statusCode}) { throw result; }
875
+ return {
876
+ data: result.data.${shape.items},
877
+ meta: {
878
+ hasMore: Boolean(result.data.${shape.hasMore}),
879
+ },
880
+ };
881
+ }, { signal: options.signal });
882
+ await pagination.getNextPage();
883
+ return pagination
884
+ }}`;
885
+ }
886
+
807
887
  // packages/typescript/src/lib/status-map.ts
808
888
  var status_map_default = {
809
889
  "200": "Ok",
@@ -868,7 +948,7 @@ function toEndpoint(groupName, spec, specOperation, operation) {
868
948
  signal?: AbortSignal;
869
949
  interceptors: Interceptor[];
870
950
  fetch: z.infer<typeof fetchType>;
871
- })${specOperation["x-pagination"] ? paginationOperation(specOperation) : normalOperation()}`
951
+ })${specOperation["x-pagination"] ? paginationOperation(specOperation["x-pagination"]) : normalOperation()}`
872
952
  );
873
953
  }
874
954
  return { schemas };
@@ -880,92 +960,11 @@ function normalOperation() {
880
960
  },
881
961
  }`;
882
962
  }
883
- function paginationOperation(operation) {
884
- const pagination = operation["x-pagination"];
885
- const data = `result.data`;
886
- const returnValue = `pagination`;
887
- if (pagination.type === "offset") {
888
- const sameInputNames = pagination.limitParamName === "limit" && pagination.offsetParamName === "offset";
889
- const initialParams = sameInputNames ? "input" : `{...input, limit: input.${pagination.limitParamName}, offset: input.${pagination.offsetParamName}}`;
890
- const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.offsetParamName}: nextPageParams.offset, ${pagination.limitParamName}: nextPageParams.limit`;
891
- const logic = `const pagination = new OffsetPagination(${initialParams}, async (nextPageParams, requestOptions) => {
892
- const dispatcher = new Dispatcher(options.interceptors, options.fetch);
893
- const result = await dispatcher.send(
894
- this.toRequest({...input, ${nextPageParams}}),
895
- this.output,
896
- requestOptions?.signal ?? options.signal,
897
- );
898
- return {
899
- data: ${data}.${pagination.items},
900
- meta: {
901
- hasMore: Boolean(${data}.${pagination.hasMore}),
902
- },
903
- };
904
- }, { signal: options.signal });
905
- await pagination.getNextPage();
906
- return ${returnValue}
907
- `;
908
- return `{${logic}}}`;
909
- }
910
- if (pagination.type === "cursor") {
911
- const sameInputNames = pagination.cursorParamName === "cursor";
912
- const initialParams = sameInputNames ? "input" : `{...input, cursor: input.${pagination.cursorParamName}}`;
913
- const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.cursorParamName}: nextPageParams.cursor`;
914
- const logic = `
915
- const pagination = new CursorPagination(${initialParams}, async (nextPageParams, requestOptions) => {
916
- const dispatcher = new Dispatcher(options.interceptors, options.fetch);
917
- const result = await dispatcher.send(
918
- this.toRequest({...input, ${nextPageParams}}),
919
- this.output,
920
- requestOptions?.signal ?? options.signal,
921
- );
922
- return {
923
- data: ${data}.${pagination.items},
924
- meta: {
925
- hasMore: Boolean(${data}.${pagination.hasMore}),
926
- },
927
- };
928
- }, { signal: options.signal });
929
- await pagination.getNextPage();
930
- return ${returnValue}
931
- `;
932
- return `{${logic}}}`;
933
- }
934
- if (pagination.type === "page") {
935
- const sameInputNames = pagination.pageNumberParamName === "page" && pagination.pageSizeParamName === "pageSize";
936
- const initialParams = sameInputNames ? "input" : `{...input, page: input.${pagination.pageNumberParamName}, pageSize: input.${pagination.pageSizeParamName}}`;
937
- const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.pageNumberParamName}: nextPageParams.page, ${pagination.pageSizeParamName}: nextPageParams.pageSize`;
938
- const logic = `
939
- const pagination = new Pagination(${initialParams}, async (nextPageParams, requestOptions) => {
940
- const dispatcher = new Dispatcher(options.interceptors, options.fetch);
941
- const result = await dispatcher.send(
942
- this.toRequest({...input, ${nextPageParams}}),
943
- this.output,
944
- requestOptions?.signal ?? options.signal,
945
- );
946
- return {
947
- data: ${data}.${pagination.items},
948
- meta: {
949
- hasMore: Boolean(${data}.${pagination.hasMore}),
950
- },
951
- };
952
- }, { signal: options.signal });
953
- await pagination.getNextPage();
954
- return ${returnValue}
955
- `;
956
- return `{${logic}}}`;
957
- }
958
- return normalOperation();
959
- }
960
963
  function toHttpOutput(spec, operationName, status, response, withGenerics = true) {
961
964
  const typeScriptDeserialzer = new TypeScriptEmitter(spec);
962
965
  const interfaceName = pascalcase3(sanitizeTag3(response["x-response-name"]));
963
966
  if (!isEmpty(response.content)) {
964
- const contentTypeResult = fromContentType(
965
- spec,
966
- typeScriptDeserialzer,
967
- response
968
- );
967
+ const contentTypeResult = fromContentType(typeScriptDeserialzer, response);
969
968
  if (!contentTypeResult) {
970
969
  throw new Error(
971
970
  `No recognizable content type for response ${status} in operation ${operationName}`
@@ -993,7 +992,7 @@ function toHttpOutput(spec, operationName, status, response, withGenerics = true
993
992
  }
994
993
  return [];
995
994
  }
996
- function fromContentType(spec, typeScriptDeserialzer, response) {
995
+ function fromContentType(typeScriptDeserialzer, response) {
997
996
  if ((response.headers ?? {})["Transfer-Encoding"]) {
998
997
  return streamedOutput();
999
998
  }
@@ -1011,9 +1010,10 @@ function fromContentType(spec, typeScriptDeserialzer, response) {
1011
1010
  };
1012
1011
  }
1013
1012
  if (parseJsonContentType(type)) {
1013
+ const schema = response.content[type].schema;
1014
1014
  return {
1015
1015
  parser: "buffered",
1016
- responseSchema: response.content[type].schema ? typeScriptDeserialzer.handle(response.content[type].schema, true) : "void"
1016
+ responseSchema: schema ? typeScriptDeserialzer.handle(schema, true) : "void"
1017
1017
  };
1018
1018
  }
1019
1019
  if (isSseContentType(type)) {
@@ -1077,7 +1077,7 @@ var endpoints_default = "type DispatchReturn<E extends keyof typeof schemas> = A
1077
1077
 
1078
1078
  // packages/typescript/src/lib/generator.ts
1079
1079
  function coearceRequestInput(spec, operation, type) {
1080
- let objectSchema = resolveRef(
1080
+ let objectSchema = resolveRef2(
1081
1081
  spec,
1082
1082
  operation.requestBody.content[type].schema
1083
1083
  );
@@ -1326,25 +1326,25 @@ function operationSchema(ir, operation, type) {
1326
1326
  }
1327
1327
 
1328
1328
  // packages/typescript/src/lib/http/dispatcher.txt
1329
- var dispatcher_default = "export type Unionize<T> = T extends [infer Single extends OutputType]\n ? InstanceType<Single>\n : T extends readonly [...infer Tuple extends OutputType[]]\n ? { [I in keyof Tuple]: InstanceType<Tuple[I]> }[number]\n : never;\n\nexport type InstanceType<T> =\n T extends Type<infer U>\n ? U\n : T extends { type: Type<infer U> }\n ? U\n : T extends Array<unknown>\n ? Unionize<T>\n : never;\n\ntype ResponseData<T extends OutputType[]> =\n Extract<InstanceType<T>, SuccessfulResponse> extends SuccessfulResponse<\n infer P\n >\n ? P\n : unknown;\n\ntype ResponseMapper<T extends OutputType[], R> = (data: ResponseData<T>) => R;\n\nexport interface Type<T> {\n new (...args: any[]): T;\n}\nexport type Parser = (\n response: Response,\n) => Promise<unknown> | ReadableStream<any> | SSEListener;\nexport type OutputType =\n | Type<APIResponse>\n | { parser: Parser; type: Type<APIResponse> };\n\nexport const fetchType = z\n .function()\n .args(z.custom<Request>())\n .returns(z.promise(z.custom<Response>()))\n .optional();\n\nexport async function parse<T extends OutputType[]>(\n outputs: T,\n response: Response,\n): Promise<Extract<Unionize<T>, SuccessfulResponse<unknown>>>;\nexport async function parse<T extends OutputType[], R>(\n outputs: T,\n response: Response,\n mapper: ResponseMapper<T, R>,\n): Promise<RebindSuccessPayload<Extract<Unionize<T>, SuccessfulResponse<unknown>>, R>>;\nexport async function parse<T extends OutputType[], R = ResponseData<T>>(\n outputs: T,\n response: Response,\n mapper?: ResponseMapper<T, R>,\n) {\n let output: typeof APIResponse | null = null;\n let parser: Parser = buffered;\n for (const outputType of outputs) {\n if ('parser' in outputType) {\n parser = outputType.parser;\n if (isTypeOf(outputType.type, APIResponse)) {\n if (response.status === outputType.type.status) {\n output = outputType.type;\n break;\n }\n }\n } else if (isTypeOf(outputType, APIResponse)) {\n if (response.status === outputType.status) {\n output = outputType;\n break;\n }\n }\n }\n\n if (response.ok) {\n const data = (await parser(response)) as ResponseData<T>;\n const mapped = mapper ? mapper(data) : data;\n const apiresponse = (output || APIResponse).create(\n response.status,\n response.headers,\n mapped,\n );\n\n return apiresponse as any;\n }\n\n throw (output || APIError).create(\n response.status,\n response.headers,\n await parser(response),\n );\n}\n\nexport function isTypeOf<T extends Type<APIResponse>>(\n instance: any,\n baseType: T,\n): instance is T {\n if (instance === baseType) {\n return true;\n }\n const prototype = Object.getPrototypeOf(instance);\n if (prototype === null) {\n return false;\n }\n return isTypeOf(prototype, baseType);\n}\n\nexport class Dispatcher {\n #interceptors: Interceptor[] = [];\n #fetch: z.infer<typeof fetchType>;\n constructor(interceptors: Interceptor[], fetch?: z.infer<typeof fetchType>) {\n this.#interceptors = interceptors;\n this.#fetch = fetch;\n }\n\n async send<T extends OutputType[]>(\n config: RequestConfig,\n outputs: T,\n signal?: AbortSignal,\n ): Promise<Extract<Unionize<T>, SuccessfulResponse<unknown>>>;\n async send<T extends OutputType[], R>(\n config: RequestConfig,\n outputs: T,\n signal?: AbortSignal,\n mapper?: ResponseMapper<T, R>,\n ): Promise<RebindSuccessPayload<Extract<Unionize<T>, SuccessfulResponse<unknown>>, R>>;\n async send<T extends OutputType[], R = ResponseData<T>>(\n config: RequestConfig,\n outputs: T,\n signal?: AbortSignal,\n mapper?: ResponseMapper<T, R>,\n ) {\n for (const interceptor of this.#interceptors) {\n if (interceptor.before) {\n config = await interceptor.before(config);\n }\n }\n\n const init = signal === undefined ? config.init : { ...config.init, signal };\n\n let response = await (this.#fetch ?? fetch)(new Request(config.url, init));\n\n for (let i = this.#interceptors.length - 1; i >= 0; i--) {\n const interceptor = this.#interceptors[i];\n if (interceptor.after) {\n response = await interceptor.after(response.clone());\n }\n }\n\n if (mapper) {\n return await parse(outputs, response, mapper);\n }\n return await parse(outputs, response);\n }\n}\n";
1329
+ var dispatcher_default = "export type Unionize<T> = T extends [infer Single extends OutputType]\n ? InstanceType<Single>\n : T extends readonly [...infer Tuple extends OutputType[]]\n ? { [I in keyof Tuple]: InstanceType<Tuple[I]> }[number]\n : never;\n\nexport type InstanceType<T> =\n T extends Type<infer U>\n ? U\n : T extends { type: Type<infer U> }\n ? U\n : T extends Array<unknown>\n ? Unionize<T>\n : never;\n\ntype ResponseData<T extends OutputType[]> =\n Extract<InstanceType<T>, SuccessfulResponse> extends SuccessfulResponse<\n infer P\n >\n ? P\n : unknown;\n\ntype ResponseMapper<T extends OutputType[], R> = (data: ResponseData<T>) => R;\n\nexport interface Type<T> {\n new (...args: any[]): T;\n}\nexport type Parser = (\n response: Response,\n) => Promise<unknown> | ReadableStream<any> | SSEListener;\nexport type OutputType =\n | Type<APIResponse>\n | { parser: Parser; type: Type<APIResponse> };\n\n// Bare z.custom (no predicate) on purpose: Request/Response from another\n// realm (undici vs global fetch) fail instanceof checks. The output is\n// typed as a Promise directly \u2014 zod 4 deprecated z.promise.\nexport const fetchType = z\n .function({\n input: [z.custom<Request>()],\n output: z.custom<Promise<Response>>(),\n })\n .optional();\n\nexport async function parse<T extends OutputType[]>(\n outputs: T,\n response: Response,\n): Promise<Extract<Unionize<T>, SuccessfulResponse<unknown>>>;\nexport async function parse<T extends OutputType[], R>(\n outputs: T,\n response: Response,\n mapper: ResponseMapper<T, R>,\n): Promise<RebindSuccessPayload<Extract<Unionize<T>, SuccessfulResponse<unknown>>, R>>;\nexport async function parse<T extends OutputType[], R = ResponseData<T>>(\n outputs: T,\n response: Response,\n mapper?: ResponseMapper<T, R>,\n) {\n let output: typeof APIResponse | null = null;\n let parser: Parser = buffered;\n for (const outputType of outputs) {\n if ('parser' in outputType) {\n if (isTypeOf(outputType.type, APIResponse)) {\n if (response.status === outputType.type.status) {\n parser = outputType.parser;\n output = outputType.type;\n break;\n }\n }\n } else if (isTypeOf(outputType, APIResponse)) {\n if (response.status === outputType.status) {\n output = outputType;\n break;\n }\n }\n }\n\n if (response.ok) {\n const data = (await parser(response)) as ResponseData<T>;\n const mapped = mapper ? mapper(data) : data;\n const apiresponse = (output || APIResponse).create(\n response.status,\n response.headers,\n mapped,\n );\n\n return apiresponse as Extract<Unionize<T>, SuccessfulResponse<unknown>>;\n }\n\n throw (output || APIError).create(\n response.status,\n response.headers,\n await parser(response),\n );\n}\n\nexport function isTypeOf<T extends Type<APIResponse>>(\n instance: any,\n baseType: T,\n): instance is T {\n if (instance === baseType) {\n return true;\n }\n const prototype = Object.getPrototypeOf(instance);\n if (prototype === null) {\n return false;\n }\n return isTypeOf(prototype, baseType);\n}\n\nexport class Dispatcher {\n #interceptors: Interceptor[] = [];\n #fetch: z.infer<typeof fetchType>;\n constructor(interceptors: Interceptor[], fetch?: z.infer<typeof fetchType>) {\n this.#interceptors = interceptors;\n this.#fetch = fetch;\n }\n\n async send<T extends OutputType[]>(\n config: RequestConfig,\n outputs: T,\n signal?: AbortSignal,\n ): Promise<Extract<Unionize<T>, SuccessfulResponse<unknown>>>;\n async send<T extends OutputType[], R>(\n config: RequestConfig,\n outputs: T,\n signal: AbortSignal | undefined,\n mapper: ResponseMapper<T, R>,\n ): Promise<RebindSuccessPayload<Extract<Unionize<T>, SuccessfulResponse<unknown>>, R>>;\n async send<T extends OutputType[], R = ResponseData<T>>(\n config: RequestConfig,\n outputs: T,\n signal?: AbortSignal,\n mapper?: ResponseMapper<T, R>,\n ) {\n for (const interceptor of this.#interceptors) {\n if (interceptor.before) {\n config = await interceptor.before(config);\n }\n }\n\n const init = signal === undefined ? config.init : { ...config.init, signal };\n\n let response = await (this.#fetch ?? fetch)(new Request(config.url, init));\n\n for (let i = this.#interceptors.length - 1; i >= 0; i--) {\n const interceptor = this.#interceptors[i];\n if (interceptor.after) {\n response = await interceptor.after(response.clone());\n }\n }\n\n if (mapper) {\n return await parse(outputs, response, mapper);\n }\n return await parse(outputs, response);\n }\n}\n";
1330
1330
 
1331
1331
  // packages/typescript/src/lib/http/interceptors.txt
1332
1332
  var interceptors_default = "export interface Interceptor {\n before?: (config: RequestConfig) => Promise<RequestConfig> | RequestConfig;\n after?: (response: Response) => Promise<Response> | Response;\n}\n\nexport const createHeadersInterceptor = (\n headers: Record<string, string | undefined>,\n requestHeaders: HeadersInit,\n):Interceptor => {\n return {\n before({init, url}) {\n // Priority Levels\n // 1. Headers Input\n // 2. Request Headers\n // 3. Default Headers\n\n for (const [key, value] of new Headers(requestHeaders)) {\n // Only set the header if it doesn't already exist and has a value\n // even though these headers are passed at operation level\n // still they are lower priority compared to the headers input\n if (value !== undefined && !init.headers.has(key)) {\n init.headers.set(key, value);\n }\n }\n\n for (const [key, value] of Object.entries(headers)) {\n // Only set the header if it doesn't already exist and has a value\n if (value !== undefined && !init.headers.has(key)) {\n init.headers.set(key, value);\n }\n }\n\n return {init, url};\n },\n };\n};\n\nexport const createBaseUrlInterceptor = (baseUrl: string): Interceptor => {\n return {\n before({ init, url }) {\n if (url.protocol === 'local:') {\n return {\n init,\n url: new URL(url.href.replace('local://', baseUrl))\n };\n }\n return { init, url };\n },\n };\n};\n\nexport const logInterceptor: Interceptor = {\n before({ url, init }) {\n console.log('Request:', { url, init });\n return { url, init };\n },\n after(response) {\n console.log('Response:', response);\n return response;\n },\n};\n\n/**\n * Creates an interceptor that logs detailed information about requests and responses.\n * @param options Configuration options for the logger\n * @returns An interceptor object with before and after handlers\n */\nexport const createDetailedLogInterceptor = (options?: {\n logLevel?: 'debug' | 'info' | 'warn' | 'error';\n includeRequestBody?: boolean;\n includeResponseBody?: boolean;\n}) => {\n const logLevel = options?.logLevel || 'info';\n const includeRequestBody = options?.includeRequestBody || false;\n const includeResponseBody = options?.includeResponseBody || false;\n\n return {\n async before(request: Request) {\n const logData = {\n url: request.url,\n method: request.method,\n contentType: request.headers.get('Content-Type'),\n headers: Object.fromEntries([...request.headers.entries()]),\n };\n\n console[logLevel]('\u{1F680} Outgoing Request:', logData);\n\n if (includeRequestBody) {\n try {\n // Clone the request to avoid consuming the body stream\n const clonedRequest = request.clone();\n if (clonedRequest.headers.get('Content-Type')?.includes('application/json')) {\n const body = await clonedRequest.json().catch(() => null);\n console[logLevel]('Request Body:', body);\n } else {\n const body = await clonedRequest.text().catch(() => null);\n console[logLevel]('Request Body:', body);\n }\n } catch (error) {\n console.error('Could not log request body:', error);\n }\n }\n\n return request;\n },\n\n async after(response: Response) {\n const logData = {\n status: response.status,\n statusText: response.statusText,\n url: response.url,\n headers: Object.fromEntries([...response.headers.entries()]),\n };\n\n console[logLevel]('\u{1F4E5} Incoming Response:', logData);\n\n if (includeResponseBody && response.body) {\n try {\n // Clone the response to avoid consuming the body stream\n const clonedResponse = response.clone();\n if (clonedResponse.headers.get('Content-Type')?.includes('application/json')) {\n const body = await clonedResponse.json().catch(() => null);\n console[logLevel]('Response Body:', body);\n } else {\n const body = await clonedResponse.text().catch(() => null);\n if (body) {\n console[logLevel]('Response Body:', body.substring(0, 500) + (body.length > 500 ? '...' : ''));\n } else {\n console[logLevel]('No response body');\n }\n }\n } catch (error) {\n console.error('Could not log response body:', error);\n }\n }\n\n return response;\n },\n };\n};\n";
1333
1333
 
1334
1334
  // packages/typescript/src/lib/http/parse-response.txt
1335
- var parse_response_default = 'import { parse } from "fast-content-type-parse";\n\nfunction isBinaryContentType(contentType: string) {\n const type = contentType.toLowerCase();\n if (type.startsWith("image/")) {\n return true;\n }\n if (type.startsWith("audio/")) {\n return true;\n }\n if (type.startsWith("video/")) {\n return true;\n }\n switch (type) {\n case "application/pdf":\n case "application/zip":\n case "application/gzip":\n case "application/x-7z-compressed":\n case "application/x-tar":\n case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":\n case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":\n case "application/vnd.openxmlformats-officedocument.presentationml.presentation":\n case "application/vnd.ms-excel":\n case "application/vnd.ms-powerpoint":\n case "application/msword":\n case "application/octet-stream":\n return true;\n default:\n return false;\n }\n}\n\nasync function handleChunkedResponse(response: Response, contentType: string) {\n const { type } = parse(contentType);\n\n switch (type) {\n case "application/json": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return JSON.parse(buffer);\n }\n case "text/html":\n case "text/plain": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return buffer;\n }\n default:\n return response.body;\n }\n}\n\nexport function chunked(response: Response) {\n return response.body!;\n}\n\nexport async function buffered(response: Response) {\n const contentType = response.headers.get("Content-Type");\n if (!contentType) {\n throw new Error("Content-Type header is missing");\n }\n\n if (response.status === 204) {\n return null;\n }\n\n const { type } = parse(contentType);\n if (isBinaryContentType(type)) {\n return response.blob();\n }\n if (type.startsWith("text/")) {\n return response.text();\n }\n switch (type) {\n case "application/json":\n return response.json();\n case "application/xml":\n return response.text();\n case "application/x-www-form-urlencoded": {\n const text = await response.text();\n return Object.fromEntries(new URLSearchParams(text));\n }\n case "multipart/form-data":\n return response.formData();\n default:\n throw new Error(`Unsupported content type: ${contentType}`);\n }\n}\n';
1335
+ var parse_response_default = 'import { parse } from "fast-content-type-parse";\n\nfunction isBinaryContentType(contentType: string) {\n const type = contentType.toLowerCase();\n if (type.startsWith("image/")) {\n return true;\n }\n if (type.startsWith("audio/")) {\n return true;\n }\n if (type.startsWith("video/")) {\n return true;\n }\n switch (type) {\n case "application/pdf":\n case "application/zip":\n case "application/gzip":\n case "application/x-7z-compressed":\n case "application/x-tar":\n case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":\n case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":\n case "application/vnd.openxmlformats-officedocument.presentationml.presentation":\n case "application/vnd.ms-excel":\n case "application/vnd.ms-powerpoint":\n case "application/msword":\n case "application/octet-stream":\n return true;\n default:\n return false;\n }\n}\n\nasync function handleChunkedResponse(response: Response, contentType: string) {\n const { type } = parse(contentType);\n\n switch (type) {\n case "application/json": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return JSON.parse(buffer);\n }\n case "text/html":\n case "text/plain": {\n let buffer = "";\n const reader = response.body!.getReader();\n const decoder = new TextDecoder();\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value);\n }\n return buffer;\n }\n default:\n return response.body;\n }\n}\n\nexport function chunked(response: Response) {\n return response.body!;\n}\n\nexport async function buffered(response: Response) {\n // Statuses that, per the HTTP spec, carry no message body. These responses\n // usually omit Content-Type entirely, so this must run before the guard below.\n if (\n response.status === 204 ||\n response.status === 205 ||\n response.status === 304\n ) {\n return null;\n }\n\n const contentType = response.headers.get("Content-Type");\n if (!contentType) {\n throw new Error("Content-Type header is missing");\n }\n\n const { type } = parse(contentType);\n if (isBinaryContentType(type)) {\n return response.blob();\n }\n if (type.startsWith("text/")) {\n return response.text();\n }\n switch (type) {\n case "application/json":\n return response.json();\n case "application/xml":\n return response.text();\n case "application/x-www-form-urlencoded": {\n const text = await response.text();\n return Object.fromEntries(new URLSearchParams(text));\n }\n case "multipart/form-data":\n return response.formData();\n default:\n throw new Error(`Unsupported content type: ${contentType}`);\n }\n}\n';
1336
1336
 
1337
1337
  // packages/typescript/src/lib/http/parser.txt
1338
- var parser_default = "import { z } from 'zod';\n\nexport class ParseError<T extends z.ZodType<any, any, any>> extends Error {\n public data: z.typeToFlattenedError<T, z.ZodIssue>;\n constructor(data: z.typeToFlattenedError<T, z.ZodIssue>) {\n super('Validation failed');\n this.name = 'ParseError';\n this.data = data;\n }\n}\n\nexport function parseInput<T extends z.ZodType<any, any, any>>(\n schema: T,\n input: unknown,\n): z.infer<T> {\n const result = schema.safeParse(input);\n if (!result.success) {\n const error = result.error.flatten((issue) => issue);\n throw new ParseError(error);\n }\n return result.data as z.infer<T>;\n}\n";
1338
+ var parser_default = "import { z } from 'zod';\n\nexport class ParseError<T extends z.ZodType> extends Error {\n public data: z.core.$ZodFlattenedError<z.output<T>, z.core.$ZodIssue>;\n constructor(\n data: z.core.$ZodFlattenedError<z.output<T>, z.core.$ZodIssue>,\n ) {\n super('Validation failed');\n this.name = 'ParseError';\n this.data = data;\n }\n}\n\nexport function parseInput<T extends z.ZodType>(\n schema: T,\n input: unknown,\n): z.infer<T> {\n const result = schema.safeParse(input);\n if (!result.success) {\n const error = z.flattenError(result.error, (issue) => issue);\n throw new ParseError<T>(error);\n }\n return result.data as z.infer<T>;\n}\n";
1339
1339
 
1340
1340
  // packages/typescript/src/lib/http/request.txt
1341
- var request_default = "type Init = Omit<RequestInit, 'headers'> & { headers: Headers };\nexport type RequestConfig = { init: Init; url: URL };\nexport type Method =\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'PATCH'\n | 'DELETE'\n | 'HEAD'\n | 'OPTIONS';\nexport type ContentType =\n | 'xml'\n | 'json'\n | 'urlencoded'\n | 'multipart'\n | 'formdata';\nexport type HeadersInit = [string, string][] | Record<string, string>;\nexport type Endpoint =\n | `${ContentType} ${Method} ${string}`\n | `${Method} ${string}`;\n\nexport type BodyInit =\n | ArrayBuffer\n | Blob\n | FormData\n | URLSearchParams\n | null\n | string;\n\nfunction template(\n templateString: string,\n templateVariables: Record<string, any>,\n): string {\n const nargs = /{([0-9a-zA-Z_]+)}/g;\n return templateString.replace(nargs, (match, key: string, index: number) => {\n // Handle escaped double braces\n if (\n templateString[index - 1] === '{' &&\n templateString[index + match.length] === '}'\n ) {\n return key;\n }\n\n const result = key in templateVariables ? templateVariables[key] : null;\n return result === null || result === undefined ? '' : String(result);\n });\n}\n\ntype Input = Record<string, any>;\ntype Props = {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n};\n\nabstract class Serializer {\n protected input: Input;\n protected props: Props;\n\n constructor(input: Input, props: Props) {\n this.input = input;\n this.props = props;\n }\n\n abstract getBody(): BodyInit | null;\n abstract getHeaders(): Record<string, string>;\n serialize(path: string): Serialized {\n const params = this.props.inputParams.reduce<Record<string, any>>(\n (acc, key) => {\n acc[key] = this.input[key];\n return acc;\n },\n {},\n );\n const url = new URL(template(path, params), `local://`);\n\n const headers = new Headers({});\n for (const header of this.props.inputHeaders) {\n headers.set(header, this.input[header]);\n }\n\n for (const key of this.props.inputQuery) {\n const value = this.input[key];\n if (value !== undefined) {\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, String(item));\n }\n } else {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n return {\n body: this.getBody(),\n url,\n headers: this.getHeaders(),\n };\n }\n}\n\ninterface Serialized {\n body: BodyInit | null;\n headers: Record<string, string>;\n url: URL;\n}\n\nclass JsonSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body: Record<string, any> = {};\n if (\n this.props.inputBody.length === 1 &&\n this.props.inputBody[0] === '$body'\n ) {\n return JSON.stringify(this.input.$body);\n }\n\n for (const prop of this.props.inputBody) {\n body[prop] = this.input[prop];\n }\n return JSON.stringify(body);\n }\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n\nclass UrlencodedSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new URLSearchParams();\n for (const prop of this.props.inputBody) {\n body.set(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Accept: 'application/json',\n };\n }\n}\n\nclass EmptySerializer extends Serializer {\n getBody(): BodyInit | null {\n return null;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nclass FormDataSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new FormData();\n for (const prop of this.props.inputBody) {\n body.append(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {\n Accept: 'application/json',\n };\n }\n}\n\nexport function json(input: Input, props: Props) {\n return new JsonSerializer(input, props);\n}\nexport function urlencoded(input: Input, props: Props) {\n return new UrlencodedSerializer(input, props);\n}\nexport function empty(input: Input, props: Props) {\n return new EmptySerializer(input, props);\n}\nexport function formdata(input: Input, props: Props) {\n return new FormDataSerializer(input, props);\n}\n\nexport function toRequest<T extends Endpoint>(\n endpoint: T,\n serializer: Serializer,\n): RequestConfig {\n const [method, path] = endpoint.split(' ');\n const input = serializer.serialize(path);\n return {\n url: input.url,\n init: {\n method: method,\n headers: new Headers(input.headers),\n body: method === 'GET' ? undefined : input.body,\n },\n };\n}\n";
1341
+ var request_default = "type Init = Omit<RequestInit, 'headers'> & { headers: Headers };\nexport type RequestConfig = { init: Init; url: URL };\nexport type Method =\n | 'GET'\n | 'POST'\n | 'PUT'\n | 'PATCH'\n | 'DELETE'\n | 'HEAD'\n | 'OPTIONS';\nexport type ContentType =\n | 'xml'\n | 'json'\n | 'urlencoded'\n | 'multipart'\n | 'formdata';\nexport type HeadersInit = [string, string][] | Record<string, string>;\nexport type Endpoint =\n | `${ContentType} ${Method} ${string}`\n | `${Method} ${string}`;\n\nexport type BodyInit =\n | ArrayBuffer\n | Blob\n | FormData\n | URLSearchParams\n | null\n | string;\n\nfunction template(\n templateString: string,\n templateVariables: Record<string, any>,\n): string {\n const nargs = /{([0-9a-zA-Z_]+)}/g;\n return templateString.replace(nargs, (match, key: string, index: number) => {\n // Handle escaped double braces\n if (\n templateString[index - 1] === '{' &&\n templateString[index + match.length] === '}'\n ) {\n return key;\n }\n\n const result = key in templateVariables ? templateVariables[key] : null;\n return result === null || result === undefined ? '' : String(result);\n });\n}\n\ntype Input = Record<string, any>;\n\n// Validated inputs can carry Date (coerce-date) values; String(new Date())\n// yields a local-time RFC 2822 string, so serialize Dates as ISO 8601.\nfunction toWireValue(value: any): string {\n return value instanceof Date ? value.toISOString() : String(value);\n}\n\ntype Props = {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n};\n\nabstract class Serializer {\n protected input: Input;\n protected props: Props;\n\n constructor(input: Input, props: Props) {\n this.input = input;\n this.props = props;\n }\n\n abstract getBody(): BodyInit | null;\n abstract getHeaders(): Record<string, string>;\n serialize(path: string): Serialized {\n const params = this.props.inputParams.reduce<Record<string, any>>(\n (acc, key) => {\n acc[key] = this.input[key];\n return acc;\n },\n {},\n );\n const url = new URL(template(path, params), `local://`);\n\n const headers: Record<string, string> = { ...this.getHeaders() };\n for (const header of this.props.inputHeaders) {\n const value = this.input[header];\n if (value !== undefined) {\n headers[header] = toWireValue(value);\n }\n }\n\n for (const key of this.props.inputQuery) {\n const value = this.input[key];\n if (value !== undefined) {\n if (Array.isArray(value)) {\n for (const item of value) {\n url.searchParams.append(key, toWireValue(item));\n }\n } else {\n url.searchParams.set(key, toWireValue(value));\n }\n }\n }\n\n return {\n body: this.getBody(),\n url,\n headers,\n };\n }\n}\n\ninterface Serialized {\n body: BodyInit | null;\n headers: Record<string, string>;\n url: URL;\n}\n\nclass JsonSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body: Record<string, any> = {};\n if (\n this.props.inputBody.length === 1 &&\n this.props.inputBody[0] === '$body'\n ) {\n return JSON.stringify(this.input.$body);\n }\n\n for (const prop of this.props.inputBody) {\n body[prop] = this.input[prop];\n }\n return JSON.stringify(body);\n }\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n\nclass UrlencodedSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new URLSearchParams();\n for (const prop of this.props.inputBody) {\n body.set(prop, toWireValue(this.input[prop]));\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/x-www-form-urlencoded',\n Accept: 'application/json',\n };\n }\n}\n\nclass EmptySerializer extends Serializer {\n getBody(): BodyInit | null {\n return null;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nclass FormDataSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new FormData();\n for (const prop of this.props.inputBody) {\n body.append(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {\n Accept: 'application/json',\n };\n }\n}\n\nexport function json(input: Input, props: Props) {\n return new JsonSerializer(input, props);\n}\nexport function urlencoded(input: Input, props: Props) {\n return new UrlencodedSerializer(input, props);\n}\nexport function empty(input: Input, props: Props) {\n return new EmptySerializer(input, props);\n}\nexport function formdata(input: Input, props: Props) {\n return new FormDataSerializer(input, props);\n}\n\nexport function toRequest<T extends Endpoint>(\n endpoint: T,\n serializer: Serializer,\n): RequestConfig {\n const [method, path] = endpoint.split(' ');\n const input = serializer.serialize(path);\n return {\n url: input.url,\n init: {\n method: method,\n headers: new Headers(input.headers),\n body: method === 'GET' ? undefined : input.body,\n },\n };\n}\n";
1342
1342
 
1343
1343
  // packages/typescript/src/lib/http/response.txt
1344
- var response_default = "export class APIResponse<Body = unknown, Status extends number = number> {\n static readonly status: number;\n readonly status: Status;\n data: Body;\n readonly headers: Headers;\n\n constructor(status: Status, headers: Headers, data: Body) {\n this.status = status;\n this.headers = headers;\n this.data = data;\n }\n\n static create<Body = unknown>(status: number, headers: Headers, data: Body) {\n return new this(status, headers, data);\n }\n}\n\nexport class APIError<Body, Status extends number = number> extends APIResponse<\n Body,\n Status\n> {\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(status, headers, data);\n }\n}\n\n// 2xx Success\nexport class Ok<T> extends APIResponse<T, 200> {\n static override readonly status = 200 as const;\n constructor(headers: Headers, data: T) {\n super(Ok.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\n\nexport class Created<T> extends APIResponse<T, 201> {\n static override status = 201 as const;\n constructor(headers: Headers, data: T) {\n super(Created.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Accepted<T> extends APIResponse<T, 202> {\n static override status = 202 as const;\n constructor(headers: Headers, data: T) {\n super(Accepted.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NoContent extends APIResponse<never, 204> {\n static override status = 204 as const;\n constructor(headers: Headers) {\n super(NoContent.status, headers, null as never);\n }\n static override create(status: number, headers: Headers): NoContent {\n return new this(headers);\n }\n}\n\n// 4xx Client Errors\nexport class BadRequest<T> extends APIError<T, 400> {\n static override status = 400 as const;\n constructor(headers: Headers, data: T) {\n super(BadRequest.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Unauthorized<T = { message: string }> extends APIError<T, 401> {\n static override status = 401 as const;\n constructor(headers: Headers, data: T) {\n super(Unauthorized.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class PaymentRequired<T = { message: string }> extends APIError<T, 402> {\n static override status = 402 as const;\n constructor(headers: Headers, data: T) {\n super(PaymentRequired.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Forbidden<T = { message: string }> extends APIError<T, 403> {\n static override status = 403 as const;\n constructor(headers: Headers, data: T) {\n super(Forbidden.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NotFound<T = { message: string }> extends APIError<T, 404> {\n static override status = 404 as const;\n constructor(headers: Headers, data: T) {\n super(NotFound.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class MethodNotAllowed<T = { message: string }> extends APIError<\n T,\n 405\n> {\n static override status = 405 as const;\n constructor(headers: Headers, data: T) {\n super(MethodNotAllowed.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NotAcceptable<T = { message: string }> extends APIError<T, 406> {\n static override status = 406 as const;\n constructor(headers: Headers, data: T) {\n super(NotAcceptable.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Conflict<T = { message: string }> extends APIError<T, 409> {\n static override status = 409 as const;\n constructor(headers: Headers, data: T) {\n super(Conflict.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Gone<T = { message: string }> extends APIError<T, 410> {\n static override status = 410 as const;\n constructor(headers: Headers, data: T) {\n super(Gone.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class PreconditionFailed<T = { message: string }> extends APIError<\n T,\n 412\n> {\n static override status = 412 as const;\n constructor(headers: Headers, data: T) {\n super(PreconditionFailed.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class UnprocessableEntity<\n T = { message: string; errors?: Record<string, string[]> },\n> extends APIError<T, 422> {\n static override status = 422 as const;\n constructor(headers: Headers, data: T) {\n super(UnprocessableEntity.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class TooManyRequests<\n T = { message: string; retryAfter?: string },\n> extends APIError<T, 429> {\n static override status = 429 as const;\n constructor(headers: Headers, data: T) {\n super(TooManyRequests.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class PayloadTooLarge<T = { message: string }> extends APIError<T, 413> {\n static override status = 413 as const;\n constructor(headers: Headers, data: T) {\n super(PayloadTooLarge.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class UnsupportedMediaType<T = { message: string }> extends APIError<\n T,\n 415\n> {\n static override status = 415 as const;\n constructor(headers: Headers, data: T) {\n super(UnsupportedMediaType.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\n\n// 5xx Server Errors\nexport class InternalServerError<T = { message: string }> extends APIError<\n T,\n 500\n> {\n static override status = 500 as const;\n constructor(headers: Headers, data: T) {\n super(InternalServerError.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NotImplemented<T = { message: string }> extends APIError<T, 501> {\n static override status = 501 as const;\n constructor(headers: Headers, data: T) {\n super(NotImplemented.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class BadGateway<T = { message: string }> extends APIError<T, 502> {\n static override status = 502 as const;\n constructor(headers: Headers, data: T) {\n super(BadGateway.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class ServiceUnavailable<\n T = { message: string; retryAfter?: string },\n> extends APIError<T, 503> {\n static override status = 503 as const;\n constructor(headers: Headers, data: T) {\n super(ServiceUnavailable.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class GatewayTimeout<T = { message: string }> extends APIError<T, 504> {\n static override status = 504 as const;\n constructor(headers: Headers, data: T) {\n super(GatewayTimeout.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\n\nexport type ClientError =\n | BadRequest<unknown>\n | Unauthorized<unknown>\n | PaymentRequired<unknown>\n | Forbidden<unknown>\n | NotFound<unknown>\n | MethodNotAllowed<unknown>\n | NotAcceptable<unknown>\n | Conflict<unknown>\n | Gone<unknown>\n | PreconditionFailed<unknown>\n | PayloadTooLarge<unknown>\n | UnsupportedMediaType<unknown>\n | UnprocessableEntity<unknown>\n | TooManyRequests<unknown>;\n\nexport type ServerError =\n | InternalServerError<unknown>\n | NotImplemented<unknown>\n | BadGateway<unknown>\n | ServiceUnavailable<unknown>\n | GatewayTimeout<unknown>;\n\nexport type ProblematicResponse = ClientError | ServerError;\n\nexport type SuccessfulResponse<T = unknown> =\n | Ok<T>\n | Created<T>\n | Accepted<T>\n | NoContent;\n\nexport type RebindSuccessPayload<Resp, New> =\n Resp extends Ok<infer _>\n ? Ok<New>\n : Resp extends Created<infer _>\n ? Created<New>\n : Resp extends Accepted<infer _>\n ? Accepted<New>\n : Resp extends NoContent\n ? NoContent\n : Resp extends SuccessfulResponse<infer _>\n ? APIResponse<New, Resp['status']>\n : never;\n";
1344
+ var response_default = "export class APIResponse<Body = unknown, Status extends number = number> {\n static readonly status: number;\n readonly status: Status;\n data: Body;\n readonly headers: Headers;\n\n constructor(status: Status, headers: Headers, data: Body) {\n this.status = status;\n this.headers = headers;\n this.data = data;\n }\n\n static create<Body = unknown>(status: number, headers: Headers, data: Body) {\n return new this(status, headers, data);\n }\n}\n\nexport class APIError<Body, Status extends number = number> extends APIResponse<\n Body,\n Status\n> {\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(status, headers, data);\n }\n}\n\n// 2xx Success\nexport class Ok<T> extends APIResponse<T, 200> {\n static override readonly status = 200 as const;\n constructor(headers: Headers, data: T) {\n super(Ok.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\n\nexport class Created<T> extends APIResponse<T, 201> {\n static override status = 201 as const;\n constructor(headers: Headers, data: T) {\n super(Created.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Accepted<T> extends APIResponse<T, 202> {\n static override status = 202 as const;\n constructor(headers: Headers, data: T) {\n super(Accepted.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NoContent extends APIResponse<never, 204> {\n static override status = 204 as const;\n constructor(headers: Headers) {\n super(NoContent.status, headers, null as never);\n }\n static override create(\n status: number,\n headers: Headers,\n data?: unknown,\n ): NoContent {\n return new this(headers);\n }\n}\n\n// 4xx Client Errors\nexport class BadRequest<T> extends APIError<T, 400> {\n static override status = 400 as const;\n constructor(headers: Headers, data: T) {\n super(BadRequest.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Unauthorized<T = { message: string }> extends APIError<T, 401> {\n static override status = 401 as const;\n constructor(headers: Headers, data: T) {\n super(Unauthorized.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class PaymentRequired<T = { message: string }> extends APIError<T, 402> {\n static override status = 402 as const;\n constructor(headers: Headers, data: T) {\n super(PaymentRequired.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Forbidden<T = { message: string }> extends APIError<T, 403> {\n static override status = 403 as const;\n constructor(headers: Headers, data: T) {\n super(Forbidden.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NotFound<T = { message: string }> extends APIError<T, 404> {\n static override status = 404 as const;\n constructor(headers: Headers, data: T) {\n super(NotFound.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class MethodNotAllowed<T = { message: string }> extends APIError<\n T,\n 405\n> {\n static override status = 405 as const;\n constructor(headers: Headers, data: T) {\n super(MethodNotAllowed.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NotAcceptable<T = { message: string }> extends APIError<T, 406> {\n static override status = 406 as const;\n constructor(headers: Headers, data: T) {\n super(NotAcceptable.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Conflict<T = { message: string }> extends APIError<T, 409> {\n static override status = 409 as const;\n constructor(headers: Headers, data: T) {\n super(Conflict.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class Gone<T = { message: string }> extends APIError<T, 410> {\n static override status = 410 as const;\n constructor(headers: Headers, data: T) {\n super(Gone.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class PreconditionFailed<T = { message: string }> extends APIError<\n T,\n 412\n> {\n static override status = 412 as const;\n constructor(headers: Headers, data: T) {\n super(PreconditionFailed.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class UnprocessableEntity<\n T = { message: string; errors?: Record<string, string[]> },\n> extends APIError<T, 422> {\n static override status = 422 as const;\n constructor(headers: Headers, data: T) {\n super(UnprocessableEntity.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class TooManyRequests<\n T = { message: string; retryAfter?: string },\n> extends APIError<T, 429> {\n static override status = 429 as const;\n constructor(headers: Headers, data: T) {\n super(TooManyRequests.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class PayloadTooLarge<T = { message: string }> extends APIError<T, 413> {\n static override status = 413 as const;\n constructor(headers: Headers, data: T) {\n super(PayloadTooLarge.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class UnsupportedMediaType<T = { message: string }> extends APIError<\n T,\n 415\n> {\n static override status = 415 as const;\n constructor(headers: Headers, data: T) {\n super(UnsupportedMediaType.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\n\n// 5xx Server Errors\nexport class InternalServerError<T = { message: string }> extends APIError<\n T,\n 500\n> {\n static override status = 500 as const;\n constructor(headers: Headers, data: T) {\n super(InternalServerError.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class NotImplemented<T = { message: string }> extends APIError<T, 501> {\n static override status = 501 as const;\n constructor(headers: Headers, data: T) {\n super(NotImplemented.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class BadGateway<T = { message: string }> extends APIError<T, 502> {\n static override status = 502 as const;\n constructor(headers: Headers, data: T) {\n super(BadGateway.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class ServiceUnavailable<\n T = { message: string; retryAfter?: string },\n> extends APIError<T, 503> {\n static override status = 503 as const;\n constructor(headers: Headers, data: T) {\n super(ServiceUnavailable.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\nexport class GatewayTimeout<T = { message: string }> extends APIError<T, 504> {\n static override status = 504 as const;\n constructor(headers: Headers, data: T) {\n super(GatewayTimeout.status, headers, data);\n }\n static override create<T>(status: number, headers: Headers, data: T) {\n return new this(headers, data);\n }\n}\n\nexport type ClientError =\n | BadRequest<unknown>\n | Unauthorized<unknown>\n | PaymentRequired<unknown>\n | Forbidden<unknown>\n | NotFound<unknown>\n | MethodNotAllowed<unknown>\n | NotAcceptable<unknown>\n | Conflict<unknown>\n | Gone<unknown>\n | PreconditionFailed<unknown>\n | PayloadTooLarge<unknown>\n | UnsupportedMediaType<unknown>\n | UnprocessableEntity<unknown>\n | TooManyRequests<unknown>;\n\nexport type ServerError =\n | InternalServerError<unknown>\n | NotImplemented<unknown>\n | BadGateway<unknown>\n | ServiceUnavailable<unknown>\n | GatewayTimeout<unknown>;\n\nexport type ProblematicResponse = ClientError | ServerError;\n\nexport type SuccessfulResponse<T = unknown> =\n | Ok<T>\n | Created<T>\n | Accepted<T>\n | NoContent;\n\nexport type RebindSuccessPayload<Resp, New> =\n Resp extends Ok<infer _>\n ? Ok<New>\n : Resp extends Created<infer _>\n ? Created<New>\n : Resp extends Accepted<infer _>\n ? Accepted<New>\n : Resp extends NoContent\n ? NoContent\n : Resp extends SuccessfulResponse<infer _>\n ? APIResponse<New, Resp['status']>\n : never;\n";
1345
1345
 
1346
1346
  // packages/typescript/src/lib/http/sse.txt
1347
- var sse_default = 'export type SSEListener = (eventType: string) => AsyncIterable<string>;\n\nexport function sse(response: Response): SSEListener {\n const subscribers = new Map<\n string,\n { queue: string[]; resolve: (() => void) | null }\n >();\n let started = false;\n let streamDone = false;\n\n function dispatch(eventType: string, data: string) {\n const sub = subscribers.get(eventType);\n if (sub) {\n sub.queue.push(data);\n sub.resolve?.();\n sub.resolve = null;\n }\n }\n\n function endAll() {\n streamDone = true;\n for (const sub of subscribers.values()) {\n sub.resolve?.();\n }\n }\n\n function startReading() {\n if (started) return;\n started = true;\n const decoder = new TextDecoder();\n let buffer = "";\n\n (async () => {\n try {\n for await (const value of response.body!) {\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split("\\n\\n");\n buffer = parts.pop()!;\n\n for (const part of parts) {\n if (!part.trim()) continue;\n let eventType = "message";\n let data = "";\n for (const line of part.split("\\n")) {\n if (line.startsWith("event:")) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith("data:")) {\n data += (data ? "\\n" : "") + line.slice(5).trim();\n }\n }\n if (data) dispatch(eventType, data);\n }\n }\n } catch {}\n endAll();\n })();\n }\n\n return function listen(eventType: string): AsyncIterable<string> {\n if (!subscribers.has(eventType)) {\n subscribers.set(eventType, { queue: [], resolve: null });\n }\n const sub = subscribers.get(eventType)!;\n startReading();\n\n return {\n [Symbol.asyncIterator]() {\n return {\n async next(): Promise<IteratorResult<string>> {\n while (sub.queue.length === 0) {\n if (streamDone) return { value: undefined as any, done: true };\n const { promise, resolve } = Promise.withResolvers<void>();\n sub.resolve = resolve;\n await promise;\n }\n return { value: sub.queue.shift()!, done: false };\n },\n async return(): Promise<IteratorResult<string>> {\n return { value: undefined as any, done: true };\n },\n };\n },\n };\n };\n}\n';
1347
+ var sse_default = 'export type SSEListener = (eventType: string) => AsyncIterable<string>;\n\nexport function sse(response: Response): SSEListener {\n const subscribers = new Map<\n string,\n { queue: string[]; resolve: (() => void) | null }\n >();\n let started = false;\n let streamDone = false;\n\n function dispatch(eventType: string, data: string) {\n const sub = subscribers.get(eventType);\n if (sub) {\n sub.queue.push(data);\n sub.resolve?.();\n sub.resolve = null;\n }\n }\n\n function endAll() {\n streamDone = true;\n for (const sub of subscribers.values()) {\n sub.resolve?.();\n }\n }\n\n function startReading() {\n if (started) return;\n started = true;\n const decoder = new TextDecoder();\n let buffer = "";\n\n (async () => {\n try {\n for await (const value of response.body!) {\n buffer += decoder.decode(value, { stream: true });\n const parts = buffer.split("\\n\\n");\n buffer = parts.pop()!;\n\n for (const part of parts) {\n if (!part.trim()) continue;\n let eventType = "message";\n let data = "";\n for (const line of part.split("\\n")) {\n if (line.startsWith("event:")) {\n eventType = line.slice(6).trim();\n } else if (line.startsWith("data:")) {\n data += (data ? "\\n" : "") + line.slice(5).trim();\n }\n }\n if (data) dispatch(eventType, data);\n }\n }\n } catch (err) {\n console.warn("sse stream error", err);\n }\n endAll();\n })();\n }\n\n return function listen(eventType: string): AsyncIterable<string> {\n if (!subscribers.has(eventType)) {\n subscribers.set(eventType, { queue: [], resolve: null });\n }\n const sub = subscribers.get(eventType)!;\n startReading();\n\n return {\n [Symbol.asyncIterator]() {\n return {\n async next(): Promise<IteratorResult<string>> {\n while (sub.queue.length === 0) {\n if (streamDone) return { value: undefined as any, done: true };\n const { promise, resolve } = Promise.withResolvers<void>();\n sub.resolve = resolve;\n await promise;\n }\n return { value: sub.queue.shift()!, done: false };\n },\n async return(): Promise<IteratorResult<string>> {\n return { value: undefined as any, done: true };\n },\n };\n },\n };\n };\n}\n';
1348
1348
 
1349
1349
  // packages/typescript/src/lib/paginations/cursor-pagination.txt
1350
1350
  var cursor_pagination_default = "type CursorPaginationParams = {\n cursor?: string;\n};\n\ninterface CursorMetadata extends Metadata {\n nextCursor?: string;\n}\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationRequestOptions = {\n signal?: AbortSignal;\n};\n\ntype PaginationResult<T, M extends CursorMetadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<T, M extends CursorMetadata> = (\n input: CursorPaginationParams,\n requestOptions?: PaginationRequestOptions,\n) => Promise<PaginationResult<T, M>>;\n\n/**\n * @experimental\n */\nexport class CursorPagination<T, M extends CursorMetadata> {\n #meta: PaginationResult<T, M>['meta'] | null = null;\n #params: CursorPaginationParams;\n #currentPage: Page<T> | null = null;\n readonly #fetchFn: FetchFn<T, M>;\n readonly #requestOptions: PaginationRequestOptions;\n\n constructor(\n initialParams: PartialNullable<CursorPaginationParams>,\n fetchFn: FetchFn<T, M>,\n requestOptions: PaginationRequestOptions = {},\n ) {\n this.#fetchFn = fetchFn;\n this.#requestOptions = requestOptions;\n this.#params = {\n cursor: initialParams.cursor ?? undefined,\n };\n }\n\n async getNextPage(requestOptions?: PaginationRequestOptions) {\n const result = await this.#fetchFn(this.#params, {\n ...this.#requestOptions,\n ...requestOptions,\n });\n this.#currentPage = new Page(result.data);\n this.#meta = result.meta;\n this.#params = {\n ...this.#params,\n cursor: result.meta.nextCursor,\n };\n return this;\n }\n\n getCurrentPage() {\n if (!this.#currentPage) {\n throw new Error(\n 'No page data available. Please call getNextPage() first.',\n );\n }\n return this.#currentPage;\n }\n\n get hasMore() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta.hasMore;\n }\n\n async *[Symbol.asyncIterator]() {\n for await (const page of this.iter()) {\n yield page.getCurrentPage();\n }\n }\n\n async *iter(requestOptions?: PaginationRequestOptions) {\n if (!this.#currentPage) {\n yield await this.getNextPage(requestOptions);\n }\n\n while (this.hasMore) {\n yield await this.getNextPage(requestOptions);\n }\n }\n\n get metadata() {\n if (!this.#meta) {\n throw new Error(\n 'No meta data available. Please call getNextPage() first.',\n );\n }\n return this.#meta;\n }\n}\n\nclass Page<T> {\n data: T[];\n constructor(data: T[]) {\n this.data = data;\n }\n}\n\ntype PartialNullable<T> = {\n [K in keyof T]?: T[K] | null;\n};\n";
@@ -1768,7 +1768,7 @@ function expandServerUrls(servers) {
1768
1768
 
1769
1769
  // packages/typescript/src/lib/typescript-snippet.ts
1770
1770
  import { camelcase as camelcase5, spinalcase as spinalcase3 } from "stringcase";
1771
- import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as resolveRef3 } from "@sdk-it/core";
1771
+ import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as resolveRef4 } from "@sdk-it/core";
1772
1772
  import "@sdk-it/readme";
1773
1773
  import {
1774
1774
  forEachOperation as forEachOperation5,
@@ -1777,7 +1777,7 @@ import {
1777
1777
  } from "@sdk-it/spec";
1778
1778
 
1779
1779
  // packages/typescript/src/lib/emitters/snippet.ts
1780
- import { followRef as followRef5, isRef as isRef5, resolveRef as resolveRef2 } from "@sdk-it/core";
1780
+ import { followRef as followRef5, isRef as isRef5, resolveRef as resolveRef3 } from "@sdk-it/core";
1781
1781
  var SnippetEmitter = class {
1782
1782
  spec;
1783
1783
  generatedRefs = /* @__PURE__ */ new Set();
@@ -1786,12 +1786,12 @@ var SnippetEmitter = class {
1786
1786
  this.spec = spec;
1787
1787
  }
1788
1788
  object(schema) {
1789
- const schemaObj = resolveRef2(this.spec, schema);
1789
+ const schemaObj = resolveRef3(this.spec, schema);
1790
1790
  const result = {};
1791
1791
  const properties = schemaObj.properties || {};
1792
1792
  for (const [propName, propSchema] of Object.entries(properties)) {
1793
1793
  const isRequired = (schemaObj.required ?? []).includes(propName);
1794
- const resolvedProp = resolveRef2(this.spec, propSchema);
1794
+ const resolvedProp = resolveRef3(this.spec, propSchema);
1795
1795
  if (isRequired || resolvedProp.example !== void 0 || resolvedProp.default !== void 0) {
1796
1796
  result[propName] = this.handle(propSchema);
1797
1797
  }
@@ -1804,7 +1804,7 @@ var SnippetEmitter = class {
1804
1804
  return result;
1805
1805
  }
1806
1806
  array(schema) {
1807
- const schemaObj = resolveRef2(this.spec, schema);
1807
+ const schemaObj = resolveRef3(this.spec, schema);
1808
1808
  const itemsSchema = schemaObj.items;
1809
1809
  if (!itemsSchema) {
1810
1810
  return [];
@@ -1916,7 +1916,7 @@ var SnippetEmitter = class {
1916
1916
  if (isRef5(schemaOrRef)) {
1917
1917
  return this.ref(schemaOrRef.$ref);
1918
1918
  }
1919
- const schema = resolveRef2(this.spec, schemaOrRef);
1919
+ const schema = resolveRef3(this.spec, schemaOrRef);
1920
1920
  if (schema.example !== void 0) {
1921
1921
  return schema.example;
1922
1922
  }
@@ -1981,7 +1981,7 @@ var TypeScriptSnippet = class {
1981
1981
  let payload = "{}";
1982
1982
  if (!isEmpty4(operation.requestBody)) {
1983
1983
  const contentTypes = Object.keys(operation.requestBody.content || {});
1984
- const schema = resolveRef3(
1984
+ const schema = resolveRef4(
1985
1985
  this.#spec,
1986
1986
  operation.requestBody.content[contentTypes[0]].schema
1987
1987
  );
@@ -2694,31 +2694,6 @@ function availablePaginationTypes(spec) {
2694
2694
  }
2695
2695
 
2696
2696
  // packages/typescript/src/lib/generate.ts
2697
- function security(spec) {
2698
- const security2 = spec.security || [];
2699
- const components = spec.components || {};
2700
- const securitySchemes = components.securitySchemes || {};
2701
- const paths = Object.values(spec.paths ?? {});
2702
- const options = securityToOptions2(spec, security2, securitySchemes);
2703
- for (const it of paths) {
2704
- for (const method of methods) {
2705
- const operation = it[method];
2706
- if (!operation) {
2707
- continue;
2708
- }
2709
- Object.assign(
2710
- options,
2711
- securityToOptions2(
2712
- spec,
2713
- operation.security || [],
2714
- securitySchemes,
2715
- "input"
2716
- )
2717
- );
2718
- }
2719
- }
2720
- return options;
2721
- }
2722
2697
  async function generate(openapi, settings) {
2723
2698
  const spec = toIR(
2724
2699
  {
@@ -2901,7 +2876,7 @@ ${utils_default}`
2901
2876
  },
2902
2877
  dependencies: {
2903
2878
  "fast-content-type-parse": "^3.0.0",
2904
- zod: "^3.25.76"
2879
+ zod: "^4.3.0"
2905
2880
  }
2906
2881
  },
2907
2882
  null,