@sdk-it/typescript 0.38.0 → 0.40.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 +168 -63
- package/dist/index.js.map +3 -3
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/emitters/zod.d.ts.map +1 -1
- package/dist/lib/generate.d.ts +3 -1
- package/dist/lib/generate.d.ts.map +1 -1
- package/dist/lib/generator.d.ts.map +1 -1
- package/dist/lib/options.d.ts +1 -0
- package/dist/lib/options.d.ts.map +1 -1
- package/dist/lib/sdk.d.ts +1 -1
- package/dist/lib/sdk.d.ts.map +1 -1
- package/dist/lib/server-urls.d.ts +3 -0
- package/dist/lib/server-urls.d.ts.map +1 -0
- package/dist/lib/status-map.d.ts.map +1 -1
- package/dist/lib/typescript-snippet.d.ts.map +1 -1
- package/package.json +4 -4
- package/dist/connect.d.ts +0 -1
- package/dist/connect.d.ts.map +0 -1
- package/dist/global.d.js +0 -1
- package/dist/global.d.js.map +0 -7
- package/dist/lib/connect.d.ts +0 -162
- package/dist/lib/connect.d.ts.map +0 -1
- package/dist/lib/readme-generator.d.ts +0 -8
- package/dist/lib/readme-generator.d.ts.map +0 -1
- package/dist/lib/statusMap.d.ts +0 -2
- package/dist/lib/statusMap.d.ts.map +0 -1
- package/dist/lib/utils.d.ts +0 -17
- package/dist/lib/utils.d.ts.map +0 -1
- package/dist/lib/watcher.d.ts +0 -2
- package/dist/lib/watcher.d.ts.map +0 -1
- package/dist/src/index.js +0 -5
- package/dist/src/index.js.map +0 -7
- package/dist/src/lib/agent/ai-sdk.js +0 -60
- package/dist/src/lib/agent/ai-sdk.js.map +0 -7
- package/dist/src/lib/agent/openai-agents.js +0 -42
- package/dist/src/lib/agent/openai-agents.js.map +0 -7
- package/dist/src/lib/client.js +0 -152
- package/dist/src/lib/client.js.map +0 -7
- package/dist/src/lib/emitters/interface.js +0 -169
- package/dist/src/lib/emitters/interface.js.map +0 -7
- package/dist/src/lib/emitters/snippet.js +0 -191
- package/dist/src/lib/emitters/snippet.js.map +0 -7
- package/dist/src/lib/emitters/zod.js +0 -271
- package/dist/src/lib/emitters/zod.js.map +0 -7
- package/dist/src/lib/generate.js +0 -382
- package/dist/src/lib/generate.js.map +0 -7
- package/dist/src/lib/generator.js +0 -268
- package/dist/src/lib/generator.js.map +0 -7
- package/dist/src/lib/import-utilities.js +0 -56
- package/dist/src/lib/import-utilities.js.map +0 -7
- package/dist/src/lib/options.js +0 -3
- package/dist/src/lib/options.js.map +0 -7
- package/dist/src/lib/readme/prop.emitter.js +0 -283
- package/dist/src/lib/readme/prop.emitter.js.map +0 -7
- package/dist/src/lib/readme/readme.js +0 -105
- package/dist/src/lib/readme/readme.js.map +0 -7
- package/dist/src/lib/sdk.js +0 -236
- package/dist/src/lib/sdk.js.map +0 -7
- package/dist/src/lib/status-map.js +0 -28
- package/dist/src/lib/status-map.js.map +0 -7
- package/dist/src/lib/style.js +0 -1
- package/dist/src/lib/style.js.map +0 -7
- package/dist/src/lib/typescript-snippet.js +0 -738
- package/dist/src/lib/typescript-snippet.js.map +0 -7
package/dist/index.js
CHANGED
|
@@ -172,8 +172,10 @@ var ZodEmitter = class {
|
|
|
172
172
|
*/
|
|
173
173
|
normal(type, schema, required = false, nullable = false) {
|
|
174
174
|
switch (type) {
|
|
175
|
-
case "string":
|
|
176
|
-
|
|
175
|
+
case "string": {
|
|
176
|
+
const defaultVal = schema.format === "date" && schema.default ? `new Date(${JSON.stringify(schema.default)})` : JSON.stringify(schema.default);
|
|
177
|
+
return `${this.string(schema)}${this.#suffixes(defaultVal, required, nullable)}`;
|
|
178
|
+
}
|
|
177
179
|
case "number":
|
|
178
180
|
case "integer": {
|
|
179
181
|
const { base, defaultValue } = this.#number(schema);
|
|
@@ -415,17 +417,20 @@ var client_default = (spec) => {
|
|
|
415
417
|
token = await Promise.resolve(token());
|
|
416
418
|
}
|
|
417
419
|
return \`Bearer \${token}\`;
|
|
418
|
-
})`
|
|
420
|
+
}).describe('Bearer token for authentication. Can be a string or a function that returns a string.')`
|
|
419
421
|
}
|
|
420
422
|
} : {},
|
|
421
423
|
fetch: {
|
|
422
|
-
schema:
|
|
424
|
+
schema: `fetchType.describe('Custom fetch implementation. Defaults to globalThis.fetch.')`
|
|
423
425
|
},
|
|
424
426
|
baseUrl: {
|
|
425
|
-
schema: spec.servers.length ? `z.enum(servers).default(servers[0])` :
|
|
427
|
+
schema: spec.servers.length ? `z.enum(servers).default(servers[0]).describe('Base URL of the API server.')` : `z.string().describe('Base URL of the API server.')`
|
|
426
428
|
},
|
|
427
429
|
headers: {
|
|
428
|
-
schema:
|
|
430
|
+
schema: `z.record(z.string()).optional().describe('Default headers to include in all requests.')`
|
|
431
|
+
},
|
|
432
|
+
skipValidation: {
|
|
433
|
+
schema: `z.boolean().optional().describe('Skip request input validation. Client options and TypeScript types still enforce correct usage.')`
|
|
429
434
|
}
|
|
430
435
|
};
|
|
431
436
|
return `import z from 'zod';
|
|
@@ -453,6 +458,7 @@ export class ${spec.name} {
|
|
|
453
458
|
this.options = options;
|
|
454
459
|
}
|
|
455
460
|
|
|
461
|
+
/** Sends a request and returns the unwrapped response data. Delegates to the standalone {@link request} function. */
|
|
456
462
|
async request<const E extends keyof typeof schemas>(
|
|
457
463
|
endpoint: E,
|
|
458
464
|
input: z.input<(typeof schemas)[E]['schema']>,
|
|
@@ -466,32 +472,13 @@ export class ${spec.name} {
|
|
|
466
472
|
});
|
|
467
473
|
}
|
|
468
474
|
|
|
475
|
+
/** Builds a ready-to-send request without sending it. Delegates to the standalone {@link prepare} function. */
|
|
469
476
|
async prepare<const E extends keyof typeof schemas>(
|
|
470
477
|
endpoint: E,
|
|
471
478
|
input: z.input<(typeof schemas)[E]['schema']>,
|
|
472
479
|
options?: { headers?: HeadersInit },
|
|
473
|
-
)
|
|
474
|
-
|
|
475
|
-
}> {
|
|
476
|
-
const clientOptions = await optionsSchema.parseAsync(this.options);
|
|
477
|
-
const route = schemas[endpoint];
|
|
478
|
-
const interceptors = [
|
|
479
|
-
createHeadersInterceptor(
|
|
480
|
-
await this.defaultHeaders(),
|
|
481
|
-
options?.headers ?? {},
|
|
482
|
-
),
|
|
483
|
-
createBaseUrlInterceptor(clientOptions.baseUrl),
|
|
484
|
-
];
|
|
485
|
-
const parsedInput = parseInput(route.schema, input);
|
|
486
|
-
|
|
487
|
-
let config = route.toRequest(parsedInput as never);
|
|
488
|
-
for (const interceptor of interceptors) {
|
|
489
|
-
if (interceptor.before) {
|
|
490
|
-
config = await interceptor.before(config);
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
const prepared = { ...config, parse: (response: Response) => parse(route.output, response, (d) => d) as never };
|
|
494
|
-
return prepared as any;
|
|
480
|
+
) {
|
|
481
|
+
return prepare(this, endpoint, input, options);
|
|
495
482
|
}
|
|
496
483
|
|
|
497
484
|
async defaultHeaders() {
|
|
@@ -516,34 +503,89 @@ export class ${spec.name} {
|
|
|
516
503
|
|
|
517
504
|
}
|
|
518
505
|
|
|
506
|
+
/**
|
|
507
|
+
* Sends a validated request using the client's configuration and returns the parsed response.
|
|
508
|
+
* Merges the client's default inputs and headers before sending.
|
|
509
|
+
* Throws \`APIError\` on non-ok responses.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* \`\`\`ts
|
|
513
|
+
* const result = await request(client, 'GET /users', { limit: 10 });
|
|
514
|
+
* \`\`\`
|
|
515
|
+
*/
|
|
519
516
|
export async function request<const E extends keyof typeof schemas>(
|
|
520
517
|
client: ${spec.name},
|
|
521
518
|
endpoint: E,
|
|
522
519
|
input: z.input<(typeof schemas)[E]['schema']>,
|
|
523
|
-
|
|
520
|
+
requestOptions?: { signal?: AbortSignal; headers?: HeadersInit },
|
|
524
521
|
): Promise<Awaited<ReturnType<(typeof schemas)[E]['dispatch']>>> {
|
|
525
522
|
const route = schemas[endpoint];
|
|
523
|
+
const options = await optionsSchema.parseAsync(client.options);
|
|
526
524
|
const withDefaultInputs = Object.assign(
|
|
527
525
|
{},
|
|
528
|
-
|
|
526
|
+
${defaultInputs},
|
|
529
527
|
input,
|
|
530
528
|
);
|
|
531
|
-
const parsedInput = parseInput(route.schema, withDefaultInputs);
|
|
532
|
-
const clientOptions = await optionsSchema.parseAsync(client.options);
|
|
529
|
+
const parsedInput = options.skipValidation ? withDefaultInputs : parseInput(route.schema, withDefaultInputs);
|
|
533
530
|
const result = await route.dispatch(parsedInput as never, {
|
|
534
|
-
fetch:
|
|
531
|
+
fetch: options.fetch,
|
|
535
532
|
interceptors: [
|
|
536
533
|
createHeadersInterceptor(
|
|
537
|
-
|
|
538
|
-
|
|
534
|
+
{ ...${defaultHeaders}, ...options.headers },
|
|
535
|
+
requestOptions?.headers ?? {},
|
|
539
536
|
),
|
|
540
|
-
createBaseUrlInterceptor(
|
|
537
|
+
createBaseUrlInterceptor(options.baseUrl),
|
|
541
538
|
],
|
|
542
|
-
signal:
|
|
539
|
+
signal: requestOptions?.signal,
|
|
543
540
|
});
|
|
544
541
|
return result as Awaited<ReturnType<(typeof schemas)[E]['dispatch']>>;
|
|
545
542
|
}
|
|
546
543
|
|
|
544
|
+
/**
|
|
545
|
+
* Builds a validated \`RequestConfig\` (url + init) with a \`parse\` function attached, without sending.
|
|
546
|
+
* Use when you need control over the fetch call \u2014 framework integration (Next.js, SvelteKit),
|
|
547
|
+
* custom retry/logging, request batching, or testing.
|
|
548
|
+
*
|
|
549
|
+
* @example
|
|
550
|
+
* \`\`\`ts
|
|
551
|
+
* const { url, init, parse } = await prepare(client, 'GET /users', { limit: 10 });
|
|
552
|
+
* const response = await fetch(new Request(url, init));
|
|
553
|
+
* const result = await parse(response);
|
|
554
|
+
* \`\`\`
|
|
555
|
+
*/
|
|
556
|
+
export async function prepare<const E extends keyof typeof schemas>(
|
|
557
|
+
client: ${spec.name},
|
|
558
|
+
endpoint: E,
|
|
559
|
+
input: z.input<(typeof schemas)[E]['schema']>,
|
|
560
|
+
requestOptions?: { headers?: HeadersInit },
|
|
561
|
+
): Promise<RequestConfig & {
|
|
562
|
+
parse: (response: Response) => ReturnType<typeof parse>;
|
|
563
|
+
}> {
|
|
564
|
+
const route = schemas[endpoint];
|
|
565
|
+
const options = await optionsSchema.parseAsync(client.options);
|
|
566
|
+
const withDefaultInputs = Object.assign(
|
|
567
|
+
{},
|
|
568
|
+
${defaultInputs},
|
|
569
|
+
input,
|
|
570
|
+
);
|
|
571
|
+
const parsedInput = options.skipValidation ? withDefaultInputs : parseInput(route.schema, withDefaultInputs);
|
|
572
|
+
const interceptors = [
|
|
573
|
+
createHeadersInterceptor(
|
|
574
|
+
{ ...${defaultHeaders}, ...options.headers },
|
|
575
|
+
requestOptions?.headers ?? {},
|
|
576
|
+
),
|
|
577
|
+
createBaseUrlInterceptor(options.baseUrl),
|
|
578
|
+
];
|
|
579
|
+
|
|
580
|
+
let config = route.toRequest(parsedInput as never);
|
|
581
|
+
for (const interceptor of interceptors) {
|
|
582
|
+
if (interceptor.before) {
|
|
583
|
+
config = await interceptor.before(config);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
return { ...config, parse: (response: Response) => parse(route.output as never, response, (d) => d) as never } as any;
|
|
587
|
+
}
|
|
588
|
+
|
|
547
589
|
|
|
548
590
|
`;
|
|
549
591
|
};
|
|
@@ -719,7 +761,7 @@ function appendOptional2(type, isRequired) {
|
|
|
719
761
|
import { merge, template } from "lodash-es";
|
|
720
762
|
import { join } from "node:path";
|
|
721
763
|
import { camelcase as camelcase4, spinalcase as spinalcase2 } from "stringcase";
|
|
722
|
-
import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef } from "@sdk-it/core";
|
|
764
|
+
import { followRef as followRef3, isEmpty as isEmpty2, isRef as isRef3, resolveRef, sortArray } from "@sdk-it/core";
|
|
723
765
|
import {
|
|
724
766
|
forEachOperation as forEachOperation3
|
|
725
767
|
} from "@sdk-it/spec";
|
|
@@ -728,6 +770,8 @@ import {
|
|
|
728
770
|
import { camelcase as camelcase3 } from "stringcase";
|
|
729
771
|
import { isEmpty, pascalcase as pascalcase3 } from "@sdk-it/core";
|
|
730
772
|
import {
|
|
773
|
+
isBinaryContentType,
|
|
774
|
+
isSseContentType,
|
|
731
775
|
isStreamingContentType,
|
|
732
776
|
isTextContentType,
|
|
733
777
|
parseJsonContentType,
|
|
@@ -754,6 +798,7 @@ var status_map_default = {
|
|
|
754
798
|
"412": "PreconditionFailed",
|
|
755
799
|
"413": "PayloadTooLarge",
|
|
756
800
|
"410": "Gone",
|
|
801
|
+
"415": "UnsupportedMediaType",
|
|
757
802
|
"422": "UnprocessableEntity",
|
|
758
803
|
"429": "TooManyRequests",
|
|
759
804
|
"500": "InternalServerError",
|
|
@@ -928,16 +973,31 @@ function fromContentType(spec, typeScriptDeserialzer, response) {
|
|
|
928
973
|
if ((response.headers ?? {})["Transfer-Encoding"]) {
|
|
929
974
|
return streamedOutput();
|
|
930
975
|
}
|
|
976
|
+
const hasContentDisposition = hasHeader(response, "Content-Disposition");
|
|
931
977
|
for (const type in response.content) {
|
|
932
|
-
|
|
978
|
+
const isStreaming = isStreamingContentType(type);
|
|
979
|
+
const isBinary = isBinaryContentType(type) || isStreaming && hasContentDisposition;
|
|
980
|
+
if (isStreaming && !hasContentDisposition) {
|
|
933
981
|
return streamedOutput();
|
|
934
982
|
}
|
|
983
|
+
if (isBinary) {
|
|
984
|
+
return {
|
|
985
|
+
parser: "buffered",
|
|
986
|
+
responseSchema: response.content[type].schema ? typeScriptDeserialzer.handle(response.content[type].schema, true) : "Blob"
|
|
987
|
+
};
|
|
988
|
+
}
|
|
935
989
|
if (parseJsonContentType(type)) {
|
|
936
990
|
return {
|
|
937
991
|
parser: "buffered",
|
|
938
992
|
responseSchema: response.content[type].schema ? typeScriptDeserialzer.handle(response.content[type].schema, true) : "void"
|
|
939
993
|
};
|
|
940
994
|
}
|
|
995
|
+
if (isSseContentType(type)) {
|
|
996
|
+
return {
|
|
997
|
+
parser: "sse",
|
|
998
|
+
responseSchema: "SSEListener"
|
|
999
|
+
};
|
|
1000
|
+
}
|
|
941
1001
|
if (isTextContentType(type)) {
|
|
942
1002
|
return {
|
|
943
1003
|
parser: "buffered",
|
|
@@ -947,6 +1007,11 @@ function fromContentType(spec, typeScriptDeserialzer, response) {
|
|
|
947
1007
|
}
|
|
948
1008
|
return streamedOutput();
|
|
949
1009
|
}
|
|
1010
|
+
function hasHeader(response, name) {
|
|
1011
|
+
const headers = response.headers ?? {};
|
|
1012
|
+
const target = name.toLowerCase();
|
|
1013
|
+
return Object.keys(headers).some((key) => key.toLowerCase() === target);
|
|
1014
|
+
}
|
|
950
1015
|
function streamedOutput() {
|
|
951
1016
|
return {
|
|
952
1017
|
parser: "chunked",
|
|
@@ -1108,6 +1173,7 @@ ${allSchemas.map((it) => it.use).join(",\n")}
|
|
|
1108
1173
|
`import * as outputs from '${config.makeImport("../outputs/index")}';`,
|
|
1109
1174
|
`import { toRequest, json, urlencoded, empty, formdata, type HeadersInit } from '${config.makeImport("../http/request")}';`,
|
|
1110
1175
|
`import { chunked, buffered } from "${config.makeImport("../http/parse-response")}";`,
|
|
1176
|
+
`import { sse } from "${config.makeImport("../http/sse")}";`,
|
|
1111
1177
|
`import * as ${camelcase4(name)} from '../inputs/${config.makeImport(spinalcase2(name))}';`,
|
|
1112
1178
|
`import { createBaseUrlInterceptor, createHeadersInterceptor, type Interceptor } from '${config.makeImport("../http/interceptors")}';`,
|
|
1113
1179
|
`import { Dispatcher, fetchType, type InstanceType } from '${config.makeImport("../http/dispatcher")}';`,
|
|
@@ -1159,15 +1225,18 @@ function toProps(spec, schemaOrRef, aggregator = []) {
|
|
|
1159
1225
|
function bodyInputs(spec, ctSchema) {
|
|
1160
1226
|
const props = [];
|
|
1161
1227
|
toProps(spec, ctSchema, props);
|
|
1162
|
-
return
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1228
|
+
return (
|
|
1229
|
+
// TODO: should we preproccess the sort at spec level instead of generator's?
|
|
1230
|
+
sortArray(props).reduce(
|
|
1231
|
+
(acc, prop) => ({
|
|
1232
|
+
...acc,
|
|
1233
|
+
[prop]: {
|
|
1234
|
+
in: "body",
|
|
1235
|
+
schema: ""
|
|
1236
|
+
}
|
|
1237
|
+
}),
|
|
1238
|
+
{}
|
|
1239
|
+
)
|
|
1171
1240
|
);
|
|
1172
1241
|
}
|
|
1173
1242
|
var contentTypeSerializerMap = {
|
|
@@ -1233,13 +1302,13 @@ function operationSchema(ir, operation, type) {
|
|
|
1233
1302
|
}
|
|
1234
1303
|
|
|
1235
1304
|
// packages/typescript/src/lib/http/dispatcher.txt
|
|
1236
|
-
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
|
|
1305
|
+
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.instanceof(Request))\n .returns(z.promise(z.instanceof(Response)))\n .optional();\n\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 apiresponse = (output || APIResponse).create(\n response.status,\n response.headers,\n mapper((await parser(response)) as ResponseData<T>),\n );\n\n return apiresponse as RebindSuccessPayload<Extract<InstanceType<T>, SuccessfulResponse<unknown>>, R>;\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[], 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 let response = await (this.#fetch ?? fetch)(\n new Request(config.url, config.init),\n {\n ...config.init,\n signal: signal,\n },\n );\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 return await parse(\n outputs,\n response,\n mapper ?? ((data: ResponseData<T>) => data as unknown as R),\n );\n }\n}\n";
|
|
1237
1306
|
|
|
1238
1307
|
// packages/typescript/src/lib/http/interceptors.txt
|
|
1239
1308
|
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";
|
|
1240
1309
|
|
|
1241
1310
|
// packages/typescript/src/lib/http/parse-response.txt
|
|
1242
|
-
var parse_response_default = 'import { parse } from "fast-content-type-parse";\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
|
|
1311
|
+
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';
|
|
1243
1312
|
|
|
1244
1313
|
// packages/typescript/src/lib/http/parser.txt
|
|
1245
1314
|
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";
|
|
@@ -1250,6 +1319,9 @@ var request_default = "type Init = Omit<RequestInit, 'headers'> & { headers: Hea
|
|
|
1250
1319
|
// packages/typescript/src/lib/http/response.txt
|
|
1251
1320
|
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";
|
|
1252
1321
|
|
|
1322
|
+
// packages/typescript/src/lib/http/sse.txt
|
|
1323
|
+
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';
|
|
1324
|
+
|
|
1253
1325
|
// packages/typescript/src/lib/paginations/cursor-pagination.txt
|
|
1254
1326
|
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";
|
|
1255
1327
|
|
|
@@ -1644,6 +1716,32 @@ ${l}`));
|
|
|
1644
1716
|
return markdown.join("\n\n");
|
|
1645
1717
|
}
|
|
1646
1718
|
|
|
1719
|
+
// packages/typescript/src/lib/server-urls.ts
|
|
1720
|
+
function expandServerUrls(servers) {
|
|
1721
|
+
return servers.flatMap((server) => {
|
|
1722
|
+
const variables = server.variables;
|
|
1723
|
+
if (!variables || Object.keys(variables).length === 0) {
|
|
1724
|
+
return [server.url];
|
|
1725
|
+
}
|
|
1726
|
+
const entries = Object.entries(variables);
|
|
1727
|
+
const valueSets = entries.map(([, variable]) => {
|
|
1728
|
+
const enumValues = variable.enum?.map(String);
|
|
1729
|
+
return enumValues?.length ? enumValues : [String(variable.default)];
|
|
1730
|
+
});
|
|
1731
|
+
const combinations = valueSets.reduce(
|
|
1732
|
+
(acc, values) => acc.flatMap((combo) => values.map((v) => [...combo, v])),
|
|
1733
|
+
[[]]
|
|
1734
|
+
);
|
|
1735
|
+
return combinations.map((combo) => {
|
|
1736
|
+
let url = server.url;
|
|
1737
|
+
for (let i = 0; i < entries.length; i++) {
|
|
1738
|
+
url = url.replaceAll(`{${entries[i][0]}}`, combo[i]);
|
|
1739
|
+
}
|
|
1740
|
+
return url;
|
|
1741
|
+
});
|
|
1742
|
+
});
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1647
1745
|
// packages/typescript/src/lib/typescript-snippet.ts
|
|
1648
1746
|
import { camelcase as camelcase5, spinalcase as spinalcase3 } from "stringcase";
|
|
1649
1747
|
import { isEmpty as isEmpty4, pascalcase as pascalcase4, resolveRef as resolveRef3 } from "@sdk-it/core";
|
|
@@ -1997,7 +2095,7 @@ var TypeScriptSnippet = class {
|
|
|
1997
2095
|
}
|
|
1998
2096
|
client() {
|
|
1999
2097
|
const options = {
|
|
2000
|
-
baseUrl: this.#spec.servers
|
|
2098
|
+
baseUrl: expandServerUrls(this.#spec.servers ?? [])[0] ?? "http://localhost:3000"
|
|
2001
2099
|
};
|
|
2002
2100
|
const authOptions = this.#authentication();
|
|
2003
2101
|
if (!isEmpty4(authOptions)) {
|
|
@@ -2038,7 +2136,7 @@ ${client.use}`;
|
|
|
2038
2136
|
const hasServers = Boolean(
|
|
2039
2137
|
this.#spec.servers && this.#spec.servers.length > 0
|
|
2040
2138
|
);
|
|
2041
|
-
const baseUrl = this.#spec.servers
|
|
2139
|
+
const baseUrl = expandServerUrls(this.#spec.servers ?? [])[0] || "https://api.example.com";
|
|
2042
2140
|
const authOptions = this.#authentication();
|
|
2043
2141
|
const hasApiKey = !isEmpty4(authOptions);
|
|
2044
2142
|
sections.push("### Configuration Options");
|
|
@@ -2454,7 +2552,7 @@ ${client.use}`;
|
|
|
2454
2552
|
);
|
|
2455
2553
|
sections.push("");
|
|
2456
2554
|
const bearerAuthClient = this.#constructClient({
|
|
2457
|
-
[optionName]: "
|
|
2555
|
+
[optionName]: "test_51234567890abcdef1234567890abcdef"
|
|
2458
2556
|
});
|
|
2459
2557
|
sections.push(createCodeBlock("typescript", [bearerAuthClient.use]));
|
|
2460
2558
|
sections.push("");
|
|
@@ -2463,7 +2561,7 @@ ${client.use}`;
|
|
|
2463
2561
|
sections.push(`${headingLevel} ${apiKeyHeading}`);
|
|
2464
2562
|
sections.push("");
|
|
2465
2563
|
const apiKeyAuthClient = this.#constructClient({
|
|
2466
|
-
[optionName]: "
|
|
2564
|
+
[optionName]: "test_api_key_1234567890abcdef1234567890abcdef"
|
|
2467
2565
|
});
|
|
2468
2566
|
sections.push(createCodeBlock("typescript", [apiKeyAuthClient.use]));
|
|
2469
2567
|
sections.push("");
|
|
@@ -2472,7 +2570,7 @@ ${client.use}`;
|
|
|
2472
2570
|
sections.push(`${headingLevel} ${queryParamHeading}`);
|
|
2473
2571
|
sections.push("");
|
|
2474
2572
|
const queryParamAuthClient = this.#constructClient({
|
|
2475
|
-
[optionName]: "
|
|
2573
|
+
[optionName]: "test_qp_key_1234567890abcdef1234567890abcdef"
|
|
2476
2574
|
});
|
|
2477
2575
|
sections.push(
|
|
2478
2576
|
createCodeBlock("typescript", [queryParamAuthClient.use])
|
|
@@ -2483,7 +2581,7 @@ ${client.use}`;
|
|
|
2483
2581
|
sections.push(`${headingLevel} ${genericAuthHeading}`);
|
|
2484
2582
|
sections.push("");
|
|
2485
2583
|
const genericAuthClient = this.#constructClient({
|
|
2486
|
-
[optionName]: "
|
|
2584
|
+
[optionName]: "test_auth_token_1234567890abcdef1234567890abcdef"
|
|
2487
2585
|
});
|
|
2488
2586
|
sections.push(createCodeBlock("typescript", [genericAuthClient.use]));
|
|
2489
2587
|
sections.push("");
|
|
@@ -2510,7 +2608,7 @@ ${client.use}`;
|
|
|
2510
2608
|
if (!isEmpty4(authOptions)) {
|
|
2511
2609
|
const [primaryAuth] = authOptions;
|
|
2512
2610
|
const authOptionName = primaryAuth["x-optionName"] ?? primaryAuth.name;
|
|
2513
|
-
initialClientOptions[authOptionName] = "
|
|
2611
|
+
initialClientOptions[authOptionName] = "YOUR_PRODUCTION_TOKEN";
|
|
2514
2612
|
}
|
|
2515
2613
|
const initialClientSetup = this.#constructClient(initialClientOptions);
|
|
2516
2614
|
const configurationUpdateCode = [
|
|
@@ -2524,9 +2622,7 @@ ${client.use}`;
|
|
|
2524
2622
|
if (!isEmpty4(authOptions)) {
|
|
2525
2623
|
const [primaryAuth] = authOptions;
|
|
2526
2624
|
const authOptionName = primaryAuth["x-optionName"] ?? primaryAuth.name;
|
|
2527
|
-
configurationUpdateCode.push(
|
|
2528
|
-
` ${authOptionName}: 'staging_sk_abcdef1234567890'`
|
|
2529
|
-
);
|
|
2625
|
+
configurationUpdateCode.push(` ${authOptionName}: 'YOUR_STAGING_TOKEN'`);
|
|
2530
2626
|
}
|
|
2531
2627
|
configurationUpdateCode.push("});");
|
|
2532
2628
|
sections.push(createCodeBlock("typescript", configurationUpdateCode));
|
|
@@ -2631,7 +2727,7 @@ async function generate(openapi, settings) {
|
|
|
2631
2727
|
makeImport
|
|
2632
2728
|
});
|
|
2633
2729
|
const clientName = pascalcase5((settings.name || "client").trim());
|
|
2634
|
-
const packageName = settings.name ? `@${spinalcase4(settings.name.trim().toLowerCase())}/sdk` : "sdk";
|
|
2730
|
+
const packageName = settings.packageName ?? (settings.name ? `@${spinalcase4(settings.name.trim().toLowerCase())}/sdk` : "sdk");
|
|
2635
2731
|
const inputs = toInputs(groups, commonZod, makeImport);
|
|
2636
2732
|
const models = serializeModels(spec);
|
|
2637
2733
|
await settings.writer(output, {
|
|
@@ -2644,10 +2740,12 @@ async function generate(openapi, settings) {
|
|
|
2644
2740
|
"response.ts": response_default,
|
|
2645
2741
|
"parser.ts": parser_default,
|
|
2646
2742
|
"request.ts": request_default,
|
|
2743
|
+
"sse.ts": sse_default,
|
|
2647
2744
|
"dispatcher.ts": `import z from 'zod';
|
|
2648
2745
|
import { type Interceptor } from '${makeImport("../http/interceptors")}';
|
|
2649
2746
|
import { type RequestConfig } from '${makeImport("../http/request")}';
|
|
2650
2747
|
import { buffered } from '${makeImport("./parse-response")}';
|
|
2748
|
+
import { type SSEListener } from '${makeImport("./sse")}';
|
|
2651
2749
|
import { APIError, APIResponse, type SuccessfulResponse, type RebindSuccessPayload } from '${makeImport("./response")}';
|
|
2652
2750
|
|
|
2653
2751
|
${template2(dispatcher_default, {})()}`,
|
|
@@ -2658,7 +2756,7 @@ ${template2(dispatcher_default, {})()}`,
|
|
|
2658
2756
|
await settings.writer(output, {
|
|
2659
2757
|
"client.ts": client_default({
|
|
2660
2758
|
name: clientName,
|
|
2661
|
-
servers: (spec.servers ?? [])
|
|
2759
|
+
servers: expandServerUrls(spec.servers ?? []),
|
|
2662
2760
|
options: security(spec),
|
|
2663
2761
|
makeImport
|
|
2664
2762
|
}),
|
|
@@ -2818,6 +2916,7 @@ ${utils_default}`
|
|
|
2818
2916
|
output,
|
|
2819
2917
|
env: npmRunPathEnv()
|
|
2820
2918
|
});
|
|
2919
|
+
return { packageName };
|
|
2821
2920
|
}
|
|
2822
2921
|
function serializeModels(spec) {
|
|
2823
2922
|
const filesMap = {};
|
|
@@ -2831,12 +2930,18 @@ function serializeModels(spec) {
|
|
|
2831
2930
|
continue;
|
|
2832
2931
|
}
|
|
2833
2932
|
const folder = isResponseBody ? "outputs" : "models";
|
|
2834
|
-
|
|
2933
|
+
const isSse = schema["x-sse"];
|
|
2934
|
+
let typeContent = isSse ? "SSEListener" : "ReadableStream";
|
|
2835
2935
|
if (!stream) {
|
|
2836
2936
|
const serializer = new TypeScriptEmitter(spec);
|
|
2837
2937
|
typeContent = serializer.handle(schema, true);
|
|
2838
2938
|
}
|
|
2939
|
+
const imports = [];
|
|
2940
|
+
if (isSse) {
|
|
2941
|
+
imports.push(`import type { SSEListener } from '../http/sse.ts';`);
|
|
2942
|
+
}
|
|
2839
2943
|
const fileContent = [
|
|
2944
|
+
...imports,
|
|
2840
2945
|
`
|
|
2841
2946
|
${schema.description ? `
|
|
2842
2947
|
/**
|