@sdk-it/typescript 0.42.0 → 0.43.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 +127 -109
- package/dist/index.js.map +4 -4
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/emitters/interface.d.ts.map +1 -1
- package/dist/lib/generate.d.ts.map +1 -1
- package/dist/lib/pagination-emit.d.ts +3 -0
- package/dist/lib/pagination-emit.d.ts.map +1 -0
- package/dist/lib/sdk.d.ts.map +1 -1
- package/dist/lib/typescript-snippet.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -255,7 +255,7 @@ var ZodEmitter = class {
|
|
|
255
255
|
string(schema) {
|
|
256
256
|
let base = schema["x-zod-type"] === "coerce-string" ? "z.coerce.string()" : "z.string()";
|
|
257
257
|
if (schema.contentEncoding === "binary") {
|
|
258
|
-
base = "z.
|
|
258
|
+
base = "z.custom<Blob>()";
|
|
259
259
|
return base;
|
|
260
260
|
}
|
|
261
261
|
switch (schema.format) {
|
|
@@ -296,7 +296,7 @@ var ZodEmitter = class {
|
|
|
296
296
|
break;
|
|
297
297
|
case "byte":
|
|
298
298
|
case "binary":
|
|
299
|
-
base = "z.
|
|
299
|
+
base = "z.custom<Blob>()";
|
|
300
300
|
break;
|
|
301
301
|
case "int64":
|
|
302
302
|
base += " /* or z.bigint() if your app can handle it */";
|
|
@@ -402,6 +402,7 @@ function toZod(schema, required) {
|
|
|
402
402
|
|
|
403
403
|
// packages/typescript/src/lib/client.ts
|
|
404
404
|
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])" : ""}`;
|
|
405
406
|
const defaultHeaders = `{${spec.options.filter((value) => value.in === "header").map(
|
|
406
407
|
(value) => `'${value.name}': options['${value["x-optionName"] ?? value.name}']`
|
|
407
408
|
).join(",\n")}}`;
|
|
@@ -432,7 +433,12 @@ var client_default = (spec) => {
|
|
|
432
433
|
schema: `fetchType.describe('Custom fetch implementation. Defaults to globalThis.fetch.')`
|
|
433
434
|
},
|
|
434
435
|
baseUrl: {
|
|
435
|
-
schema:
|
|
436
|
+
schema: `${baseUrlSchema}.transform(async (baseUrl) => {
|
|
437
|
+
if (typeof baseUrl === 'function') {
|
|
438
|
+
return Promise.resolve(baseUrl());
|
|
439
|
+
}
|
|
440
|
+
return baseUrl;
|
|
441
|
+
}).describe('Base URL of the API server. Can be a string or a function that returns a string.')`
|
|
436
442
|
},
|
|
437
443
|
headers: {
|
|
438
444
|
schema: `z.record(z.string()).optional().describe('Default headers to include in all requests.')`
|
|
@@ -484,7 +490,7 @@ export class ${spec.name} {
|
|
|
484
490
|
async prepare<const E extends keyof typeof schemas>(
|
|
485
491
|
endpoint: E,
|
|
486
492
|
input: z.input<(typeof schemas)[E]['schema']>,
|
|
487
|
-
options?: { headers?: HeadersInit },
|
|
493
|
+
options?: { signal?: AbortSignal; headers?: HeadersInit },
|
|
488
494
|
) {
|
|
489
495
|
return prepare(this, endpoint, input, options);
|
|
490
496
|
}
|
|
@@ -565,7 +571,7 @@ export async function prepare<const E extends keyof typeof schemas>(
|
|
|
565
571
|
client: ${spec.name},
|
|
566
572
|
endpoint: E,
|
|
567
573
|
input: z.input<(typeof schemas)[E]['schema']>,
|
|
568
|
-
requestOptions?: { headers?: HeadersInit },
|
|
574
|
+
requestOptions?: { signal?: AbortSignal; headers?: HeadersInit },
|
|
569
575
|
): Promise<RequestConfig & {
|
|
570
576
|
parse: (response: Response) => ReturnType<typeof parse>;
|
|
571
577
|
}> {
|
|
@@ -586,6 +592,15 @@ export async function prepare<const E extends keyof typeof schemas>(
|
|
|
586
592
|
];
|
|
587
593
|
|
|
588
594
|
let config = route.toRequest(parsedInput as never);
|
|
595
|
+
if (requestOptions?.signal) {
|
|
596
|
+
config = {
|
|
597
|
+
...config,
|
|
598
|
+
init: {
|
|
599
|
+
...config.init,
|
|
600
|
+
signal: requestOptions.signal,
|
|
601
|
+
},
|
|
602
|
+
};
|
|
603
|
+
}
|
|
589
604
|
for (const interceptor of interceptors) {
|
|
590
605
|
if (interceptor.before) {
|
|
591
606
|
config = await interceptor.before(config);
|
|
@@ -599,7 +614,7 @@ export async function prepare<const E extends keyof typeof schemas>(
|
|
|
599
614
|
};
|
|
600
615
|
|
|
601
616
|
// packages/typescript/src/lib/emitters/interface.ts
|
|
602
|
-
import { followRef as followRef2, isRef as isRef2, parseRef as parseRef2, pascalcase as pascalcase2 } from "@sdk-it/core";
|
|
617
|
+
import { followRef as followRef2, isRef as isRef2, parseRef as parseRef2, pascalcase as pascalcase2, resolveRef } from "@sdk-it/core";
|
|
603
618
|
import { isPrimitiveSchema as isPrimitiveSchema2, sanitizeTag as sanitizeTag2 } from "@sdk-it/spec";
|
|
604
619
|
var TypeScriptEmitter = class {
|
|
605
620
|
#spec;
|
|
@@ -677,7 +692,23 @@ var TypeScriptEmitter = class {
|
|
|
677
692
|
return allOfTypes.length > 1 ? `${allOfTypes.join(" & ")}` : allOfTypes[0];
|
|
678
693
|
}
|
|
679
694
|
oneOf(schemas, required) {
|
|
680
|
-
const
|
|
695
|
+
const isBareString = (s) => {
|
|
696
|
+
const r = resolveRef(this.#spec, s);
|
|
697
|
+
return r.type === "string" && !r.enum && !r.const && !r.format;
|
|
698
|
+
};
|
|
699
|
+
const isStringLiteral = (s) => {
|
|
700
|
+
const r = resolveRef(this.#spec, s);
|
|
701
|
+
return Array.isArray(r.enum) && r.enum.every((v) => typeof v === "string") || typeof r.const === "string";
|
|
702
|
+
};
|
|
703
|
+
const hasStringLiteral = schemas.some(isStringLiteral);
|
|
704
|
+
const seen = /* @__PURE__ */ new Set();
|
|
705
|
+
const oneOfTypes = [];
|
|
706
|
+
for (const sub of schemas) {
|
|
707
|
+
const part = hasStringLiteral && isBareString(sub) ? "(string & {})" : this.handle(sub, true);
|
|
708
|
+
if (seen.has(part)) continue;
|
|
709
|
+
seen.add(part);
|
|
710
|
+
oneOfTypes.push(part);
|
|
711
|
+
}
|
|
681
712
|
return appendOptional2(
|
|
682
713
|
oneOfTypes.length > 1 ? `${oneOfTypes.join(" | ")}` : oneOfTypes[0],
|
|
683
714
|
required
|
|
@@ -769,7 +800,7 @@ function appendOptional2(type, isRequired) {
|
|
|
769
800
|
import { merge, template } from "lodash-es";
|
|
770
801
|
import { join } from "node:path";
|
|
771
802
|
import { camelcase as camelcase4, spinalcase as spinalcase2 } from "stringcase";
|
|
772
|
-
import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef, sortArray } from "@sdk-it/core";
|
|
803
|
+
import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef as resolveRef2, sortArray } from "@sdk-it/core";
|
|
773
804
|
import {
|
|
774
805
|
forEachOperation as forEachOperation3
|
|
775
806
|
} from "@sdk-it/spec";
|
|
@@ -789,6 +820,69 @@ import {
|
|
|
789
820
|
// packages/typescript/src/lib/import-utilities.ts
|
|
790
821
|
import { removeDuplicates } from "@sdk-it/core";
|
|
791
822
|
|
|
823
|
+
// packages/typescript/src/lib/pagination-emit.ts
|
|
824
|
+
function describe(p) {
|
|
825
|
+
switch (p.type) {
|
|
826
|
+
case "offset":
|
|
827
|
+
return {
|
|
828
|
+
className: "OffsetPagination",
|
|
829
|
+
items: p.items,
|
|
830
|
+
hasMore: p.hasMore,
|
|
831
|
+
statusCode: p.statusCode,
|
|
832
|
+
sameInputNames: p.limitParamName === "limit" && p.offsetParamName === "offset",
|
|
833
|
+
initialOverride: `limit: input.${p.limitParamName}, offset: input.${p.offsetParamName}`,
|
|
834
|
+
nextPageMapping: `${p.offsetParamName}: nextPageParams.offset, ${p.limitParamName}: nextPageParams.limit`
|
|
835
|
+
};
|
|
836
|
+
case "cursor":
|
|
837
|
+
return {
|
|
838
|
+
className: "CursorPagination",
|
|
839
|
+
items: p.items,
|
|
840
|
+
hasMore: p.hasMore,
|
|
841
|
+
statusCode: p.statusCode,
|
|
842
|
+
sameInputNames: p.cursorParamName === "cursor",
|
|
843
|
+
initialOverride: `cursor: input.${p.cursorParamName}`,
|
|
844
|
+
nextPageMapping: `${p.cursorParamName}: nextPageParams.cursor`
|
|
845
|
+
};
|
|
846
|
+
case "page":
|
|
847
|
+
return {
|
|
848
|
+
className: "Pagination",
|
|
849
|
+
items: p.items,
|
|
850
|
+
hasMore: p.hasMore,
|
|
851
|
+
statusCode: p.statusCode,
|
|
852
|
+
sameInputNames: p.pageNumberParamName === "page" && p.pageSizeParamName === "pageSize",
|
|
853
|
+
initialOverride: `page: input.${p.pageNumberParamName}, pageSize: input.${p.pageSizeParamName}`,
|
|
854
|
+
nextPageMapping: `${p.pageNumberParamName}: nextPageParams.page, ${p.pageSizeParamName}: nextPageParams.pageSize`
|
|
855
|
+
};
|
|
856
|
+
}
|
|
857
|
+
throw new Error(
|
|
858
|
+
`Unknown pagination type: ${p.type}`
|
|
859
|
+
);
|
|
860
|
+
}
|
|
861
|
+
function paginationOperation(pagination) {
|
|
862
|
+
const shape = describe(pagination);
|
|
863
|
+
const initialParams = shape.sameInputNames ? "input" : `{...input, ${shape.initialOverride}}`;
|
|
864
|
+
const nextPageParams = shape.sameInputNames ? "...nextPageParams" : shape.nextPageMapping;
|
|
865
|
+
return `{
|
|
866
|
+
const pagination = new ${shape.className}(${initialParams}, async (nextPageParams, requestOptions) => {
|
|
867
|
+
const dispatcher = new Dispatcher(options.interceptors, options.fetch);
|
|
868
|
+
const result = await dispatcher.send(
|
|
869
|
+
this.toRequest({...input, ${nextPageParams}}),
|
|
870
|
+
this.output,
|
|
871
|
+
requestOptions?.signal ?? options.signal,
|
|
872
|
+
);
|
|
873
|
+
if (result.status !== ${shape.statusCode}) { throw result; }
|
|
874
|
+
return {
|
|
875
|
+
data: result.data.${shape.items},
|
|
876
|
+
meta: {
|
|
877
|
+
hasMore: Boolean(result.data.${shape.hasMore}),
|
|
878
|
+
},
|
|
879
|
+
};
|
|
880
|
+
}, { signal: options.signal });
|
|
881
|
+
await pagination.getNextPage();
|
|
882
|
+
return pagination
|
|
883
|
+
}}`;
|
|
884
|
+
}
|
|
885
|
+
|
|
792
886
|
// packages/typescript/src/lib/status-map.ts
|
|
793
887
|
var status_map_default = {
|
|
794
888
|
"200": "Ok",
|
|
@@ -853,7 +947,7 @@ function toEndpoint(groupName, spec, specOperation, operation) {
|
|
|
853
947
|
signal?: AbortSignal;
|
|
854
948
|
interceptors: Interceptor[];
|
|
855
949
|
fetch: z.infer<typeof fetchType>;
|
|
856
|
-
})${specOperation["x-pagination"] ? paginationOperation(specOperation) : normalOperation()}`
|
|
950
|
+
})${specOperation["x-pagination"] ? paginationOperation(specOperation["x-pagination"]) : normalOperation()}`
|
|
857
951
|
);
|
|
858
952
|
}
|
|
859
953
|
return { schemas };
|
|
@@ -865,82 +959,6 @@ function normalOperation() {
|
|
|
865
959
|
},
|
|
866
960
|
}`;
|
|
867
961
|
}
|
|
868
|
-
function paginationOperation(operation) {
|
|
869
|
-
const pagination = operation["x-pagination"];
|
|
870
|
-
const data = `result.data`;
|
|
871
|
-
const returnValue = `pagination`;
|
|
872
|
-
if (pagination.type === "offset") {
|
|
873
|
-
const sameInputNames = pagination.limitParamName === "limit" && pagination.offsetParamName === "offset";
|
|
874
|
-
const initialParams = sameInputNames ? "input" : `{...input, limit: input.${pagination.limitParamName}, offset: input.${pagination.offsetParamName}}`;
|
|
875
|
-
const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.offsetParamName}: nextPageParams.offset, ${pagination.limitParamName}: nextPageParams.limit`;
|
|
876
|
-
const logic = `const pagination = new OffsetPagination(${initialParams}, async (nextPageParams) => {
|
|
877
|
-
const dispatcher = new Dispatcher(options.interceptors, options.fetch);
|
|
878
|
-
const result = await dispatcher.send(
|
|
879
|
-
this.toRequest({...input, ${nextPageParams}}),
|
|
880
|
-
this.output,
|
|
881
|
-
options.signal,
|
|
882
|
-
);
|
|
883
|
-
return {
|
|
884
|
-
data: ${data}.${pagination.items},
|
|
885
|
-
meta: {
|
|
886
|
-
hasMore: Boolean(${data}.${pagination.hasMore}),
|
|
887
|
-
},
|
|
888
|
-
};
|
|
889
|
-
});
|
|
890
|
-
await pagination.getNextPage();
|
|
891
|
-
return ${returnValue}
|
|
892
|
-
`;
|
|
893
|
-
return `{${logic}}}`;
|
|
894
|
-
}
|
|
895
|
-
if (pagination.type === "cursor") {
|
|
896
|
-
const sameInputNames = pagination.cursorParamName === "cursor";
|
|
897
|
-
const initialParams = sameInputNames ? "input" : `{...input, cursor: input.${pagination.cursorParamName}}`;
|
|
898
|
-
const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.cursorParamName}: nextPageParams.cursor`;
|
|
899
|
-
const logic = `
|
|
900
|
-
const pagination = new CursorPagination(${initialParams}, async (nextPageParams) => {
|
|
901
|
-
const dispatcher = new Dispatcher(options.interceptors, options.fetch);
|
|
902
|
-
const result = await dispatcher.send(
|
|
903
|
-
this.toRequest({...input, ${nextPageParams}}),
|
|
904
|
-
this.output,
|
|
905
|
-
options.signal,
|
|
906
|
-
);
|
|
907
|
-
return {
|
|
908
|
-
data: ${data}.${pagination.items},
|
|
909
|
-
meta: {
|
|
910
|
-
hasMore: Boolean(${data}.${pagination.hasMore}),
|
|
911
|
-
},
|
|
912
|
-
};
|
|
913
|
-
});
|
|
914
|
-
await pagination.getNextPage();
|
|
915
|
-
return ${returnValue}
|
|
916
|
-
`;
|
|
917
|
-
return `{${logic}}}`;
|
|
918
|
-
}
|
|
919
|
-
if (pagination.type === "page") {
|
|
920
|
-
const sameInputNames = pagination.pageNumberParamName === "page" && pagination.pageSizeParamName === "pageSize";
|
|
921
|
-
const initialParams = sameInputNames ? "input" : `{...input, page: input.${pagination.pageNumberParamName}, pageSize: input.${pagination.pageSizeParamName}}`;
|
|
922
|
-
const nextPageParams = sameInputNames ? "...nextPageParams" : `${pagination.pageNumberParamName}: nextPageParams.page, ${pagination.pageSizeParamName}: nextPageParams.pageSize`;
|
|
923
|
-
const logic = `
|
|
924
|
-
const pagination = new Pagination(${initialParams}, async (nextPageParams) => {
|
|
925
|
-
const dispatcher = new Dispatcher(options.interceptors, options.fetch);
|
|
926
|
-
const result = await dispatcher.send(
|
|
927
|
-
this.toRequest({...input, ${nextPageParams}}),
|
|
928
|
-
this.output,
|
|
929
|
-
options.signal,
|
|
930
|
-
);
|
|
931
|
-
return {
|
|
932
|
-
data: ${data}.${pagination.items},
|
|
933
|
-
meta: {
|
|
934
|
-
hasMore: Boolean(${data}.${pagination.hasMore}),
|
|
935
|
-
},
|
|
936
|
-
};
|
|
937
|
-
});
|
|
938
|
-
return ${returnValue}
|
|
939
|
-
`;
|
|
940
|
-
return `{${logic}}}`;
|
|
941
|
-
}
|
|
942
|
-
return normalOperation();
|
|
943
|
-
}
|
|
944
962
|
function toHttpOutput(spec, operationName, status, response, withGenerics = true) {
|
|
945
963
|
const typeScriptDeserialzer = new TypeScriptEmitter(spec);
|
|
946
964
|
const interfaceName = pascalcase3(sanitizeTag3(response["x-response-name"]));
|
|
@@ -1061,7 +1079,7 @@ var endpoints_default = "type DispatchReturn<E extends keyof typeof schemas> = A
|
|
|
1061
1079
|
|
|
1062
1080
|
// packages/typescript/src/lib/generator.ts
|
|
1063
1081
|
function coearceRequestInput(spec, operation, type) {
|
|
1064
|
-
let objectSchema =
|
|
1082
|
+
let objectSchema = resolveRef2(
|
|
1065
1083
|
spec,
|
|
1066
1084
|
operation.requestBody.content[type].schema
|
|
1067
1085
|
);
|
|
@@ -1310,7 +1328,7 @@ function operationSchema(ir, operation, type) {
|
|
|
1310
1328
|
}
|
|
1311
1329
|
|
|
1312
1330
|
// packages/typescript/src/lib/http/dispatcher.txt
|
|
1313
|
-
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.
|
|
1331
|
+
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";
|
|
1314
1332
|
|
|
1315
1333
|
// packages/typescript/src/lib/http/interceptors.txt
|
|
1316
1334
|
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";
|
|
@@ -1331,13 +1349,13 @@ var response_default = "export class APIResponse<Body = unknown, Status extends
|
|
|
1331
1349
|
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';
|
|
1332
1350
|
|
|
1333
1351
|
// packages/typescript/src/lib/paginations/cursor-pagination.txt
|
|
1334
|
-
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 PaginationResult<T, M extends CursorMetadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<T, M extends CursorMetadata> = (\n input: CursorPaginationParams,\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\n constructor(\n initialParams: PartialNullable<CursorPaginationParams>,\n fetchFn: FetchFn<T, M>,\n ) {\n this.#fetchFn = fetchFn;\n this.#params = {\n cursor: initialParams.cursor ?? undefined,\n };\n }\n\n async getNextPage() {\n const result = await this.#fetchFn(this.#params);\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() {\n if (!this.#currentPage) {\n yield await this.getNextPage();\n }\n\n while (this.hasMore) {\n yield await this.getNextPage();\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";
|
|
1352
|
+
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";
|
|
1335
1353
|
|
|
1336
1354
|
// packages/typescript/src/lib/paginations/offset-pagination.txt
|
|
1337
|
-
var offset_pagination_default = "type OffsetPaginationParams = {\n offset: number;\n limit: number;\n};\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationResult<T, M extends Metadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<T, M extends Metadata> = (\n input: OffsetPaginationParams,\n) => Promise<PaginationResult<T, M>>;\n\n/**\n * @experimental\n */\nexport class OffsetPagination<T, M extends Metadata> {\n #meta: PaginationResult<T, M>['meta'] | null = null;\n #params: OffsetPaginationParams;\n #currentPage: Page<T> | null = null;\n readonly #fetchFn: FetchFn<T, M>;\n\n constructor(\n initialParams: Partial<OffsetPaginationParams>,\n fetchFn: FetchFn<T, M>,\n ) {\n this.#fetchFn = fetchFn;\n this.#params = {\n limit: initialParams.limit ?? 0,\n offset: initialParams.offset ?? 0,\n };\n }\n\n async getNextPage() {\n const result = await this.#fetchFn(this.#params);\n this.#currentPage = new Page(result.data);\n this.#meta = result.meta;\n this.#params = {\n ...this.#params,\n offset: this.#params.offset + this.#params.limit,\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() {\n if (!this.#currentPage) {\n yield await this.getNextPage();\n }\n\n while (this.hasMore) {\n yield await this.getNextPage();\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 reset(params?: Partial<OffsetPaginationParams>) {\n this.#meta = null;\n this.#currentPage = null;\n if (params) {\n this.#params = { ...this.#params, ...params };\n } else {\n this.#params.offset = 0;\n }\n return this;\n }\n}\n\nclass Page<T> {\n data: T[];\n constructor(data: T[]) {\n this.data = data;\n }\n}\n";
|
|
1355
|
+
var offset_pagination_default = "type OffsetPaginationParams = {\n offset: number;\n limit: number;\n};\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationRequestOptions = {\n signal?: AbortSignal;\n};\n\ntype PaginationResult<T, M extends Metadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<T, M extends Metadata> = (\n input: OffsetPaginationParams,\n requestOptions?: PaginationRequestOptions,\n) => Promise<PaginationResult<T, M>>;\n\n/**\n * @experimental\n */\nexport class OffsetPagination<T, M extends Metadata> {\n #meta: PaginationResult<T, M>['meta'] | null = null;\n #params: OffsetPaginationParams;\n #currentPage: Page<T> | null = null;\n readonly #fetchFn: FetchFn<T, M>;\n readonly #requestOptions: PaginationRequestOptions;\n\n constructor(\n initialParams: Partial<OffsetPaginationParams>,\n fetchFn: FetchFn<T, M>,\n requestOptions: PaginationRequestOptions = {},\n ) {\n this.#fetchFn = fetchFn;\n this.#requestOptions = requestOptions;\n this.#params = {\n limit: initialParams.limit ?? 0,\n offset: initialParams.offset ?? 0,\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 offset: this.#params.offset + this.#params.limit,\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 reset(params?: Partial<OffsetPaginationParams>) {\n this.#meta = null;\n this.#currentPage = null;\n if (params) {\n this.#params = { ...this.#params, ...params };\n } else {\n this.#params.offset = 0;\n }\n return this;\n }\n}\n\nclass Page<T> {\n data: T[];\n constructor(data: T[]) {\n this.data = data;\n }\n}\n";
|
|
1338
1356
|
|
|
1339
1357
|
// packages/typescript/src/lib/paginations/page-pagination.txt
|
|
1340
|
-
var page_pagination_default = "type InferPage<T> = T extends Page<infer U> ? U : never;\ntype PaginationParams<P extends number | bigint, S extends number | bigint> = {\n page?: P;\n pageSize?: S;\n};\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationResult<T, M extends Metadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<\n T,\n M extends Metadata,\n P extends number | bigint,\n S extends number | bigint,\n> = (input: Partial<PaginationParams<P, S
|
|
1358
|
+
var page_pagination_default = "type InferPage<T> = T extends Page<infer U> ? U : never;\ntype PaginationParams<P extends number | bigint, S extends number | bigint> = {\n page?: P;\n pageSize?: S;\n};\n\ninterface Metadata {\n hasMore?: boolean;\n}\n\ntype PaginationRequestOptions = {\n signal?: AbortSignal;\n};\n\ntype PaginationResult<T, M extends Metadata> = {\n data: T[];\n meta: M;\n};\n\ntype FetchFn<\n T,\n M extends Metadata,\n P extends number | bigint,\n S extends number | bigint,\n> = (\n input: Partial<PaginationParams<P, S>>,\n requestOptions?: PaginationRequestOptions,\n) => Promise<PaginationResult<T, M>>;\n\n/**\n * @experimental\n */\nexport class Pagination<\n T,\n M extends Metadata,\n P extends number | bigint,\n S extends number | bigint,\n> {\n #meta: PaginationResult<T, M>['meta'] | null = null;\n #params: PaginationParams<P, S>;\n #currentPage: Page<T> | null = null;\n readonly #fetchFn: FetchFn<T, M, P, S>;\n readonly #requestOptions: PaginationRequestOptions;\n\n constructor(\n initialParams: Partial<PaginationParams<P, S>>,\n fetchFn: FetchFn<T, M, P, S>,\n requestOptions: PaginationRequestOptions = {},\n ) {\n this.#fetchFn = fetchFn;\n this.#requestOptions = requestOptions;\n this.#params = { ...initialParams, page: initialParams.page };\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 page: (((this.#params.page as number) || 0) + 1) as never,\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";
|
|
1341
1359
|
|
|
1342
1360
|
// packages/typescript/src/lib/readme/readme.ts
|
|
1343
1361
|
import { isEmpty as isEmpty3 } from "@sdk-it/core";
|
|
@@ -1752,7 +1770,7 @@ function expandServerUrls(servers) {
|
|
|
1752
1770
|
|
|
1753
1771
|
// packages/typescript/src/lib/typescript-snippet.ts
|
|
1754
1772
|
import { camelcase as camelcase5, spinalcase as spinalcase3 } from "stringcase";
|
|
1755
|
-
import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as
|
|
1773
|
+
import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as resolveRef4 } from "@sdk-it/core";
|
|
1756
1774
|
import "@sdk-it/readme";
|
|
1757
1775
|
import {
|
|
1758
1776
|
forEachOperation as forEachOperation5,
|
|
@@ -1761,7 +1779,7 @@ import {
|
|
|
1761
1779
|
} from "@sdk-it/spec";
|
|
1762
1780
|
|
|
1763
1781
|
// packages/typescript/src/lib/emitters/snippet.ts
|
|
1764
|
-
import { followRef as followRef5, isRef as isRef5, resolveRef as
|
|
1782
|
+
import { followRef as followRef5, isRef as isRef5, resolveRef as resolveRef3 } from "@sdk-it/core";
|
|
1765
1783
|
var SnippetEmitter = class {
|
|
1766
1784
|
spec;
|
|
1767
1785
|
generatedRefs = /* @__PURE__ */ new Set();
|
|
@@ -1770,12 +1788,12 @@ var SnippetEmitter = class {
|
|
|
1770
1788
|
this.spec = spec;
|
|
1771
1789
|
}
|
|
1772
1790
|
object(schema) {
|
|
1773
|
-
const schemaObj =
|
|
1791
|
+
const schemaObj = resolveRef3(this.spec, schema);
|
|
1774
1792
|
const result = {};
|
|
1775
1793
|
const properties = schemaObj.properties || {};
|
|
1776
1794
|
for (const [propName, propSchema] of Object.entries(properties)) {
|
|
1777
1795
|
const isRequired = (schemaObj.required ?? []).includes(propName);
|
|
1778
|
-
const resolvedProp =
|
|
1796
|
+
const resolvedProp = resolveRef3(this.spec, propSchema);
|
|
1779
1797
|
if (isRequired || resolvedProp.example !== void 0 || resolvedProp.default !== void 0) {
|
|
1780
1798
|
result[propName] = this.handle(propSchema);
|
|
1781
1799
|
}
|
|
@@ -1788,7 +1806,7 @@ var SnippetEmitter = class {
|
|
|
1788
1806
|
return result;
|
|
1789
1807
|
}
|
|
1790
1808
|
array(schema) {
|
|
1791
|
-
const schemaObj =
|
|
1809
|
+
const schemaObj = resolveRef3(this.spec, schema);
|
|
1792
1810
|
const itemsSchema = schemaObj.items;
|
|
1793
1811
|
if (!itemsSchema) {
|
|
1794
1812
|
return [];
|
|
@@ -1900,7 +1918,7 @@ var SnippetEmitter = class {
|
|
|
1900
1918
|
if (isRef5(schemaOrRef)) {
|
|
1901
1919
|
return this.ref(schemaOrRef.$ref);
|
|
1902
1920
|
}
|
|
1903
|
-
const schema =
|
|
1921
|
+
const schema = resolveRef3(this.spec, schemaOrRef);
|
|
1904
1922
|
if (schema.example !== void 0) {
|
|
1905
1923
|
return schema.example;
|
|
1906
1924
|
}
|
|
@@ -1965,7 +1983,7 @@ var TypeScriptSnippet = class {
|
|
|
1965
1983
|
let payload = "{}";
|
|
1966
1984
|
if (!isEmpty4(operation.requestBody)) {
|
|
1967
1985
|
const contentTypes = Object.keys(operation.requestBody.content || {});
|
|
1968
|
-
const schema =
|
|
1986
|
+
const schema = resolveRef4(
|
|
1969
1987
|
this.#spec,
|
|
1970
1988
|
operation.requestBody.content[contentTypes[0]].schema
|
|
1971
1989
|
);
|
|
@@ -2035,22 +2053,25 @@ var TypeScriptSnippet = class {
|
|
|
2035
2053
|
switch (pagination.type) {
|
|
2036
2054
|
case "page":
|
|
2037
2055
|
return {
|
|
2038
|
-
content: `const
|
|
2039
|
-
|
|
2056
|
+
content: `const controller = new AbortController();
|
|
2057
|
+
const result = await ${camelcase5(this.#clientName)}.request('${entry.method.toUpperCase()} ${entry.path}', ${payload}, { signal: controller.signal });`,
|
|
2058
|
+
footer: `for await (const page of result.iter({ signal: controller.signal })) {
|
|
2040
2059
|
console.log(page);
|
|
2041
2060
|
}`
|
|
2042
2061
|
};
|
|
2043
2062
|
case "offset":
|
|
2044
2063
|
return {
|
|
2045
|
-
content: `const
|
|
2046
|
-
|
|
2064
|
+
content: `const controller = new AbortController();
|
|
2065
|
+
const result = await ${camelcase5(this.#clientName)}.request('${entry.method.toUpperCase()} ${entry.path}', ${payload}, { signal: controller.signal });`,
|
|
2066
|
+
footer: `for await (const page of result.iter({ signal: controller.signal })) {
|
|
2047
2067
|
console.log(page);
|
|
2048
2068
|
}`
|
|
2049
2069
|
};
|
|
2050
2070
|
case "cursor":
|
|
2051
2071
|
return {
|
|
2052
|
-
content: `const
|
|
2053
|
-
|
|
2072
|
+
content: `const controller = new AbortController();
|
|
2073
|
+
const result = await ${camelcase5(this.#clientName)}.request('${entry.method.toUpperCase()} ${entry.path}', ${payload}, { signal: controller.signal });`,
|
|
2074
|
+
footer: `for await (const page of result.iter({ signal: controller.signal })) {
|
|
2054
2075
|
console.log(page);
|
|
2055
2076
|
}`
|
|
2056
2077
|
};
|
|
@@ -2156,7 +2177,7 @@ ${client.use}`;
|
|
|
2156
2177
|
);
|
|
2157
2178
|
if (hasServers) {
|
|
2158
2179
|
sections.push(
|
|
2159
|
-
"| `baseUrl` | `string` | No | API base URL (default: `" + baseUrl + "`) |"
|
|
2180
|
+
"| `baseUrl` | `string | (() => string | Promise<string>)` | No | API base URL (default: `" + baseUrl + "`) |"
|
|
2160
2181
|
);
|
|
2161
2182
|
}
|
|
2162
2183
|
for (const authOption of authOptions) {
|
|
@@ -2230,10 +2251,10 @@ ${client.use}`;
|
|
|
2230
2251
|
"",
|
|
2231
2252
|
"// Check if more pages exist",
|
|
2232
2253
|
"if (result.hasMore) {",
|
|
2233
|
-
" await result.getNextPage();",
|
|
2254
|
+
" await result.getNextPage({ signal: controller.signal });",
|
|
2234
2255
|
"}",
|
|
2235
2256
|
"",
|
|
2236
|
-
"// Or iterate through all pages
|
|
2257
|
+
"// Or iterate through all pages with cancellable page fetches",
|
|
2237
2258
|
paginationExample.footer
|
|
2238
2259
|
])
|
|
2239
2260
|
);
|
|
@@ -2897,12 +2918,9 @@ ${utils_default}`
|
|
|
2897
2918
|
skipLibCheck: true,
|
|
2898
2919
|
skipDefaultLibCheck: true,
|
|
2899
2920
|
target: "ESNext",
|
|
2900
|
-
module: "ESNext",
|
|
2901
2921
|
noEmit: true,
|
|
2902
|
-
strict: true,
|
|
2903
2922
|
allowImportingTsExtensions: true,
|
|
2904
2923
|
verbatimModuleSyntax: true,
|
|
2905
|
-
baseUrl: ".",
|
|
2906
2924
|
moduleResolution: "bundler"
|
|
2907
2925
|
},
|
|
2908
2926
|
include: ["**/*.ts"]
|