@sdk-it/typescript 0.5.1 → 0.6.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/README.md +45 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +151 -43
- package/dist/index.js.map +4 -4
- package/dist/lib/client.d.ts.map +1 -1
- package/dist/lib/generate.d.ts +6 -0
- package/dist/lib/generate.d.ts.map +1 -1
- package/dist/lib/generator.d.ts.map +1 -1
- package/dist/lib/sdk.d.ts +10 -18
- package/dist/lib/sdk.d.ts.map +1 -1
- package/dist/lib/utils.d.ts +5 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/watcher.d.ts +2 -0
- package/dist/lib/watcher.d.ts.map +1 -0
- package/package.json +5 -5
package/README.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# @sdk-it/typescript
|
|
2
|
+
|
|
3
|
+
<p align="center">A type-safe SDK generator that converts OpenAPI specifications into TypeScript client.</p>
|
|
4
|
+
|
|
5
|
+
## Description
|
|
6
|
+
|
|
7
|
+
This package transforms OpenAPI specifications into fully-typed TypeScript client libraries. It focuses on generating clean, organized code that works in any JavaScript environment.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @sdk-it/typescript
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage Examples
|
|
16
|
+
|
|
17
|
+
### Basic SDK Generation
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { generate } from '@sdk-it/typescript';
|
|
21
|
+
|
|
22
|
+
import spec from './openapi.json';
|
|
23
|
+
|
|
24
|
+
await generate(spec, {
|
|
25
|
+
output: './client',
|
|
26
|
+
name: 'MyAPI',
|
|
27
|
+
});
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Remote Spec Example
|
|
31
|
+
|
|
32
|
+
```typescript
|
|
33
|
+
import { generate } from '@sdk-it/typescript';
|
|
34
|
+
|
|
35
|
+
// Fetch remote OpenAPI specification
|
|
36
|
+
const spec = await fetch('https://petstore.swagger.io/v2/swagger.json').then(
|
|
37
|
+
(res) => res.json(),
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
// Generate client SDK
|
|
41
|
+
await generate(spec, {
|
|
42
|
+
output: './client',
|
|
43
|
+
name: 'PetStore',
|
|
44
|
+
});
|
|
45
|
+
```
|
package/dist/index.d.ts
CHANGED
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// packages/typescript/src/lib/generate.ts
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
+
import { npmRunPathEnv } from "npm-run-path";
|
|
3
4
|
|
|
4
5
|
// packages/core/dist/index.js
|
|
5
6
|
import ts, { TypeFlags, symbolName } from "typescript";
|
|
@@ -10,6 +11,15 @@ import { dirname as dirname2, isAbsolute, join as join2 } from "node:path";
|
|
|
10
11
|
var deriveSymbol = Symbol.for("serialize");
|
|
11
12
|
var $types = Symbol.for("types");
|
|
12
13
|
var logger = debug("january:client");
|
|
14
|
+
var methods = [
|
|
15
|
+
"get",
|
|
16
|
+
"post",
|
|
17
|
+
"put",
|
|
18
|
+
"patch",
|
|
19
|
+
"delete",
|
|
20
|
+
"trace",
|
|
21
|
+
"head"
|
|
22
|
+
];
|
|
13
23
|
async function exist(file) {
|
|
14
24
|
return stat(file).then(() => true).catch(() => false);
|
|
15
25
|
}
|
|
@@ -325,49 +335,60 @@ function appendDefault(defaultValue) {
|
|
|
325
335
|
import { camelcase, pascalcase, spinalcase } from "stringcase";
|
|
326
336
|
|
|
327
337
|
// packages/typescript/src/lib/client.ts
|
|
328
|
-
import { titlecase } from "stringcase";
|
|
329
338
|
var client_default = (spec) => {
|
|
339
|
+
const optionsEntries = Object.entries(spec.options).map(
|
|
340
|
+
([key, value]) => [`'${key}'`, value]
|
|
341
|
+
);
|
|
342
|
+
const defaultHeaders = `{${optionsEntries.filter(([, value]) => value.in === "header").map(
|
|
343
|
+
([key, value]) => `${key}: this.options[${value.optionName ? `'${value.optionName}'` : key}]`
|
|
344
|
+
).join(",\n")}}`;
|
|
345
|
+
const defaultInputs = `{${optionsEntries.filter(([, value]) => value.in === "input").map(
|
|
346
|
+
([key, value]) => `${key}: this.options[${value.optionName ? `'${value.optionName}'` : key}]`
|
|
347
|
+
).join(",\n")}}`;
|
|
330
348
|
const specOptions = {
|
|
331
|
-
...
|
|
349
|
+
...Object.fromEntries(
|
|
350
|
+
optionsEntries.map(([key, value]) => [value.optionName ?? key, value])
|
|
351
|
+
),
|
|
332
352
|
fetch: {
|
|
333
353
|
schema: "fetchType"
|
|
334
354
|
},
|
|
335
355
|
baseUrl: {
|
|
336
|
-
schema: `z.enum(servers).default(servers[0])`
|
|
356
|
+
schema: spec.servers.length ? `z.enum(servers).default(servers[0])` : "z.string()"
|
|
337
357
|
}
|
|
338
358
|
};
|
|
339
|
-
if (spec.securityScheme) {
|
|
340
|
-
specOptions["token"] = { schema: "z.string().optional()" };
|
|
341
|
-
}
|
|
342
|
-
const defaultHeaders = spec.securityScheme ? `{Authorization: \`${titlecase(spec.securityScheme.bearerAuth.scheme)} \${this.options.token}\`}` : `{}`;
|
|
343
359
|
return `
|
|
344
360
|
import { fetchType, sendRequest } from './http/send-request.ts';
|
|
345
361
|
import z from 'zod';
|
|
346
362
|
import type { Endpoints } from './endpoints.ts';
|
|
347
363
|
import schemas from './schemas.ts';
|
|
364
|
+
${spec.servers.length ? `const servers = ${JSON.stringify(spec.servers, null, 2)} as const` : ""}
|
|
365
|
+
const optionsSchema = z.object(${toLitObject(specOptions, (x) => x.schema)});
|
|
366
|
+
|
|
367
|
+
type ${spec.name}Options = z.infer<typeof optionsSchema>;
|
|
348
368
|
|
|
349
|
-
|
|
350
|
-
const optionsSchema = z.object(${toLitObject(specOptions, (x) => x.schema)});
|
|
351
|
-
type ${spec.name}Options = z.infer<typeof optionsSchema>;
|
|
352
|
-
export class ${spec.name} {
|
|
369
|
+
export class ${spec.name} {
|
|
353
370
|
|
|
354
|
-
|
|
371
|
+
constructor(public options: ${spec.name}Options) {}
|
|
355
372
|
|
|
356
373
|
async request<E extends keyof Endpoints>(
|
|
357
374
|
endpoint: E,
|
|
358
375
|
input: Endpoints[E]['input'],
|
|
359
376
|
): Promise<readonly [Endpoints[E]['output'], Endpoints[E]['error'] | null]> {
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
377
|
+
const route = schemas[endpoint];
|
|
378
|
+
return sendRequest(Object.assign(this.#defaultInputs, input), route, {
|
|
379
|
+
baseUrl: this.options.baseUrl,
|
|
380
|
+
fetch: this.options.fetch,
|
|
381
|
+
headers: this.defaultHeaders,
|
|
382
|
+
});
|
|
366
383
|
}
|
|
367
384
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
385
|
+
get defaultHeaders() {
|
|
386
|
+
return ${defaultHeaders}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
get #defaultInputs() {
|
|
390
|
+
return ${defaultInputs}
|
|
391
|
+
}
|
|
371
392
|
|
|
372
393
|
setOptions(options: Partial<${spec.name}Options>) {
|
|
373
394
|
const validated = optionsSchema.partial().parse(options);
|
|
@@ -437,7 +458,7 @@ function generateClientSdk(spec) {
|
|
|
437
458
|
const schemasImports = [];
|
|
438
459
|
const schemaEndpoint = new SchemaEndpoint();
|
|
439
460
|
const errors = [];
|
|
440
|
-
for (const [name, operations] of Object.entries(spec.
|
|
461
|
+
for (const [name, operations] of Object.entries(spec.operations)) {
|
|
441
462
|
const featureSchemaFileName = camelcase(name);
|
|
442
463
|
schemas[featureSchemaFileName] = [`import z from 'zod';`];
|
|
443
464
|
emitter.addImport(
|
|
@@ -463,19 +484,19 @@ function generateClientSdk(spec) {
|
|
|
463
484
|
const inputBody = [];
|
|
464
485
|
const inputParams = [];
|
|
465
486
|
for (const [name2, prop] of Object.entries(operation.inputs)) {
|
|
466
|
-
if (prop.
|
|
487
|
+
if (prop.in === "headers" || prop.in === "header") {
|
|
467
488
|
inputHeaders.push(`"${name2}"`);
|
|
468
|
-
} else if (prop.
|
|
489
|
+
} else if (prop.in === "query") {
|
|
469
490
|
inputQuery.push(`"${name2}"`);
|
|
470
|
-
} else if (prop.
|
|
491
|
+
} else if (prop.in === "body") {
|
|
471
492
|
inputBody.push(`"${name2}"`);
|
|
472
|
-
} else if (prop.
|
|
493
|
+
} else if (prop.in === "path") {
|
|
473
494
|
inputParams.push(`"${name2}"`);
|
|
474
|
-
} else if (prop.
|
|
495
|
+
} else if (prop.in === "internal") {
|
|
475
496
|
continue;
|
|
476
497
|
} else {
|
|
477
498
|
throw new Error(
|
|
478
|
-
`Unknown source ${prop.
|
|
499
|
+
`Unknown source ${prop.in} in ${name2} ${JSON.stringify(
|
|
479
500
|
prop
|
|
480
501
|
)} in ${operation.name}`
|
|
481
502
|
);
|
|
@@ -495,7 +516,7 @@ function generateClientSdk(spec) {
|
|
|
495
516
|
endpoint,
|
|
496
517
|
`{
|
|
497
518
|
schema: ${schemaRef},
|
|
498
|
-
toRequest(input: StreamEndpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Record<string, string
|
|
519
|
+
toRequest(input: StreamEndpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Partial<Record<string, string>>}) {
|
|
499
520
|
const endpoint = '${endpoint}';
|
|
500
521
|
return toRequest(endpoint, json(input, {
|
|
501
522
|
inputHeaders: [${inputHeaders}],
|
|
@@ -527,7 +548,7 @@ function generateClientSdk(spec) {
|
|
|
527
548
|
endpoint,
|
|
528
549
|
`{
|
|
529
550
|
schema: ${schemaRef}${addTypeParser ? `.${type}` : ""},
|
|
530
|
-
toRequest(input: Endpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Record<string, string
|
|
551
|
+
toRequest(input: Endpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Partial<Record<string, string>>}) {
|
|
531
552
|
const endpoint = '${endpoint}';
|
|
532
553
|
return toRequest(endpoint, ${operation.contentType || "json"}(input, {
|
|
533
554
|
inputHeaders: [${inputHeaders}],
|
|
@@ -557,16 +578,51 @@ function generateClientSdk(spec) {
|
|
|
557
578
|
// add a newline at the end
|
|
558
579
|
])
|
|
559
580
|
),
|
|
560
|
-
"
|
|
581
|
+
"client.ts": client_default(spec),
|
|
561
582
|
"schemas.ts": schemaEndpoint.complete(),
|
|
562
583
|
"endpoints.ts": emitter.complete()
|
|
563
584
|
};
|
|
564
585
|
}
|
|
565
586
|
|
|
566
|
-
// packages/typescript/src/lib/
|
|
587
|
+
// packages/typescript/src/lib/utils.ts
|
|
567
588
|
function isRef(obj) {
|
|
568
589
|
return "$ref" in obj;
|
|
569
590
|
}
|
|
591
|
+
function securityToOptions(security2, securitySchemas, staticIn) {
|
|
592
|
+
securitySchemas ??= {};
|
|
593
|
+
const options = {};
|
|
594
|
+
for (const it of security2) {
|
|
595
|
+
const [name] = Object.keys(it);
|
|
596
|
+
const schema = securitySchemas[name];
|
|
597
|
+
if (isRef(schema)) {
|
|
598
|
+
throw new Error(`Ref security schemas are not supported`);
|
|
599
|
+
}
|
|
600
|
+
if (schema.type === "http") {
|
|
601
|
+
options["authorization"] = {
|
|
602
|
+
in: staticIn ?? "header",
|
|
603
|
+
schema: "z.string().optional()",
|
|
604
|
+
optionName: "token"
|
|
605
|
+
};
|
|
606
|
+
continue;
|
|
607
|
+
}
|
|
608
|
+
if (schema.type === "apiKey") {
|
|
609
|
+
if (!schema.in) {
|
|
610
|
+
throw new Error(`apiKey security schema must have an "in" field`);
|
|
611
|
+
}
|
|
612
|
+
if (!schema.name) {
|
|
613
|
+
throw new Error(`apiKey security schema must have a "name" field`);
|
|
614
|
+
}
|
|
615
|
+
options[schema.name] = {
|
|
616
|
+
in: staticIn ?? schema.in,
|
|
617
|
+
schema: "z.string().optional()"
|
|
618
|
+
};
|
|
619
|
+
continue;
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
return options;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// packages/typescript/src/lib/generator.ts
|
|
570
626
|
var responses = {
|
|
571
627
|
"400": "BadRequest",
|
|
572
628
|
"401": "Unauthorized",
|
|
@@ -600,8 +656,8 @@ function generateCode(config) {
|
|
|
600
656
|
const groups = {};
|
|
601
657
|
const commonSchemas = {};
|
|
602
658
|
const outputs = {};
|
|
603
|
-
for (const [path,
|
|
604
|
-
for (const [method, operation] of Object.entries(
|
|
659
|
+
for (const [path, methods2] of Object.entries(config.spec.paths ?? {})) {
|
|
660
|
+
for (const [method, operation] of Object.entries(methods2)) {
|
|
605
661
|
const formatOperationId = config.operationId ?? defaults.operationId;
|
|
606
662
|
const operationName = formatOperationId(operation, path, method);
|
|
607
663
|
console.log(`Processing ${method} ${path}`);
|
|
@@ -618,11 +674,27 @@ function generateCode(config) {
|
|
|
618
674
|
throw new Error(`Schema not found for parameter ${param.name}`);
|
|
619
675
|
}
|
|
620
676
|
inputs[param.name] = {
|
|
621
|
-
|
|
677
|
+
in: param.in,
|
|
622
678
|
schema: ""
|
|
623
679
|
};
|
|
624
680
|
additionalProperties.push(param);
|
|
625
681
|
}
|
|
682
|
+
const security2 = operation.security ?? [];
|
|
683
|
+
const securitySchemas = config.spec.components?.securitySchemes ?? {};
|
|
684
|
+
const securityOptions = securityToOptions(security2, securitySchemas);
|
|
685
|
+
Object.assign(inputs, securityOptions);
|
|
686
|
+
additionalProperties.push(
|
|
687
|
+
...Object.entries(securityOptions).map(
|
|
688
|
+
([name, value]) => ({
|
|
689
|
+
name,
|
|
690
|
+
required: false,
|
|
691
|
+
schema: {
|
|
692
|
+
type: "string"
|
|
693
|
+
},
|
|
694
|
+
in: value.in
|
|
695
|
+
})
|
|
696
|
+
)
|
|
697
|
+
);
|
|
626
698
|
const types = {};
|
|
627
699
|
const shortContenTypeMap = {
|
|
628
700
|
"application/json": "json",
|
|
@@ -800,28 +872,47 @@ var client_default2 = "import { parse } from 'fast-content-type-parse';\n\nexpor
|
|
|
800
872
|
var parser_default = "import { z } from 'zod';\n\nexport type ParseError<T extends z.ZodType<any, any, any>> = {\n kind: 'parse';\n} & z.inferFlattenedErrors<T>;\n\nexport function parse<T extends z.ZodType>(\n schema: T,\n input: unknown,\n) {\n const result = schema.safeParse(input);\n if (!result.success) {\n const errors = result.error.flatten((issue) => issue);\n return [null, errors];\n }\n return [result.data as z.infer<T>, null];\n}\n";
|
|
801
873
|
|
|
802
874
|
// packages/typescript/src/lib/http/request.txt
|
|
803
|
-
var request_default = "type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\ntype ContentType = 'xml' | 'json' | 'urlencoded' | 'multipart';\ntype Endpoint = `${ContentType} ${Method} ${string}` | `${Method} ${string}`;\n\nexport function createUrl(base: string, path: string, query: URLSearchParams) {\n const url = new URL(path, base);\n url.search = query.toString();\n return url;\n}\nfunction template(\n templateString: string,\n templateVariables: Record<string, any>,\n): string {\n const nargs = /{([0-9a-zA-Z_]+)}/g;\n return templateString.replace(nargs, (match, key: string, index: number) => {\n // Handle escaped double braces\n if (\n templateString[index - 1] === '{' &&\n templateString[index + match.length] === '}'\n ) {\n return key;\n }\n\n const result = key in templateVariables ? templateVariables[key] : null;\n return result === null || result === undefined ? '' : String(result);\n });\n}\n\ninterface ToRequest {\n <T extends Endpoint>(\n endpoint: T,\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n defaults: {\n baseUrl: string;\n headers?: Record<string, string
|
|
875
|
+
var request_default = "type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\ntype ContentType = 'xml' | 'json' | 'urlencoded' | 'multipart';\ntype Endpoint = `${ContentType} ${Method} ${string}` | `${Method} ${string}`;\n\nexport function createUrl(base: string, path: string, query: URLSearchParams) {\n const url = new URL(path, base);\n url.search = query.toString();\n return url;\n}\nfunction template(\n templateString: string,\n templateVariables: Record<string, any>,\n): string {\n const nargs = /{([0-9a-zA-Z_]+)}/g;\n return templateString.replace(nargs, (match, key: string, index: number) => {\n // Handle escaped double braces\n if (\n templateString[index - 1] === '{' &&\n templateString[index + match.length] === '}'\n ) {\n return key;\n }\n\n const result = key in templateVariables ? templateVariables[key] : null;\n return result === null || result === undefined ? '' : String(result);\n });\n}\n\ninterface ToRequest {\n <T extends Endpoint>(\n endpoint: T,\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n defaults: {\n baseUrl: string;\n headers?: Partial<Record<string, string>>;\n },\n ): Request;\n urlencoded: <T extends Endpoint>(\n endpoint: T,\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n defaults: {\n baseUrl: string;\n headers?: Partial<Record<string, string>>;\n },\n ) => Request;\n}\n\nfunction _json(\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n) {\n const headers = new Headers({});\n for (const header of props.inputHeaders) {\n headers.set(header, input[header]);\n }\n\n const body: Record<string, any> = {};\n for (const prop of props.inputBody) {\n body[prop] = input[prop];\n }\n\n const query = new URLSearchParams();\n for (const key of props.inputQuery) {\n const value = input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = props.inputParams.reduce<Record<string, any>>((acc, key) => {\n acc[key] = input[key];\n return acc;\n }, {});\n\n return {\n body: JSON.stringify(body),\n query,\n params,\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n };\n}\n\ntype Input = Record<string, any>;\ntype Props = {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n};\n\nabstract class Serializer {\n constructor(\n protected input: Input,\n protected props: Props,\n ) {}\n abstract getBody(): BodyInit | null;\n abstract getHeaders(): Partial<Record<string, string>>;\n serialize(): Serialized {\n const headers = new Headers({});\n for (const header of this.props.inputHeaders) {\n headers.set(header, this.input[header]);\n }\n\n const query = new URLSearchParams();\n for (const key of this.props.inputQuery) {\n const value = this.input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = this.props.inputParams.reduce<Record<string, any>>(\n (acc, key) => {\n acc[key] = this.input[key];\n return acc;\n },\n {},\n );\n\n return {\n body: this.getBody(),\n query,\n params,\n headers: this.getHeaders(),\n };\n }\n}\n\ninterface Serialized {\n body: BodyInit | null;\n query: URLSearchParams;\n params: Record<string, any>;\n headers: Partial<Record<string, string>>;\n}\n\nclass JsonSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body: Record<string, any> = {};\n for (const prop of this.props.inputBody) {\n body[prop] = this.input[prop];\n }\n return JSON.stringify(body);\n }\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n\nclass UrlencodedSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new URLSearchParams();\n for (const prop of this.props.inputBody) {\n body.set(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nclass FormDataSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new FormData();\n for (const prop of this.props.inputBody) {\n body.append(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nexport function json(input: Input, props: Props) {\n return new JsonSerializer(input, props).serialize();\n}\nexport function urlencoded(input: Input, props: Props) {\n return new UrlencodedSerializer(input, props).serialize();\n}\nexport function formdata(input: Input, props: Props) {\n return new FormDataSerializer(input, props).serialize();\n}\n\nexport function _urlencoded(\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n) {\n const headers = new Headers({});\n for (const header of props.inputHeaders) {\n headers.set(header, input[header]);\n }\n\n const body = new URLSearchParams();\n for (const prop of props.inputBody) {\n body.set(prop, input[prop]);\n }\n\n const query = new URLSearchParams();\n for (const key of props.inputQuery) {\n const value = input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = props.inputParams.reduce<Record<string, any>>((acc, key) => {\n acc[key] = input[key];\n return acc;\n }, {});\n\n return {\n body,\n query,\n params,\n headers: {},\n };\n}\n\nexport function toRequest<T extends Endpoint>(\n endpoint: T,\n input: Serialized,\n defaults: {\n baseUrl: string;\n headers?: Partial<Record<string, string>>;\n },\n): Request {\n const [method, path] = endpoint.split(' ');\n\n const headers = new Headers(\n Object.entries({\n ...defaults?.headers,\n ...input.headers,\n }).filter(truthyEntry),\n );\n const pathVariable = template(path, input.params);\n\n const url = createUrl(defaults.baseUrl, pathVariable, input.query);\n return new Request(url, {\n method: method,\n headers: headers,\n body: method === 'GET' ? undefined : input.body,\n });\n}\n\nfunction truthyEntry(entry: [string, unknown]): entry is [string, string] {\n return entry[1] !== undefined;\n}\n";
|
|
804
876
|
|
|
805
877
|
// packages/typescript/src/lib/http/response.txt
|
|
806
878
|
var response_default = "export interface ApiResponse<Status extends number, Body extends unknown> {\n kind: 'response';\n status: Status;\n body: Body;\n}\n\n// 4xx Client Errors\nexport type BadRequest = ApiResponse<400, { message: string }>;\nexport type Unauthorized = ApiResponse<401, { message: string }>;\nexport type PaymentRequired = ApiResponse<402, { message: string }>;\nexport type Forbidden = ApiResponse<403, { message: string }>;\nexport type NotFound = ApiResponse<404, { message: string }>;\nexport type MethodNotAllowed = ApiResponse<405, { message: string }>;\nexport type NotAcceptable = ApiResponse<406, { message: string }>;\nexport type Conflict = ApiResponse<409, { message: string }>;\nexport type Gone = ApiResponse<410, { message: string }>;\nexport type UnprocessableEntity = ApiResponse<422, { message: string; errors?: Record<string, string[]> }>;\nexport type TooManyRequests = ApiResponse<429, { message: string; retryAfter?: string }>;\nexport type PayloadTooLarge = ApiResponse<413, { message: string; }>;\nexport type UnsupportedMediaType = ApiResponse<415, { message: string; }>;\n\n// 5xx Server Errors\nexport type InternalServerError = ApiResponse<500, { message: string }>;\nexport type NotImplemented = ApiResponse<501, { message: string }>;\nexport type BadGateway = ApiResponse<502, { message: string }>;\nexport type ServiceUnavailable = ApiResponse<503, { message: string; retryAfter?: string }>;\nexport type GatewayTimeout = ApiResponse<504, { message: string }>;\n\nexport type ClientError =\n | BadRequest\n | Unauthorized\n | PaymentRequired\n | Forbidden\n | NotFound\n | MethodNotAllowed\n | NotAcceptable\n | Conflict\n | Gone\n | UnprocessableEntity\n | TooManyRequests;\n\nexport type ServerError =\n | InternalServerError\n | NotImplemented\n | BadGateway\n | ServiceUnavailable\n | GatewayTimeout;\n\nexport type ProblematicResponse = ClientError | ServerError;\n";
|
|
807
879
|
|
|
808
880
|
// packages/typescript/src/lib/http/send-request.txt
|
|
809
|
-
var send_request_default = "import z from 'zod';\n\nimport { handleError, parseResponse } from './parse-response.ts';\nimport { parse } from './parser.ts';\n\nexport interface RequestSchema {\n schema: z.ZodType;\n toRequest: (\n input: any,\n init: { baseUrl: string; headers?: Record<string, string
|
|
810
|
-
|
|
811
|
-
// packages/typescript/src/lib/readme-generator.ts
|
|
812
|
-
import { pascalcase as pascalcase3 } from "stringcase";
|
|
881
|
+
var send_request_default = "import z from 'zod';\n\nimport { handleError, parseResponse } from './parse-response.ts';\nimport { parse } from './parser.ts';\n\nexport interface RequestSchema {\n schema: z.ZodType;\n toRequest: (\n input: any,\n init: { baseUrl: string; headers?: Partial<Record<string, string>> },\n ) => any;\n}\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 sendRequest(\n input: any,\n route: RequestSchema,\n options: {\n baseUrl: string;\n fetch?: z.infer<typeof fetchType>;\n headers?: Partial<Record<string, string>>;\n },\n) {\n const [parsedInput, parseError] = parse(route.schema, input);\n if (parseError) {\n return [null as never, { ...parseError, kind: 'parse' } as never] as const;\n }\n const request = route.toRequest(parsedInput as never, {\n headers: options.headers,\n baseUrl: options.baseUrl,\n });\n const response = await (options.fetch ?? fetch)(request);\n if (response.ok) {\n const data = await parseResponse(response);\n return [data, null] as const;\n }\n const error = await handleError(response);\n return [null as never, { ...error, kind: 'response' }] as const;\n}\n";
|
|
813
882
|
|
|
814
883
|
// packages/typescript/src/lib/generate.ts
|
|
884
|
+
function security(spec) {
|
|
885
|
+
const security2 = spec.security || [];
|
|
886
|
+
const components = spec.components || {};
|
|
887
|
+
const securitySchemas = components.securitySchemes || {};
|
|
888
|
+
const paths = Object.values(spec.paths ?? {});
|
|
889
|
+
const options = securityToOptions(security2, securitySchemas);
|
|
890
|
+
for (const it of paths) {
|
|
891
|
+
for (const method of methods) {
|
|
892
|
+
const operation = it[method];
|
|
893
|
+
if (!operation) {
|
|
894
|
+
continue;
|
|
895
|
+
}
|
|
896
|
+
Object.assign(
|
|
897
|
+
options,
|
|
898
|
+
securityToOptions(operation.security || [], securitySchemas, "input")
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
}
|
|
902
|
+
return options;
|
|
903
|
+
}
|
|
815
904
|
async function generate(spec, settings) {
|
|
816
905
|
const { commonSchemas, groups, outputs } = generateCode({
|
|
817
906
|
spec,
|
|
818
907
|
style: "github",
|
|
819
908
|
target: "javascript"
|
|
820
909
|
});
|
|
910
|
+
const options = security(spec);
|
|
821
911
|
const clientFiles = generateClientSdk({
|
|
822
912
|
name: settings.name || "Client",
|
|
823
|
-
groups,
|
|
824
|
-
servers: spec.servers?.map((server) => server.url) || []
|
|
913
|
+
operations: groups,
|
|
914
|
+
servers: spec.servers?.map((server) => server.url) || [],
|
|
915
|
+
options
|
|
825
916
|
});
|
|
826
917
|
await writeFiles(settings.output, {
|
|
827
918
|
"outputs/index.ts": "",
|
|
@@ -853,8 +944,25 @@ ${Object.entries(commonSchemas).map(([name, schema]) => `export const ${name} =
|
|
|
853
944
|
"inputs/index.ts": inputsIndex,
|
|
854
945
|
"http/index.ts": httpIndex
|
|
855
946
|
});
|
|
947
|
+
await settings.formatCode?.({
|
|
948
|
+
output: settings.output,
|
|
949
|
+
env: npmRunPathEnv()
|
|
950
|
+
});
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
// packages/typescript/src/lib/watcher.ts
|
|
954
|
+
import { watch as nodeWatch } from "node:fs/promises";
|
|
955
|
+
import { debounceTime, from } from "rxjs";
|
|
956
|
+
function watch(path) {
|
|
957
|
+
return from(
|
|
958
|
+
nodeWatch(path, {
|
|
959
|
+
persistent: true,
|
|
960
|
+
recursive: true
|
|
961
|
+
})
|
|
962
|
+
).pipe(debounceTime(400));
|
|
856
963
|
}
|
|
857
964
|
export {
|
|
858
|
-
generate
|
|
965
|
+
generate,
|
|
966
|
+
watch
|
|
859
967
|
};
|
|
860
968
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/generate.ts", "../../core/src/lib/deriver.ts", "../../core/src/lib/program.ts", "../../core/src/lib/paths.ts", "../../core/src/lib/file-system.ts", "../../core/src/index.ts", "../src/lib/generator.ts", "../src/lib/json-zod.ts", "../src/lib/sdk.ts", "../src/lib/client.ts", "../src/lib/http/client.txt", "../src/lib/http/parser.txt", "../src/lib/http/request.txt", "../src/lib/http/response.txt", "../src/lib/http/send-request.txt", "../src/lib/
|
|
4
|
-
"sourcesContent": ["import { join } from 'node:path';\nimport type { OpenAPIObject } from 'openapi3-ts/oas31';\n\nimport { getFolderExports, writeFiles } from '@sdk-it/core';\n\nimport { generateCode } from './generator.ts';\nimport clientTxt from './http/client.txt';\nimport parserTxt from './http/parser.txt';\nimport requestTxt from './http/request.txt';\nimport responseTxt from './http/response.txt';\nimport sendRequest from './http/send-request.txt';\nimport { generateReadme } from './readme-generator.ts';\nimport { generateClientSdk } from './sdk.ts';\n\nexport async function generate(\n spec: OpenAPIObject,\n settings: {\n output: string;\n name?: string;\n },\n) {\n const { commonSchemas, groups, outputs } = generateCode({\n spec,\n style: 'github',\n target: 'javascript',\n });\n\n const clientFiles = generateClientSdk({\n name: settings.name || 'Client',\n groups: groups,\n servers: spec.servers?.map((server) => server.url) || [],\n });\n\n // const readme = generateReadme(spec, {\n // name: settings.name || 'Client',\n // });\n\n await writeFiles(settings.output, {\n 'outputs/index.ts': '',\n 'inputs/index.ts': '',\n // 'README.md': readme,\n });\n\n await writeFiles(join(settings.output, 'http'), {\n 'parse-response.ts': clientTxt,\n 'send-request.ts': sendRequest,\n 'response.ts': responseTxt,\n 'parser.ts': parserTxt,\n 'request.ts': requestTxt,\n });\n\n await writeFiles(join(settings.output, 'outputs'), outputs);\n await writeFiles(settings.output, {\n ...clientFiles,\n 'zod.ts': `import z from 'zod';\\n${Object.entries(commonSchemas)\n .map(([name, schema]) => `export const ${name} = ${schema};`)\n .join('\\n')}`,\n });\n\n const [index, outputIndex, inputsIndex, httpIndex] = await Promise.all([\n getFolderExports(settings.output),\n getFolderExports(join(settings.output, 'outputs')),\n getFolderExports(join(settings.output, 'inputs')),\n getFolderExports(join(settings.output, 'http')),\n ]);\n\n await writeFiles(settings.output, {\n 'index.ts': index,\n 'outputs/index.ts': outputIndex,\n 'inputs/index.ts': inputsIndex,\n 'http/index.ts': httpIndex,\n });\n}\n", "import ts, { TypeFlags, symbolName } from 'typescript';\n\ntype Collector = Record<string, any>;\nexport const deriveSymbol = Symbol.for('serialize');\nexport const $types = Symbol.for('types');\nconst defaults: Record<string, string> = {\n ReadableStream: 'any',\n DateConstructor: 'string',\n ArrayBufferConstructor: 'any',\n SharedArrayBufferConstructor: 'any',\n Int8ArrayConstructor: 'any',\n Uint8Array: 'any',\n};\nexport class TypeDeriver {\n public readonly collector: Collector = {};\n public readonly checker: ts.TypeChecker;\n constructor(checker: ts.TypeChecker) {\n this.checker = checker;\n }\n\n serializeType(type: ts.Type): any {\n if (type.flags & TypeFlags.Any) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.flags & ts.TypeFlags.Boolean) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (type.isIntersection()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'intersection',\n optional,\n [$types]: types,\n };\n }\n if (type.isUnion()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'union',\n optional,\n [$types]: types,\n };\n }\n if (this.checker.isArrayLikeType(type)) {\n const [argType] = this.checker.getTypeArguments(type as ts.TypeReference);\n if (!argType) {\n const typeName = type.symbol?.getName() || '<unknown>';\n console.warn(\n `Could not find generic type argument for array type ${typeName}`,\n );\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: ['any'],\n };\n }\n const typeSymbol = argType.getSymbol();\n if (!typeSymbol) {\n console.warn(\n `No symbol found for array type ${this.checker.typeToString(argType)}`,\n );\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: [this.serializeType(argType)],\n };\n }\n\n if (typeSymbol.valueDeclaration) {\n return {\n kind: 'array',\n [deriveSymbol]: true,\n [$types]: [this.serializeNode(typeSymbol.valueDeclaration)],\n };\n }\n const maybeDeclaration = typeSymbol.declarations?.[0];\n if (maybeDeclaration) {\n if (ts.isMappedTypeNode(maybeDeclaration)) {\n const resolvedType = this.checker\n .getPropertiesOfType(argType)\n .reduce<Record<string, unknown>>((acc, prop) => {\n const propType = this.checker.getTypeOfSymbol(prop);\n acc[prop.name] = this.serializeType(propType);\n return acc;\n }, {});\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: [resolvedType],\n };\n } else {\n return {\n kind: 'array',\n ...this.serializeNode(maybeDeclaration),\n };\n }\n }\n\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: ['any'],\n };\n }\n if (type.isClass()) {\n const declaration = type.symbol?.valueDeclaration;\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n if (isInterfaceType(type)) {\n const valueDeclaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!valueDeclaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(valueDeclaration);\n }\n if (type.flags & TypeFlags.Null) {\n return {\n [deriveSymbol]: true,\n optional: true,\n [$types]: ['null'],\n };\n }\n if (type.flags & TypeFlags.Object) {\n if (defaults[symbolName(type.symbol)]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [defaults[type.symbol.name]],\n };\n }\n const properties = this.checker.getPropertiesOfType(type);\n if (properties.length > 0) {\n const serializedProps: Record<string, any> = {};\n for (const prop of properties) {\n if (\n (prop.getDeclarations() ?? []).some(\n (it) => ts.isPropertySignature(it) || ts.isPropertyAssignment(it),\n )\n ) {\n const propType = this.checker.getTypeOfSymbol(prop);\n serializedProps[prop.name] = this.serializeType(propType);\n }\n }\n return {\n [deriveSymbol]: true,\n kind: 'object',\n optional: false,\n [$types]: [serializedProps],\n };\n }\n const declaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [\n this.checker.typeToString(\n type,\n undefined,\n ts.TypeFormatFlags.NoTruncation,\n ),\n ],\n };\n }\n\n serializeNode(node: ts.Node): any {\n if (ts.isObjectLiteralExpression(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, any> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return props;\n }\n if (ts.isPropertyAccessExpression(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertySignature(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertyDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isInterfaceDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Interface has no name');\n }\n console.log(node.name.text);\n if (defaults[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [defaults[node.name.text]],\n };\n }\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, any> = {};\n for (const member of node.members.filter(ts.isPropertySignature)) {\n members[member.name.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = members;\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n };\n }\n if (ts.isClassDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Class has no name');\n }\n if (defaults[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [defaults[node.name.text]],\n };\n }\n\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, unknown> = {};\n for (const member of node.members.filter(ts.isPropertyDeclaration)) {\n members[member.name!.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = members;\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n $ref: `#/components/schemas/${node.name.text}`,\n };\n }\n if (ts.isVariableDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n if (!node.type) {\n console.warn(`No type found for ${node.name.getText()}`);\n return 'any';\n }\n const type = this.checker.getTypeFromTypeNode(node.type);\n return this.serializeType(type);\n }\n if (ts.isIdentifier(node)) {\n const symbol = this.checker.getSymbolAtLocation(node);\n if (!symbol) {\n console.warn(`Identifer: No symbol found for ${node.getText()}`);\n return null;\n }\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAwaitExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isCallExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAsExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isTypeLiteralNode(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, unknown> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [props],\n };\n }\n if (node.kind === ts.SyntaxKind.NullKeyword) {\n return {\n [deriveSymbol]: true,\n optional: true,\n [$types]: ['null'],\n };\n }\n if (node.kind === ts.SyntaxKind.BooleanKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (\n node.kind === ts.SyntaxKind.TrueKeyword ||\n node.kind === ts.SyntaxKind.FalseKeyword\n ) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (ts.isArrayLiteralExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n console.warn(`Unhandled node: ${ts.SyntaxKind[node.kind]} ${node.flags}`);\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n}\n\nfunction isInterfaceType(type: ts.Type): boolean {\n if (type.isClassOrInterface()) {\n // Check if it's an interface\n return !!(type.symbol.flags & ts.SymbolFlags.Interface);\n }\n return false;\n}\n", "import debug from 'debug';\nimport { dirname, join } from 'node:path';\nimport ts from 'typescript';\n\n\n\n\n\nconst logger = debug('january:client');\n\nexport function parseTsConfig(tsconfigPath: string) {\n logger(`Using TypeScript version: ${ts.version}`);\n const configContent = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configContent.error) {\n console.error(\n `Failed to read tsconfig file:`,\n ts.formatDiagnosticsWithColorAndContext([configContent.error], {\n getCanonicalFileName: (path) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n }),\n );\n throw new Error('Failed to parse tsconfig.json');\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n configContent.config,\n ts.sys,\n dirname(tsconfigPath),\n );\n\n if (parsed.errors.length > 0) {\n console.error(\n `Errors found in tsconfig.json:`,\n ts.formatDiagnosticsWithColorAndContext(parsed.errors, {\n getCanonicalFileName: (path) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n }),\n );\n throw new Error('Failed to parse tsconfig.json');\n }\n return parsed;\n}\nexport function getProgram(tsconfigPath: string) {\n const tsConfigParseResult = parseTsConfig(tsconfigPath);\n logger(`Parsing tsconfig`);\n return ts.createProgram({\n options: {\n ...tsConfigParseResult.options,\n noEmit: true,\n incremental: true,\n tsBuildInfoFile: join(dirname(tsconfigPath), './.tsbuildinfo'), // not working atm\n },\n rootNames: tsConfigParseResult.fileNames,\n projectReferences: tsConfigParseResult.projectReferences,\n configFileParsingDiagnostics: tsConfigParseResult.errors,\n });\n}\nexport function getPropertyAssignment(node: ts.Node, name: string) {\n if (ts.isObjectLiteralExpression(node)) {\n return node.properties\n .filter((prop) => ts.isPropertyAssignment(prop))\n .find((prop) => prop.name!.getText() === name);\n }\n return undefined;\n}\nexport function isCallExpression(\n node: ts.Node,\n name: string,\n): node is ts.CallExpression {\n return (\n ts.isCallExpression(node) &&\n node.expression &&\n ts.isIdentifier(node.expression) &&\n node.expression.text === name\n );\n}\n\nexport function isInterfaceType(type: ts.Type): boolean {\n if (type.isClassOrInterface()) {\n // Check if it's an interface\n return !!(type.symbol.flags & ts.SymbolFlags.Interface);\n }\n return false;\n}", "import type {\n OperationObject,\n ParameterObject,\n PathsObject,\n ResponseObject,\n ResponsesObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { $types } from './deriver.ts';\n\nexport type Method = 'get' | 'post' | 'put' | 'patch' | 'delete';\n\nexport type SemanticSource =\n | 'query'\n | 'queries'\n | 'body'\n | 'params'\n | 'headers';\n\nconst semanticSourceToOpenAPI = {\n queries: 'query',\n query: 'query',\n headers: 'header',\n params: 'path',\n} as const;\nexport interface Selector {\n name: string;\n select: string;\n against: string;\n source: SemanticSource;\n nullable: boolean;\n required: boolean;\n}\n\nexport interface ResponseItem {\n statusCode: string;\n response?: DateType;\n contentType: string;\n headers: string[];\n}\n\nexport class Paths {\n #commonZodImport?: string;\n #operations: Array<{\n name: string;\n path: string;\n method: Method;\n selectors: Selector[];\n responses: ResponsesObject;\n tags?: string[];\n description?: string;\n }> = [];\n\n constructor(config: { commonZodImport?: string }) {\n this.#commonZodImport = config.commonZodImport;\n }\n\n addPath(\n name: string,\n path: string,\n method: Method,\n selectors: Selector[],\n responses: ResponseItem[],\n tags?: string[],\n description?: string,\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n this.#operations.push({\n name,\n path,\n method,\n selectors,\n responses: responsesObject,\n tags,\n description,\n });\n return this;\n }\n\n #responseItemToResponses(responses: ResponseItem[]): ResponsesObject {\n const responsesObject: ResponsesObject = {};\n for (const item of responses) {\n const ct = item.contentType;\n const schema = item.response ? toSchema(item.response) : {};\n if (!responsesObject[item.statusCode]) {\n responsesObject[item.statusCode] = {\n description: `Response for ${item.statusCode}`,\n content: {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n },\n headers: item.headers.length\n ? item.headers.reduce(\n (acc, header) => ({\n ...acc,\n [header]: { schema: { type: 'string' } },\n }),\n {},\n )\n : undefined,\n } satisfies ResponseObject;\n } else {\n if (!responsesObject[item.statusCode].content[ct]) {\n responsesObject[item.statusCode].content[ct] = { schema };\n } else {\n const existing = responsesObject[item.statusCode].content[ct]\n .schema as SchemaObject;\n if (existing.oneOf) {\n if (\n !existing.oneOf.find(\n (it) => JSON.stringify(it) === JSON.stringify(schema),\n )\n ) {\n existing.oneOf.push(schema);\n }\n } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {\n responsesObject[item.statusCode].content[ct].schema = {\n oneOf: [existing, schema],\n };\n }\n }\n }\n }\n return responsesObject;\n }\n\n async #selectosToParameters(selectors: Selector[]) {\n const parameters: ParameterObject[] = [];\n const bodySchemaProps: Record<string, SchemaObject> = {};\n for (const selector of selectors) {\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = await evalZod(\n selector.against,\n this.#commonZodImport,\n );\n continue;\n }\n\n const parameter: ParameterObject = {\n in: semanticSourceToOpenAPI[selector.source],\n name: selector.name,\n required: selector.required,\n schema: await evalZod(selector.against, this.#commonZodImport),\n };\n parameters.push(parameter);\n }\n return { parameters, bodySchemaProps };\n }\n\n async getPaths() {\n const operations: PathsObject = {};\n for (const operation of this.#operations) {\n const { path, method, selectors } = operation;\n const { parameters, bodySchemaProps } =\n await this.#selectosToParameters(selectors);\n const operationObject: OperationObject = {\n operationId: operation.name,\n parameters,\n tags: operation.tags,\n description: operation.description,\n requestBody: Object.keys(bodySchemaProps).length\n ? {\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: bodySchemaProps,\n },\n },\n },\n }\n : undefined,\n responses: operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n }\n return operations;\n }\n}\n\nasync function evalZod(schema: string, commonZodImport?: string) {\n const lines = [\n `import { z } from 'zod';`,\n commonZodImport ? `import * as commonZod from '${commonZodImport}'` : '',\n `import { zodToJsonSchema } from 'zod-to-json-schema';`,\n `const schema = ${schema.replace('.optional()', '')};`,\n `const jsonSchema = zodToJsonSchema(schema, {\n\t\t\t$refStrategy: 'root',\n\t\t\tbasePath: ['#', 'components', 'schemas']\n\t\t});`,\n `export default jsonSchema;`,\n ];\n const base64Code = Buffer.from(lines.join('\\n')).toString('base64');\n const dataUrl = `data:text/javascript;base64,${base64Code}`;\n return import(dataUrl)\n .then((mod) => mod.default)\n .then(({ $schema, ...result }) => result);\n}\n\nconst typeMappings: Record<string, string> = {\n DateConstructor: 'Date',\n};\n\ninterface DateType {\n [$types]: any[];\n kind: string;\n optional: boolean;\n}\n\nexport function toSchema(data: DateType | string | null | undefined): any {\n if (data === null || data === undefined) {\n return { type: 'any' };\n } else if (typeof data === 'string') {\n const isRef = data.startsWith('#');\n if (isRef) {\n return { $ref: data };\n }\n return { type: data };\n } else if (data.kind === 'array') {\n const items = data[$types].map(toSchema);\n return { type: 'array', items: data[$types].length ? items[0] : {} };\n } else if (data.kind === 'union') {\n return { oneOf: data[$types].map(toSchema) };\n } else if (data.kind === 'intersection') {\n return { allOf: data[$types].map(toSchema) };\n } else if ($types in data) {\n return data[$types].map(toSchema)[0] ?? {};\n } else {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n props[key] = toSchema(value as any);\n }\n return {\n type: 'object',\n properties: props,\n additionalProperties: false,\n };\n }\n}\n\nexport function isHttpMethod(name: string): name is Method {\n return ['get', 'post', 'put', 'delete', 'patch'].includes(name);\n}\n", "import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join } from 'node:path';\n\nexport async function getFile(filePath: string) {\n if (await exist(filePath)) {\n return readFile(filePath, 'utf-8');\n }\n return null;\n}\n\nexport async function exist(file: string): Promise<boolean> {\n return stat(file)\n .then(() => true)\n .catch(() => false);\n}\n\nexport async function readFolder(path: string) {\n if (await exist(path)) {\n return readdir(path);\n }\n return [] as string[];\n}\n\nexport async function writeFiles(\n dir: string,\n contents: Record<\n string,\n string | { content: string; ignoreIfExists?: boolean }\n >,\n) {\n return Promise.all(\n Object.entries(contents).map(async ([file, content]) => {\n const filePath = isAbsolute(file) ? file : join(dir, file);\n await mkdir(dirname(filePath), { recursive: true });\n if (typeof content === 'string') {\n await writeFile(filePath, content, 'utf-8');\n } else {\n if (content.ignoreIfExists) {\n if (!(await exist(filePath))) {\n await writeFile(filePath, content.content, 'utf-8');\n }\n }\n }\n }),\n );\n}\n\nexport async function getFolderExports(folder: string, extensions = ['ts']) {\n const files = await readdir(folder, { withFileTypes: true });\n const exports: string[] = [];\n for (const file of files) {\n if (file.isDirectory()) {\n exports.push(`export * from './${file.name}';`);\n } else if (\n file.name !== 'index.ts' &&\n extensions.includes(getExt(file.name))\n ) {\n exports.push(`export * from './${file.name}';`);\n }\n }\n return exports.join('\\n');\n}\n\nexport const getExt = (fileName?: string) => {\n if (!fileName) {\n return ''; // shouldn't happen as there will always be a file name\n }\n const lastDot = fileName.lastIndexOf('.');\n if (lastDot === -1) {\n return '';\n }\n const ext = fileName\n .slice(lastDot + 1)\n .split('/')\n .filter(Boolean)\n .join('');\n if (ext === fileName) {\n // files that have no extension\n return '';\n }\n return ext || 'txt';\n};\n", "export * from './lib/deriver.ts';\nexport * from './lib/program.ts';\nexport * from './lib/paths.ts';\nexport * from './lib/file-system.ts';\n\nexport function removeDuplicates<T>(\n data: T[],\n accessor: (item: T) => T[keyof T],\n): T[] {\n return [...new Map(data.map((x) => [accessor(x), x])).values()];\n}\n\nexport type InferRecordValue<T> = T extends Record<string, infer U> ? U : any;\n\nexport function toLitObject<T extends Record<string, any>>(\n obj: T,\n accessor: (value: InferRecordValue<T>) => string = (value) => value,\n) {\n return `{${Object.keys(obj)\n .map((key) => `${key}: ${accessor(obj[key])}`)\n .join(', ')}}`;\n}\n", "import { get, merge } from 'lodash-es';\nimport type {\n ContentObject,\n OpenAPIObject,\n OperationObject,\n ReferenceObject,\n ResponseObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase, pascalcase, spinalcase } from 'stringcase';\n\nimport { removeDuplicates } from '@sdk-it/core';\n\nimport { followRef, jsonSchemaToZod } from './json-zod.ts';\nimport { type Operation, type Spec } from './sdk.ts';\n\nexport interface NamedImport {\n name: string;\n alias?: string;\n isTypeOnly: boolean;\n}\nexport interface Import {\n isTypeOnly: boolean;\n moduleSpecifier: string;\n defaultImport: string | undefined;\n namedImports: NamedImport[];\n namespaceImport: string | undefined;\n}\nfunction isRef(obj: any): obj is ReferenceObject {\n return '$ref' in obj;\n}\n\nconst responses: Record<string, string> = {\n '400': 'BadRequest',\n '401': 'Unauthorized',\n '402': 'PaymentRequired',\n '403': 'Forbidden',\n '404': 'NotFound',\n '405': 'MethodNotAllowed',\n '406': 'NotAcceptable',\n '409': 'Conflict',\n '413': 'PayloadTooLarge',\n '410': 'Gone',\n '422': 'UnprocessableEntity',\n '429': 'TooManyRequests',\n '500': 'InternalServerError',\n '501': 'NotImplemented',\n '502': 'BadGateway',\n '503': 'ServiceUnavailable',\n '504': 'GatewayTimeout',\n};\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIObject;\n target?: 'javascript';\n /**\n * No support for jsdoc in vscode\n * @issue https://github.com/microsoft/TypeScript/issues/38106\n */\n style?: 'github';\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n}\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId'>> = {\n target: 'javascript',\n style: 'github',\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return spinalcase(operation.operationId);\n }\n return (\n operation.operationId ||\n camelcase(`${method} ${path.replace(/\\//g, ' ')}`)\n );\n },\n};\n\nexport function generateCode(config: GenerateSdkConfig) {\n const groups: Spec['groups'] = {};\n const commonSchemas: Record<string, string> = {};\n const outputs: Record<string, string> = {};\n\n for (const [path, methods] of Object.entries(config.spec.paths ?? {})) {\n for (const [method, operation] of Object.entries(methods) as [\n string,\n OperationObject,\n ][]) {\n const formatOperationId = config.operationId ?? defaults.operationId;\n const operationName = formatOperationId(operation, path, method);\n\n console.log(`Processing ${method} ${path}`);\n const groupName = (operation.tags ?? ['unknown'])[0];\n groups[groupName] ??= [];\n const inputs: Operation['inputs'] = {};\n const imports: Import[] = [];\n\n const additionalProperties = [];\n for (const param of operation.parameters ?? []) {\n if (isRef(param)) {\n throw new Error(`Found reference in parameter ${param.$ref}`);\n }\n if (!param.schema) {\n throw new Error(`Schema not found for parameter ${param.name}`);\n }\n inputs[param.name] = {\n source: param.in,\n schema: '',\n };\n additionalProperties.push(param);\n }\n\n const types: Record<string, string> = {};\n const shortContenTypeMap: Record<string, string> = {\n 'application/json': 'json',\n 'application/x-www-form-urlencoded': 'urlencoded',\n 'multipart/form-data': 'formdata',\n 'application/xml': 'xml',\n 'text/plain': 'text',\n };\n let contentType: string | undefined;\n if (operation.requestBody && Object.keys(operation.requestBody).length) {\n const content: ContentObject = isRef(operation.requestBody)\n ? get(followRef(config.spec, operation.requestBody.$ref), ['content'])\n : operation.requestBody.content;\n\n for (const type in content) {\n const schema = isRef(content[type].schema)\n ? followRef(config.spec, content[type].schema.$ref)\n : content[type].schema;\n\n types[shortContenTypeMap[type]] = jsonSchemaToZod(\n config.spec,\n merge(schema, {\n required: additionalProperties\n .filter((p) => p.required)\n .map((p) => p.name),\n properties: additionalProperties.reduce<Record<string, any>>(\n (acc, p) => ({\n ...acc,\n [p.name]: p.schema,\n }),\n {},\n ),\n }),\n true,\n (schemaName, zod) => {\n commonSchemas[schemaName] = zod;\n imports.push({\n defaultImport: undefined,\n isTypeOnly: false,\n moduleSpecifier: '../zod',\n namedImports: [{ isTypeOnly: false, name: schemaName }],\n namespaceImport: undefined,\n });\n },\n );\n }\n\n if (content['application/json']) {\n contentType = 'json';\n } else if (content['application/x-www-form-urlencoded']) {\n contentType = 'urlencoded';\n } else if (content['multipart/form-data']) {\n contentType = 'formdata';\n } else {\n contentType = 'json';\n }\n } else {\n types[shortContenTypeMap['application/json']] = jsonSchemaToZod(\n config.spec,\n {\n type: 'object',\n required: additionalProperties\n .filter((p) => p.required)\n .map((p) => p.name),\n properties: additionalProperties.reduce<Record<string, any>>(\n (acc, p) => ({\n ...acc,\n [p.name]: p.schema,\n }),\n {},\n ),\n },\n true,\n (schemaName, zod) => {\n commonSchemas[schemaName] = zod;\n imports.push({\n defaultImport: undefined,\n isTypeOnly: false,\n moduleSpecifier: './zod',\n namedImports: [{ isTypeOnly: false, name: schemaName }],\n namespaceImport: undefined,\n });\n },\n );\n }\n\n const errors: string[] = [];\n operation.responses ??= {};\n\n let foundResponse = false;\n const output = [`import z from 'zod';`];\n for (const status in operation.responses) {\n const response = operation.responses[status] as ResponseObject;\n const statusCode = +status;\n if (statusCode >= 400) {\n errors.push(responses[status] ?? 'ProblematicResponse');\n }\n if (statusCode >= 200 && statusCode < 300) {\n foundResponse = true;\n const responseContent = get(response, ['content']);\n const isJson = responseContent && responseContent['application/json'];\n // TODO: how the user is going to handle multiple response types\n const responseSchema = isJson\n ? jsonSchemaToZod(\n config.spec,\n responseContent['application/json'].schema!,\n true,\n (schemaName, zod) => {\n commonSchemas[schemaName] = zod;\n imports.push({\n defaultImport: undefined,\n isTypeOnly: false,\n moduleSpecifier: '../zod',\n namedImports: [{ isTypeOnly: false, name: schemaName }],\n namespaceImport: undefined,\n });\n },\n )\n : 'z.instanceof(ReadableStream)'; // non-json response treated as stream\n\n output.push(\n importsToString(mergeImports(Object.values(imports).flat())).join(\n '\\n',\n ),\n );\n output.push(\n `export const ${pascalcase(operationName + ' output')} = ${responseSchema}`,\n );\n }\n }\n\n if (!foundResponse) {\n output.push(\n `export const ${pascalcase(operationName + ' output')} = z.void()`,\n );\n }\n outputs[`${spinalcase(operationName)}.ts`] = output.join('\\n');\n groups[groupName].push({\n name: operationName,\n type: 'http',\n imports: mergeImports(Object.values(imports).flat()),\n inputs,\n errors: errors.length ? errors : ['ServerError'],\n contentType,\n schemas: types,\n formatOutput: () => ({\n import: pascalcase(operationName + ' output'),\n use: `z.infer<typeof ${pascalcase(operationName + ' output')}>`,\n }),\n trigger: {\n path,\n method,\n },\n });\n }\n }\n\n return { groups, commonSchemas, outputs };\n}\n\n// TODO - USE CASES\n// 1. Some parameters conflicts with request body\n// 2. Generate 400 and 500 response variations // done\n// 3. Generate 200 response variations\n// 3. Doc Security\n// 4. Operation Security\n// 5. JsDocs\n// 5. test all different types of parameters\n// 6. cookies\n// 6. x-www-form-urlencoded // done\n// 7. multipart/form-data // done\n// 7. application/octet-stream // done\n// 7. chunked response // done\n// we need to remove the stream fn in the backend\n\nfunction mergeImports(imports: Import[]) {\n const merged: Record<string, Import> = {};\n\n for (const i of imports) {\n merged[i.moduleSpecifier] = merged[i.moduleSpecifier] ?? {\n moduleSpecifier: i.moduleSpecifier,\n defaultImport: i.defaultImport,\n namespaceImport: i.namespaceImport,\n namedImports: [],\n };\n if (i.namedImports) {\n merged[i.moduleSpecifier].namedImports.push(...i.namedImports);\n }\n }\n\n return Object.values(merged);\n}\n\nfunction importsToString(imports: Import[]) {\n return imports.map((i) => {\n if (i.defaultImport) {\n return `import ${i.defaultImport} from '${i.moduleSpecifier}'`;\n }\n if (i.namespaceImport) {\n return `import * as ${i.namespaceImport} from '${i.moduleSpecifier}'`;\n }\n if (i.namedImports) {\n return `import {${removeDuplicates(i.namedImports, (it) => it.name)\n .map((n) => n.name)\n .join(', ')}} from '${i.moduleSpecifier}'`;\n }\n throw new Error(`Invalid import ${JSON.stringify(i)}`);\n });\n}\n", "import { get } from 'lodash-es';\nimport type {\n OpenAPIObject,\n ReferenceObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\n/**\n * Recursively resolve a $ref in the OpenAPI spec.\n */\n\nfunction cleanRef(ref: string) {\n return ref.replace(/^#\\//, '');\n}\n\nfunction parseRef(ref: string) {\n const parts = ref.split(ref);\n const [model] = parts.splice(-1);\n return { model, path: parts.join('/') };\n}\nexport function followRef(\n spec: OpenAPIObject,\n ref: string,\n): SchemaObject | ReferenceObject {\n // Adjust get(...) usage for your data structure\n const pathParts = cleanRef(ref).split('/');\n const entry = get(spec, pathParts) as SchemaObject | ReferenceObject;\n if (entry && '$ref' in entry) {\n return followRef(spec, entry.$ref);\n }\n return entry;\n}\n\ntype OnRefCallback = (ref: string, zod: string) => void;\n\n/**\n * Convert an OpenAPI (JSON Schema style) object into a Zod schema string,\n * adapted for OpenAPI 3.1 (fully aligned with JSON Schema 2020-12).\n */\n\nexport function jsonSchemaToZod(\n spec: OpenAPIObject,\n schema: SchemaObject | ReferenceObject,\n required = false,\n onRef: OnRefCallback,\n circularRefTracker = new Set<string>(), // Add as optional parameter with default value\n): string {\n // If it's a reference, resolve and recurse\n if ('$ref' in schema) {\n const schemaName = cleanRef(schema.$ref).split('/').pop()!;\n\n // Check for circular references\n if (circularRefTracker.has(schemaName)) {\n return schemaName;\n }\n\n circularRefTracker.add(schemaName);\n onRef(\n schemaName,\n jsonSchemaToZod(\n spec,\n followRef(spec, schema.$ref),\n required,\n onRef,\n circularRefTracker,\n ),\n );\n circularRefTracker.delete(schemaName);\n\n return schemaName;\n }\n\n // Handle allOf \u2192 intersection\n if (schema.allOf && Array.isArray(schema.allOf)) {\n const allOfSchemas = schema.allOf.map((sub) =>\n jsonSchemaToZod(spec, sub, true, onRef, circularRefTracker),\n );\n return allOfSchemas.length\n ? `z.intersection(${allOfSchemas.join(', ')})`\n : allOfSchemas[0];\n }\n\n // anyOf \u2192 union\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n const anyOfSchemas = schema.anyOf.map((sub) =>\n jsonSchemaToZod(spec, sub, false, onRef, circularRefTracker),\n );\n return anyOfSchemas.length > 1\n ? `z.union([${anyOfSchemas.join(', ')}])${appendOptional(required)}`\n : // Handle an invalid anyOf with one schema\n anyOfSchemas[0];\n }\n\n // oneOf \u2192 union\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n const oneOfSchemas = schema.oneOf.map((sub) => {\n if ('$ref' in sub) {\n const { model } = parseRef(sub.$ref);\n if (circularRefTracker.has(model)) {\n return model;\n }\n }\n return jsonSchemaToZod(spec, sub, false, onRef, circularRefTracker);\n });\n return oneOfSchemas.length > 1\n ? `z.union([${oneOfSchemas.join(', ')}])${appendOptional(required)}`\n : // Handle an invalid oneOf with one schema\n oneOfSchemas[0];\n }\n\n // enum\n if (schema.enum && Array.isArray(schema.enum)) {\n const enumVals = schema.enum.map((val) => JSON.stringify(val)).join(', ');\n return `z.enum([${enumVals}])${appendOptional(required)}`;\n }\n\n // 3.1 can have type: string or type: string[] (e.g. [\"string\",\"null\"])\n // Let's parse that carefully.\n const types = Array.isArray(schema.type)\n ? schema.type\n : schema.type\n ? [schema.type]\n : [];\n\n // If no explicit \"type\", fallback to unknown\n if (!types.length) {\n return `z.unknown()${appendOptional(required)}`;\n }\n\n // If it's a union type (like [\"string\", \"null\"]), we'll build a Zod union\n // or apply .nullable() if it's just \"type + null\".\n if (types.length > 1) {\n // If it\u2019s exactly one real type plus \"null\", we can do e.g. `z.string().nullable()`\n const realTypes = types.filter((t) => t !== 'null');\n if (realTypes.length === 1 && types.includes('null')) {\n // Single real type + \"null\"\n const typeZod = basicTypeToZod(\n realTypes[0],\n schema,\n spec,\n false,\n onRef,\n circularRefTracker,\n );\n return `${typeZod}.nullable()${appendOptional(required)}`;\n }\n // If multiple different types, build a union\n const subSchemas = types.map((t) =>\n basicTypeToZod(t, schema, spec, false, onRef, circularRefTracker),\n );\n return `z.union([${subSchemas.join(', ')}])${appendOptional(required)}`;\n }\n\n // If there's exactly one type\n return basicTypeToZod(\n types[0],\n schema,\n spec,\n required,\n onRef,\n circularRefTracker,\n );\n}\n\n/**\n * Convert a basic type (string | number | boolean | object | array, etc.) to Zod.\n * We'll also handle .optional() if needed.\n */\nfunction basicTypeToZod(\n type: string,\n schema: SchemaObject,\n spec: OpenAPIObject,\n required = false,\n onRef: OnRefCallback,\n refProcessingStack: Set<string>,\n): string {\n switch (type) {\n case 'string':\n return handleString(schema, required);\n case 'number':\n case 'integer':\n return handleNumber(schema, required);\n case 'boolean':\n return `z.boolean()${appendDefault(schema.default)}${appendOptional(required)}`;\n case 'object':\n return handleObject(schema, spec, required, onRef, refProcessingStack);\n case 'array':\n return handleArray(schema, spec, required, onRef, refProcessingStack);\n case 'null':\n // If \"type\": \"null\" alone, this is basically z.null()\n return `z.null()${appendOptional(required)}`;\n default:\n // Unknown type -> fallback\n return `z.unknown()${appendOptional(required)}`;\n }\n}\n\n/**\n * Handle a `string` schema with possible format keywords (JSON Schema).\n */\nfunction handleString(schema: SchemaObject, required?: boolean): string {\n let base = 'z.string()';\n\n // 3.1 replaces `example` in the schema with `examples` (array).\n // We do not strictly need them for the Zod type, so they\u2019re optional\n // for validation. However, we could keep them as metadata if you want.\n\n switch (schema.format) {\n case 'date-time':\n case 'datetime':\n // parse to JS Date\n base = 'z.coerce.date()';\n break;\n case 'date':\n base = 'z.coerce.date() /* or z.string() if you want raw date strings */';\n break;\n case 'time':\n base = 'z.string() /* optionally add .regex(...) for HH:MM:SS format */';\n break;\n case 'email':\n base = 'z.string().email()';\n break;\n case 'uuid':\n base = 'z.string().uuid()';\n break;\n case 'url':\n case 'uri':\n base = 'z.string().url()';\n break;\n case 'ipv4':\n base = 'z.string().ip({version: \"v4\"})';\n break;\n case 'ipv6':\n base = 'z.string().ip({version: \"v6\"})';\n break;\n case 'phone':\n base = 'z.string() /* or add .regex(...) for phone formats */';\n break;\n case 'byte':\n case 'binary':\n base = 'z.instanceof(Blob) /* consider base64 check if needed */';\n break;\n case 'int64':\n // JS numbers can't reliably store int64, consider z.bigint() or keep as string\n base = 'z.string() /* or z.bigint() if your app can handle it */';\n break;\n default:\n // No special format\n break;\n }\n\n return `${base}${appendDefault(schema.default)}${appendOptional(required)}`;\n}\n\n/**\n * Handle number/integer constraints from OpenAPI/JSON Schema.\n * In 3.1, exclusiveMinimum/Maximum hold the actual numeric threshold,\n * rather than a boolean toggling `minimum`/`maximum`.\n */\nfunction handleNumber(schema: SchemaObject, required?: boolean): string {\n let defaultValue =\n schema.default !== undefined ? `.default(${schema.default})` : ``;\n let base = 'z.number()';\n if (schema.format === 'int64') {\n base = 'z.bigint()';\n if (schema.default !== undefined) {\n defaultValue = `.default(BigInt(${schema.default}))`;\n }\n }\n\n if (schema.format === 'int32') {\n // 32-bit integer\n base += '.int()';\n }\n\n // If we see exclusiveMinimum as a number in 3.1:\n if (typeof schema.exclusiveMinimum === 'number') {\n // Zod doesn\u2019t have a direct \"exclusiveMinimum\" method, so we can do .gt()\n // If exclusiveMinimum=7 => .gt(7)\n base += `.gt(${schema.exclusiveMinimum})`;\n }\n // Similarly for exclusiveMaximum\n if (typeof schema.exclusiveMaximum === 'number') {\n // If exclusiveMaximum=10 => .lt(10)\n base += `.lt(${schema.exclusiveMaximum})`;\n }\n\n // If standard minimum/maximum\n if (typeof schema.minimum === 'number') {\n base +=\n schema.format === 'int64'\n ? `.min(BigInt(${schema.minimum}))`\n : `.min(${schema.minimum})`;\n }\n if (typeof schema.maximum === 'number') {\n base +=\n schema.format === 'int64'\n ? `.max(BigInt(${schema.maximum}))`\n : `.max(${schema.maximum})`;\n }\n\n // multipleOf\n if (typeof schema.multipleOf === 'number') {\n // There's no direct multipleOf in Zod. Some folks do a custom refine.\n // For example:\n base += `.refine((val) => Number.isInteger(val / ${schema.multipleOf}), \"Must be a multiple of ${schema.multipleOf}\")`;\n }\n\n return `${base}${defaultValue}${appendOptional(required)}`;\n}\n\n/**\n * Handle objects (properties, additionalProperties).\n */\nfunction handleObject(\n schema: SchemaObject,\n spec: OpenAPIObject,\n required = false,\n onRef: OnRefCallback,\n refProcessingStack: Set<string>,\n): string {\n const properties = schema.properties || {};\n\n // Convert each property\n const propEntries = Object.entries(properties).map(([key, propSchema]) => {\n const isRequired = (schema.required ?? []).includes(key);\n const zodPart = jsonSchemaToZod(\n spec,\n propSchema,\n isRequired,\n onRef,\n refProcessingStack,\n );\n return `'${key}': ${zodPart}`;\n });\n\n // additionalProperties\n let additionalProps = '';\n if (schema.additionalProperties) {\n if (typeof schema.additionalProperties === 'object') {\n // e.g. z.record() if it\u2019s an object schema\n const addPropZod = jsonSchemaToZod(\n spec,\n schema.additionalProperties,\n true,\n onRef,\n refProcessingStack,\n );\n additionalProps = `.catchall(${addPropZod})`;\n } else if (schema.additionalProperties === true) {\n // free-form additional props\n additionalProps = `.catchall(z.unknown())`;\n }\n }\n\n const objectSchema = `z.object({${propEntries.join(', ')}})${additionalProps}`;\n return `${objectSchema}${appendOptional(required)}`;\n}\n\n/**\n * Handle arrays (items could be a single schema or a tuple (array of schemas)).\n * In JSON Schema 2020-12, `items` can be an array \u2192 tuple style.\n */\nfunction handleArray(\n schema: SchemaObject,\n spec: OpenAPIObject,\n required = false,\n onRef: OnRefCallback,\n refProcessingStack: Set<string>,\n): string {\n const { items } = schema;\n if (!items) {\n // No items => z.array(z.unknown())\n return `z.array(z.unknown())${appendOptional(required)}`;\n }\n\n // If items is an array => tuple\n if (Array.isArray(items)) {\n // Build a Zod tuple\n const tupleItems = items.map((sub) =>\n jsonSchemaToZod(spec, sub, true, onRef, refProcessingStack),\n );\n const base = `z.tuple([${tupleItems.join(', ')}])`;\n // // If we have additionalItems: false => that\u2019s a fixed length\n // // If additionalItems is a schema => rest(...)\n // if (schema.additionalItems) {\n // if (typeof schema.additionalItems === 'object') {\n // const restSchema = jsonSchemaToZod(spec, schema.additionalItems, true);\n // base += `.rest(${restSchema})`;\n // }\n // // If `additionalItems: false`, no rest is allowed => do nothing\n // }\n return `${base}${appendOptional(required)}`;\n }\n\n // If items is a single schema => standard z.array(...)\n const itemsSchema = jsonSchemaToZod(\n spec,\n items,\n true,\n onRef,\n refProcessingStack,\n );\n return `z.array(${itemsSchema})${appendOptional(required)}`;\n}\n\n/**\n * Append .optional() if not required\n */\nfunction appendOptional(isRequired?: boolean) {\n return isRequired ? '' : '.optional()';\n}\nfunction appendDefault(defaultValue?: any) {\n return defaultValue !== undefined\n ? `.default(${JSON.stringify(defaultValue)})`\n : '';\n}\n\n// Todo: convert openapi 3.0 to 3.1 before proccesing\n", "import { camelcase, pascalcase, spinalcase } from 'stringcase';\n\nimport { removeDuplicates, toLitObject } from '@sdk-it/core';\n\nimport backend from './client.ts';\n\nexport interface Import {\n isTypeOnly: boolean;\n moduleSpecifier: string;\n defaultImport: string | undefined;\n namedImports: NamedImport[];\n namespaceImport: string | undefined;\n}\nexport interface NamedImport {\n name: string;\n alias?: string;\n isTypeOnly: boolean;\n}\n\nclass SchemaEndpoint {\n #imports: string[] = [\n `import z from 'zod';`,\n 'import type { Endpoints } from \"./endpoints.ts\";',\n `import { toRequest, json, urlencoded, formdata, createUrl } from './http/request.ts';`,\n `import type { ParseError } from './http/parser.ts';`,\n ];\n #endpoints: string[] = [];\n addEndpoint(endpoint: string, operation: any) {\n this.#endpoints.push(` \"${endpoint}\": ${operation},`);\n }\n addImport(value: string) {\n this.#imports.push(value);\n }\n complete() {\n return `${this.#imports.join('\\n')}\\nexport default {\\n${this.#endpoints.join('\\n')}\\n}`;\n }\n}\nclass Emitter {\n protected imports: string[] = [\n `import z from 'zod';`,\n `import type { ParseError } from './http/parser.ts';`,\n ];\n protected endpoints: string[] = [];\n addEndpoint(endpoint: string, operation: any) {\n this.endpoints.push(` \"${endpoint}\": ${operation};`);\n }\n addImport(value: string) {\n this.imports.push(value);\n }\n complete() {\n return `${this.imports.join('\\n')}\\nexport interface Endpoints {\\n${this.endpoints.join('\\n')}\\n}`;\n }\n}\nclass StreamEmitter extends Emitter {\n override complete() {\n return `${this.imports.join('\\n')}\\nexport interface StreamEndpoints {\\n${this.endpoints.join('\\n')}\\n}`;\n }\n}\n\nexport interface SecurityScheme {\n bearerAuth: {\n type: 'http';\n scheme: 'bearer';\n bearerFormat: 'JWT';\n };\n}\n\nexport interface SdkConfig {\n /**\n * The name of the sdk client\n */\n name: string;\n packageName?: string;\n options?: Record<string, any>;\n emptyBodyAsNull?: boolean;\n stripBodyFromGetAndHead?: boolean;\n securityScheme?: SecurityScheme;\n output: string;\n formatGeneratedCode?: boolean;\n}\n\nexport interface Spec {\n groups: Record<string, Operation[]>;\n commonZod?: string;\n name: string;\n options?: Record<\n string,\n {\n in: 'header';\n schema: string;\n }\n >;\n securityScheme?: SecurityScheme;\n servers?: string[];\n}\n\nexport interface OperationInput {\n source: string;\n schema: string;\n}\nexport interface Operation {\n name: string;\n errors: string[];\n type: string;\n imports: Import[];\n trigger: Record<string, any>;\n contentType?: string;\n schemas: Record<string, string>;\n schema?: string;\n inputs: Record<string, OperationInput>;\n formatOutput: () => { import: string; use: string };\n}\n\nexport function generateClientSdk(spec: Spec) {\n const emitter = new Emitter();\n const streamEmitter = new StreamEmitter();\n const schemas: Record<string, string[]> = {};\n const schemasImports: string[] = [];\n const schemaEndpoint = new SchemaEndpoint();\n const errors: string[] = [];\n for (const [name, operations] of Object.entries(spec.groups)) {\n const featureSchemaFileName = camelcase(name);\n schemas[featureSchemaFileName] = [`import z from 'zod';`];\n emitter.addImport(\n `import * as ${featureSchemaFileName} from './inputs/${featureSchemaFileName}.ts';`,\n );\n streamEmitter.addImport(\n `import * as ${featureSchemaFileName} from './inputs/${featureSchemaFileName}.ts';`,\n );\n schemaEndpoint.addImport(\n `import * as ${featureSchemaFileName} from './inputs/${featureSchemaFileName}.ts';`,\n );\n for (const operation of operations) {\n const schemaName = camelcase(`${operation.name} schema`);\n\n const schema = `export const ${schemaName} = ${\n Object.keys(operation.schemas).length === 1\n ? Object.values(operation.schemas)[0]\n : toLitObject(operation.schemas)\n };`;\n\n schemas[featureSchemaFileName].push(schema);\n schemasImports.push(\n ...operation.imports\n .map((it) => (it.namedImports ?? []).map((it) => it.name))\n .flat(),\n );\n const schemaRef = `${featureSchemaFileName}.${schemaName}`;\n const output = operation.formatOutput();\n const inputHeaders: string[] = [];\n const inputQuery: string[] = [];\n const inputBody: string[] = [];\n const inputParams: string[] = [];\n for (const [name, prop] of Object.entries(operation.inputs)) {\n if (prop.source === 'headers' || prop.source === 'header') {\n inputHeaders.push(`\"${name}\"`);\n } else if (prop.source === 'query') {\n inputQuery.push(`\"${name}\"`);\n } else if (prop.source === 'body') {\n inputBody.push(`\"${name}\"`);\n } else if (prop.source === 'path') {\n inputParams.push(`\"${name}\"`);\n } else if (prop.source === 'internal') {\n // ignore internal sources\n continue;\n } else {\n throw new Error(\n `Unknown source ${prop.source} in ${name} ${JSON.stringify(\n prop,\n )} in ${operation.name}`,\n );\n }\n }\n if (operation.type === 'sse') {\n const input = `z.infer<typeof ${schemaRef}>`;\n const endpoint = `${operation.trigger.method.toUpperCase()} ${operation.trigger.path}`;\n streamEmitter.addImport(\n `import type {${pascalcase(operation.name)}} from './outputs/${spinalcase(operation.name)}';`,\n );\n streamEmitter.addEndpoint(\n endpoint,\n `{input: ${input}, output: ${output.use}}`,\n );\n schemaEndpoint.addEndpoint(\n endpoint,\n `{\n schema: ${schemaRef},\n toRequest(input: StreamEndpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Record<string, string>}) {\n const endpoint = '${endpoint}';\n return toRequest(endpoint, json(input, {\n inputHeaders: [${inputHeaders}],\n inputQuery: [${inputQuery}],\n inputBody: [${inputBody}],\n inputParams: [${inputParams}],\n }), init);\n },\n }`,\n );\n } else {\n emitter.addImport(\n `import type {${output.import}} from './outputs/${spinalcase(operation.name)}';`,\n );\n errors.push(...(operation.errors ?? []));\n\n const addTypeParser = Object.keys(operation.schemas).length > 1;\n for (const type in operation.schemas ?? {}) {\n let typePrefix = '';\n if (addTypeParser && type !== 'json') {\n typePrefix = `${type} `;\n }\n const input = `typeof ${schemaRef}${addTypeParser ? `.${type}` : ''}`;\n\n const endpoint = `${typePrefix}${operation.trigger.method.toUpperCase()} ${operation.trigger.path}`;\n emitter.addEndpoint(\n endpoint,\n `{input: z.infer<${input}>; output: ${output.use}; error: ${(operation.errors ?? ['ServerError']).concat(`ParseError<${input}>`).join('|')}}`,\n );\n schemaEndpoint.addEndpoint(\n endpoint,\n `{\n schema: ${schemaRef}${addTypeParser ? `.${type}` : ''},\n toRequest(input: Endpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Record<string, string>}) {\n const endpoint = '${endpoint}';\n return toRequest(endpoint, ${operation.contentType || 'json'}(input, {\n inputHeaders: [${inputHeaders}],\n inputQuery: [${inputQuery}],\n inputBody: [${inputBody}],\n inputParams: [${inputParams}],\n }), init);\n },\n }`,\n );\n }\n }\n }\n }\n\n emitter.addImport(\n `import type { ${removeDuplicates(errors, (it) => it).join(', ')} } from './http/response.ts';`,\n );\n return {\n ...Object.fromEntries(\n Object.entries(schemas).map(([key, value]) => [\n `inputs/${key}.ts`,\n [\n schemasImports.length\n ? `import {${removeDuplicates(schemasImports, (it) => it)}} from '../zod';`\n : '',\n spec.commonZod ? 'import * as commonZod from \"../zod.ts\";' : '',\n ...value,\n ]\n .map((it) => it.trim())\n .filter(Boolean)\n .join('\\n') + '\\n', // add a newline at the end\n ]),\n ),\n 'backend.ts': backend(spec),\n 'schemas.ts': schemaEndpoint.complete(),\n 'endpoints.ts': emitter.complete(),\n };\n}\n", "import { titlecase } from 'stringcase';\n\nimport { toLitObject } from '@sdk-it/core';\n\nimport type { Spec } from './sdk.ts';\n\nexport default (spec: Spec) => {\n const specOptions: Record<string, { schema: string }> = {\n ...(spec.options ?? {}),\n fetch: {\n schema: 'fetchType',\n },\n baseUrl: {\n schema: `z.enum(servers).default(servers[0])`,\n },\n };\n if (spec.securityScheme) {\n specOptions['token'] = { schema: 'z.string().optional()' };\n }\n const defaultHeaders = spec.securityScheme\n ? `{Authorization: \\`${titlecase(spec.securityScheme.bearerAuth.scheme)} \\${this.options.token}\\`}`\n : `{}`;\n\n return `\nimport { fetchType, sendRequest } from './http/send-request.ts';\nimport z from 'zod';\nimport type { Endpoints } from './endpoints.ts';\nimport schemas from './schemas.ts';\n\n const servers = ${JSON.stringify(spec.servers || [], null, 2)} as const;\n const optionsSchema = z.object(${toLitObject(specOptions, (x) => x.schema)});\n type ${spec.name}Options = z.infer<typeof optionsSchema>;\n export class ${spec.name} {\n\n constructor(public options: ${spec.name}Options) {}\n\n async request<E extends keyof Endpoints>(\n endpoint: E,\n input: Endpoints[E]['input'],\n ): Promise<readonly [Endpoints[E]['output'], Endpoints[E]['error'] | null]> {\n const route = schemas[endpoint];\n return sendRequest(input, route, {\n baseUrl: this.options.baseUrl,\n fetch: this.options.fetch,\n headers: this.defaultHeaders,\n });\n }\n\n get defaultHeaders() {\n return ${defaultHeaders}\n }\n\n setOptions(options: Partial<${spec.name}Options>) {\n const validated = optionsSchema.partial().parse(options);\n\n for (const key of Object.keys(validated) as (keyof ${spec.name}Options)[]) {\n if (validated[key] !== undefined) {\n (this.options[key] as typeof validated[typeof key]) = validated[key]!;\n }\n }\n }\n}`;\n};\n", "import { parse } from 'fast-content-type-parse';\n\nexport async function handleError(response: Response) {\n try {\n if (response.status >= 400 && response.status < 500) {\n const body = (await response.json()) as Record<string, any>;\n return {\n status: response.status,\n body: body,\n };\n }\n return new Error(\n `An error occurred while fetching the data. Status: ${response.status}`,\n );\n } catch (error) {\n return error as any;\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 async function parseResponse(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 const isChunked = response.headers.get('Transfer-Encoding') === 'chunked';\n if (isChunked) {\n return response.body!;\n // return handleChunkedResponse(response, contentType);\n }\n\n const { type } = parse(contentType);\n switch (type) {\n case 'application/json':\n return response.json();\n case 'text/plain':\n return response.text();\n case 'text/html':\n return response.text();\n case 'text/xml':\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", "import { z } from 'zod';\n\nexport type ParseError<T extends z.ZodType<any, any, any>> = {\n kind: 'parse';\n} & z.inferFlattenedErrors<T>;\n\nexport function parse<T extends z.ZodType>(\n schema: T,\n input: unknown,\n) {\n const result = schema.safeParse(input);\n if (!result.success) {\n const errors = result.error.flatten((issue) => issue);\n return [null, errors];\n }\n return [result.data as z.infer<T>, null];\n}\n", "type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\ntype ContentType = 'xml' | 'json' | 'urlencoded' | 'multipart';\ntype Endpoint = `${ContentType} ${Method} ${string}` | `${Method} ${string}`;\n\nexport function createUrl(base: string, path: string, query: URLSearchParams) {\n const url = new URL(path, base);\n url.search = query.toString();\n return url;\n}\nfunction template(\n templateString: string,\n templateVariables: Record<string, any>,\n): string {\n const nargs = /{([0-9a-zA-Z_]+)}/g;\n return templateString.replace(nargs, (match, key: string, index: number) => {\n // Handle escaped double braces\n if (\n templateString[index - 1] === '{' &&\n templateString[index + match.length] === '}'\n ) {\n return key;\n }\n\n const result = key in templateVariables ? templateVariables[key] : null;\n return result === null || result === undefined ? '' : String(result);\n });\n}\n\ninterface ToRequest {\n <T extends Endpoint>(\n endpoint: T,\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n defaults: {\n baseUrl: string;\n headers?: Record<string, string>;\n },\n ): Request;\n urlencoded: <T extends Endpoint>(\n endpoint: T,\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n defaults: {\n baseUrl: string;\n headers?: Record<string, string>;\n },\n ) => Request;\n}\n\nfunction _json(\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n) {\n const headers = new Headers({});\n for (const header of props.inputHeaders) {\n headers.set(header, input[header]);\n }\n\n const body: Record<string, any> = {};\n for (const prop of props.inputBody) {\n body[prop] = input[prop];\n }\n\n const query = new URLSearchParams();\n for (const key of props.inputQuery) {\n const value = input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = props.inputParams.reduce<Record<string, any>>((acc, key) => {\n acc[key] = input[key];\n return acc;\n }, {});\n\n return {\n body: JSON.stringify(body),\n query,\n params,\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n };\n}\n\ntype Input = Record<string, any>;\ntype Props = {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n};\n\nabstract class Serializer {\n constructor(\n protected input: Input,\n protected props: Props,\n ) {}\n abstract getBody(): BodyInit | null;\n abstract getHeaders(): Record<string, string>;\n serialize(): Serialized {\n const headers = new Headers({});\n for (const header of this.props.inputHeaders) {\n headers.set(header, this.input[header]);\n }\n\n const query = new URLSearchParams();\n for (const key of this.props.inputQuery) {\n const value = this.input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = this.props.inputParams.reduce<Record<string, any>>(\n (acc, key) => {\n acc[key] = this.input[key];\n return acc;\n },\n {},\n );\n\n return {\n body: this.getBody(),\n query,\n params,\n headers: this.getHeaders(),\n };\n }\n}\n\ninterface Serialized {\n body: BodyInit | null;\n query: URLSearchParams;\n params: Record<string, any>;\n headers: Record<string, string>;\n}\n\nclass JsonSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body: Record<string, any> = {};\n for (const prop of this.props.inputBody) {\n body[prop] = this.input[prop];\n }\n return JSON.stringify(body);\n }\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n\nclass UrlencodedSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new URLSearchParams();\n for (const prop of this.props.inputBody) {\n body.set(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nclass FormDataSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new FormData();\n for (const prop of this.props.inputBody) {\n body.append(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nexport function json(input: Input, props: Props) {\n return new JsonSerializer(input, props).serialize();\n}\nexport function urlencoded(input: Input, props: Props) {\n return new UrlencodedSerializer(input, props).serialize();\n}\nexport function formdata(input: Input, props: Props) {\n return new FormDataSerializer(input, props).serialize();\n}\n\nexport function _urlencoded(\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n) {\n const headers = new Headers({});\n for (const header of props.inputHeaders) {\n headers.set(header, input[header]);\n }\n\n const body = new URLSearchParams();\n for (const prop of props.inputBody) {\n body.set(prop, input[prop]);\n }\n\n const query = new URLSearchParams();\n for (const key of props.inputQuery) {\n const value = input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = props.inputParams.reduce<Record<string, any>>((acc, key) => {\n acc[key] = input[key];\n return acc;\n }, {});\n\n return {\n body,\n query,\n params,\n headers: {},\n };\n}\n\nexport function toRequest<T extends Endpoint>(\n endpoint: T,\n input: Serialized,\n defaults: {\n baseUrl: string;\n headers?: Record<string, string>;\n },\n): Request {\n const [method, path] = endpoint.split(' ');\n\n const headers = new Headers({\n ...defaults?.headers,\n ...input.headers,\n });\n const pathVariable = template(path, input.params);\n\n const url = createUrl(defaults.baseUrl, pathVariable, input.query);\n return new Request(url, {\n method: method,\n headers: headers,\n body: method === 'GET' ? undefined : input.body,\n });\n}\n", "export interface ApiResponse<Status extends number, Body extends unknown> {\n kind: 'response';\n status: Status;\n body: Body;\n}\n\n// 4xx Client Errors\nexport type BadRequest = ApiResponse<400, { message: string }>;\nexport type Unauthorized = ApiResponse<401, { message: string }>;\nexport type PaymentRequired = ApiResponse<402, { message: string }>;\nexport type Forbidden = ApiResponse<403, { message: string }>;\nexport type NotFound = ApiResponse<404, { message: string }>;\nexport type MethodNotAllowed = ApiResponse<405, { message: string }>;\nexport type NotAcceptable = ApiResponse<406, { message: string }>;\nexport type Conflict = ApiResponse<409, { message: string }>;\nexport type Gone = ApiResponse<410, { message: string }>;\nexport type UnprocessableEntity = ApiResponse<422, { message: string; errors?: Record<string, string[]> }>;\nexport type TooManyRequests = ApiResponse<429, { message: string; retryAfter?: string }>;\nexport type PayloadTooLarge = ApiResponse<413, { message: string; }>;\nexport type UnsupportedMediaType = ApiResponse<415, { message: string; }>;\n\n// 5xx Server Errors\nexport type InternalServerError = ApiResponse<500, { message: string }>;\nexport type NotImplemented = ApiResponse<501, { message: string }>;\nexport type BadGateway = ApiResponse<502, { message: string }>;\nexport type ServiceUnavailable = ApiResponse<503, { message: string; retryAfter?: string }>;\nexport type GatewayTimeout = ApiResponse<504, { message: string }>;\n\nexport type ClientError =\n | BadRequest\n | Unauthorized\n | PaymentRequired\n | Forbidden\n | NotFound\n | MethodNotAllowed\n | NotAcceptable\n | Conflict\n | Gone\n | UnprocessableEntity\n | TooManyRequests;\n\nexport type ServerError =\n | InternalServerError\n | NotImplemented\n | BadGateway\n | ServiceUnavailable\n | GatewayTimeout;\n\nexport type ProblematicResponse = ClientError | ServerError;\n", "import z from 'zod';\n\nimport { handleError, parseResponse } from './parse-response.ts';\nimport { parse } from './parser.ts';\n\nexport interface RequestSchema {\n schema: z.ZodType;\n toRequest: (\n input: any,\n init: { baseUrl: string; headers?: Record<string, string> },\n ) => any;\n}\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 sendRequest(\n input: any,\n route: RequestSchema,\n options: {\n baseUrl: string;\n fetch?: z.infer<typeof fetchType>;\n headers?: Record<string, string>;\n },\n) {\n const [parsedInput, parseError] = parse(route.schema, input);\n if (parseError) {\n return [null as never, { ...parseError, kind: 'parse' } as never] as const;\n }\n const request = route.toRequest(parsedInput as never, {\n headers: options.headers,\n baseUrl: options.baseUrl,\n });\n const response = await (options.fetch ?? fetch)(request);\n if (response.ok) {\n const data = await parseResponse(response);\n return [data, null] as const;\n }\n const error = await handleError(response);\n return [null as never, { ...error, kind: 'response' }] as const;\n}\n", "import type {\n ExampleObject,\n OpenAPIObject,\n OperationObject,\n ParameterObject,\n PathItemObject,\n ReferenceObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n Server,\n ServerObject,\n} from 'openapi3-ts/oas31';\nimport { pascalcase } from 'stringcase';\n\nimport { type Method } from '@sdk-it/core';\n\nimport { followRef } from './json-zod.ts';\n\n/**\n * Generate README.md documentation directly from OpenAPI spec\n */\nexport function generateReadme(\n spec: OpenAPIObject,\n settings: { name: string },\n): string {\n const title = spec.info?.title || 'API Client';\n const description =\n spec.info?.description || 'API client generated from OpenAPI specification';\n const version = spec.info?.version || '1.0.0';\n\n // Get server URLs if available\n const servers = spec.servers || [];\n const defaultServerUrl =\n servers.length > 0 ? servers[0].url : 'https://api.example.com';\n\n // Security scheme\n const securityScheme = extractSecurityScheme(spec);\n\n // Extract all operations and organize by tags\n const operationsByTag = extractOperationsByTag(spec);\n\n // Header section\n let markdown = `# ${title} SDK\\n\\n`;\n markdown += `${description}\\n\\n`;\n markdown += `Version: ${version}\\n\\n`;\n\n // Installation section\n markdown += `## Installation\\n\\n`;\n markdown += `\\`\\`\\`bash\\n`;\n markdown += `npm install ${title.toLowerCase().replace(/\\s+/g, '-')}-sdk\\n`;\n markdown += `\\`\\`\\`\\n\\n`;\n\n // Getting started section\n markdown += `## Getting Started\\n\\n`;\n markdown += `\\`\\`\\`typescript\\n`;\n markdown += `import { ${settings.name} } from '${title.toLowerCase().replace(/\\s+/g, '-')}-sdk';\\n\\n`;\n markdown += `// Initialize the client\\n`;\n markdown += `const client = new ${settings.name}({\\n`;\n markdown += ` baseUrl: '${defaultServerUrl}',\\n`;\n\n // Add security if needed\n if (securityScheme) {\n markdown += ` token: 'your-auth-token', // Required for authenticated endpoints\\n`;\n }\n\n markdown += `});\\n\\n`;\n markdown += `// Example request\\n`;\n\n // Generate example using first available endpoint\n const firstTag = Object.keys(operationsByTag)[0];\n if (firstTag && operationsByTag[firstTag].length > 0) {\n const firstOp = operationsByTag[firstTag][0];\n const exampleParams = generateExampleParams(firstOp.operation, spec);\n\n markdown += `const [data, error] = await client.request('${firstOp.method.toUpperCase()} ${firstOp.path}', ${\n Object.keys(exampleParams).length > 0\n ? formatExample(exampleParams)\n : '{}\\n'\n });\\n\\n`;\n } else {\n markdown += `const [data, error] = await client.request('GET /example', {});\\n\\n`;\n }\n\n markdown += `if (error) {\\n`;\n markdown += ` console.error('Error:', error);\\n`;\n markdown += `} else {\\n`;\n markdown += ` console.log('Success:', data);\\n`;\n markdown += `}\\n`;\n markdown += `\\`\\`\\`\\n\\n`;\n\n // API Reference section\n markdown += `## API Reference\\n\\n`;\n\n // Group operations by tag\n for (const [tagName, operations] of Object.entries(operationsByTag)) {\n markdown += `### ${pascalcase(tagName)}\\n\\n`;\n\n for (const opInfo of operations) {\n markdown += generateEndpointDocs(spec, opInfo);\n }\n }\n\n // Add servers section if available\n if (servers.length > 0) {\n markdown += generateServersSection(servers);\n }\n\n return markdown;\n}\n\ninterface OperationInfo {\n path: string;\n method: Method;\n operation: OperationObject;\n errors: string[];\n inputs: Record<string, { source: string }>;\n}\n\n/**\n * Extract operations from spec and organize by tags\n */\nfunction extractOperationsByTag(\n spec: OpenAPIObject,\n): Record<string, OperationInfo[]> {\n const operationsByTag: Record<string, OperationInfo[]> = {};\n\n // Process all paths and their operations\n for (const [path, pathItem] of Object.entries(spec.paths || {})) {\n for (const [methodName, operation] of Object.entries(pathItem || {})) {\n // Skip non-operation properties like parameters, etc.\n if (\n ['parameters', 'servers', 'summary', 'description', '$ref'].includes(\n methodName,\n )\n ) {\n continue;\n }\n\n const method = methodName.toLowerCase() as Method;\n const opObject = operation as OperationObject;\n\n // Determine tags, defaulting to 'general' if none specified\n const tags = opObject.tags?.length ? opObject.tags : ['general'];\n\n // Extract error responses\n const errors = extractErrorResponses(opObject.responses || {});\n\n // Extract inputs (parameters)\n const inputs = extractInputs(opObject, spec);\n\n // Create operation info\n const opInfo: OperationInfo = {\n path,\n method,\n operation: opObject,\n errors,\n inputs,\n };\n\n // Add operation to each of its tags\n for (const tag of tags) {\n operationsByTag[tag] = operationsByTag[tag] || [];\n operationsByTag[tag].push(opInfo);\n }\n }\n }\n\n return operationsByTag;\n}\n\n/**\n * Extract error responses from operation responses\n */\nfunction extractErrorResponses(\n responses: Record<string, ResponseObject | ReferenceObject>,\n): string[] {\n const errorNames: string[] = [];\n const responseMap: Record<string, string> = {\n '400': 'BadRequest',\n '401': 'Unauthorized',\n '403': 'Forbidden',\n '404': 'NotFound',\n '405': 'MethodNotAllowed',\n '409': 'Conflict',\n '422': 'UnprocessableEntity',\n '429': 'TooManyRequests',\n '500': 'InternalServerError',\n '502': 'BadGateway',\n '503': 'ServiceUnavailable',\n };\n\n for (const [code, _] of Object.entries(responses)) {\n const statusCode = parseInt(code, 10);\n if (statusCode >= 400) {\n const errorName = responseMap[code] || `Error${code}`;\n errorNames.push(errorName);\n }\n }\n\n return errorNames.length ? errorNames : ['ServerError'];\n}\n\n/**\n * Extract input parameters from an operation\n */\nfunction extractInputs(\n operation: OperationObject,\n spec: OpenAPIObject,\n): Record<string, { source: string }> {\n const inputs: Record<string, { source: string }> = {};\n\n // Process path, query, header parameters\n for (const param of operation.parameters || []) {\n const parameter = isReferenceObject(param)\n ? (followRef(spec, param.$ref) as ParameterObject)\n : param;\n\n inputs[parameter.name] = { source: parameter.in };\n }\n\n // Process request body properties as inputs\n if (operation.requestBody) {\n const requestBody = isReferenceObject(operation.requestBody)\n ? (followRef(spec, operation.requestBody.$ref) as RequestBodyObject)\n : operation.requestBody;\n\n if (requestBody.content?.['application/json']?.schema) {\n const schema = requestBody.content['application/json'].schema;\n const schemaObj = isReferenceObject(schema)\n ? (followRef(spec, schema.$ref) as SchemaObject)\n : schema;\n\n if (schemaObj.properties) {\n for (const propName of Object.keys(schemaObj.properties)) {\n inputs[propName] = { source: 'body' };\n }\n }\n }\n }\n\n return inputs;\n}\n\n/**\n * Extract security scheme from OpenAPI spec\n */\nfunction extractSecurityScheme(spec: OpenAPIObject) {\n if (spec.components?.securitySchemes?.bearerAuth) {\n const scheme = spec.components.securitySchemes.bearerAuth;\n if (\n typeof scheme === 'object' &&\n !('$ref' in scheme) &&\n scheme.type === 'http' &&\n scheme.scheme === 'bearer'\n ) {\n return {\n bearerAuth: {\n type: 'http',\n scheme: 'bearer',\n bearerFormat: scheme.bearerFormat || 'JWT',\n },\n };\n }\n }\n return undefined;\n}\n\n/**\n * Generate documentation for a single endpoint\n */\nfunction generateEndpointDocs(\n spec: OpenAPIObject,\n opInfo: OperationInfo,\n): string {\n const { path, method, operation, errors, inputs } = opInfo;\n let markdown = `#### \\`${method.toUpperCase()} ${path}\\`\\n\\n`;\n\n if (operation.summary) {\n markdown += `**Summary:** ${operation.summary}\\n\\n`;\n }\n\n if (operation.description) {\n markdown += `**Description:** ${operation.description}\\n\\n`;\n }\n\n // Document request parameters\n if (Object.keys(inputs).length > 0) {\n markdown += `**Parameters:**\\n\\n`;\n markdown += `| Name | Source | Required | Description | Example |\\n`;\n markdown += `| ---- | ------ | -------- | ----------- | ------- |\\n`;\n\n for (const [name, input] of Object.entries(inputs)) {\n const param = findParameterByName(operation, name, spec);\n\n const description =\n param && 'description' in param ? param.description || '-' : '-';\n const required =\n param && 'required' in param ? (param.required ? 'Yes' : 'No') : 'No';\n\n // Get example from parameter, schema, or schema.example\n const example = extractExample(param, spec);\n markdown += `| ${name} | ${input.source} | ${required} | ${description} | ${example} |\\n`;\n }\n markdown += `\\n`;\n }\n\n // Example usage\n markdown += `**Example:**\\n\\n`;\n markdown += `\\`\\`\\`typescript\\n`;\n\n // Generate example with actual examples from schema\n const exampleParams = generateExampleParams(operation, spec);\n markdown += `const [data, error] = await client.request('${method.toUpperCase()} ${path}', ${\n Object.keys(exampleParams).length > 0\n ? formatExample(exampleParams)\n : '{}\\n'\n });\\n`;\n markdown += `\\`\\`\\`\\n\\n`;\n\n // Possible errors\n if (errors.length > 0) {\n markdown += `**Possible Errors:**\\n\\n`;\n for (const error of errors) {\n markdown += `- \\`${error}\\`\\n`;\n }\n markdown += `\\n`;\n }\n\n // Example response if available\n if (operation.responses) {\n const responseExample = getResponseExample(spec, operation);\n if (responseExample) {\n markdown += `**Example Response:**\\n\\n`;\n markdown += `\\`\\`\\`json\\n${responseExample}\\n\\`\\`\\`\\n\\n`;\n }\n }\n\n return markdown;\n}\n\n/**\n * Extract example value from parameter, schema, or examples\n */\nfunction extractExample(param: any, spec: OpenAPIObject): string {\n if (!param) return '-';\n\n // Direct example on parameter\n if ('example' in param && param.example !== undefined) {\n return formatExampleValue(param.example);\n }\n\n // Parameter has examples object\n if (\n 'examples' in param &&\n param.examples &&\n Object.keys(param.examples).length > 0\n ) {\n const firstExampleKey = Object.keys(param.examples)[0];\n const exampleObj = param.examples[firstExampleKey];\n\n if (isExampleObject(exampleObj)) {\n return formatExampleValue(exampleObj.value);\n }\n\n if (isReferenceObject(exampleObj)) {\n const refExample = followRef(spec, exampleObj.$ref);\n if (isExampleObject(refExample)) {\n return formatExampleValue((refExample as any).value);\n }\n }\n }\n\n // Look for example in schema\n if ('schema' in param && param.schema) {\n const schema = isReferenceObject(param.schema)\n ? followRef(spec, param.schema.$ref)\n : param.schema;\n\n if ('example' in schema && schema.example !== undefined) {\n return formatExampleValue(schema.example);\n }\n\n if (\n 'examples' in schema &&\n Array.isArray(schema.examples) &&\n schema.examples.length > 0\n ) {\n return formatExampleValue(schema.examples[0]);\n }\n }\n\n return '-';\n}\n\n/**\n * Get example JSON for successful response\n */\nfunction getResponseExample(\n spec: OpenAPIObject,\n opObject: OperationObject,\n): string | null {\n const successResponses = Object.entries(opObject.responses ?? {}).filter(\n ([code]) => code.startsWith('2'),\n );\n\n if (successResponses.length === 0) return null;\n\n const [_, response] = successResponses[0];\n const responseObj = isReferenceObject(response)\n ? followRef(spec, response.$ref)\n : response;\n\n // Check for examples in the response\n if (responseObj.content?.['application/json']?.examples) {\n const firstExample = Object.values(\n responseObj.content['application/json'].examples,\n )[0];\n\n if (isExampleObject(firstExample)) {\n return JSON.stringify(firstExample.value, null, 2);\n }\n\n if (isReferenceObject(firstExample)) {\n const exampleRef = followRef(spec, firstExample.$ref);\n if (isExampleObject(exampleRef)) {\n return JSON.stringify((exampleRef as any).value, null, 2);\n }\n }\n }\n\n // Check for direct example\n if (responseObj.content?.['application/json']?.example) {\n return JSON.stringify(\n responseObj.content['application/json'].example,\n null,\n 2,\n );\n }\n\n // Check schema for example\n if (responseObj.content?.['application/json']?.schema) {\n const schema = responseObj.content['application/json'].schema;\n const schemaObj = isReferenceObject(schema)\n ? followRef(spec, schema.$ref)\n : schema;\n\n if ('example' in schemaObj && schemaObj.example !== undefined) {\n return JSON.stringify(schemaObj.example, null, 2);\n }\n }\n\n return '// Response structure according to schema';\n}\n\nfunction generateServersSection(servers: ServerObject[]): string {\n let markdown = `## Available Servers\\n\\n`;\n markdown += `The API can be accessed from the following servers:\\n\\n`;\n\n for (const server of servers) {\n markdown += `- \\`${server.url}\\` - ${server.description || 'No description'}\\n`;\n\n // If server has variables, document them\n if (server.variables && Object.keys(server.variables).length > 0) {\n markdown += ` - Variables:\\n`;\n for (const [varName, variable] of Object.entries(server.variables)) {\n markdown += ` - \\`${varName}\\`: ${variable.description || 'No description'} (Default: \\`${variable.default}\\`)\\n`;\n if (variable.enum && variable.enum.length > 0) {\n markdown += ` - Possible values: ${variable.enum.map((v) => `\\`${v}\\``).join(', ')}\\n`;\n }\n }\n }\n }\n markdown += `\\n`;\n\n return markdown;\n}\n\n/**\n * Format a value for display in a markdown table\n */\nfunction formatExampleValue(value: any): string {\n if (value === undefined || value === null) return '-';\n if (typeof value === 'object') return '`' + JSON.stringify(value) + '`';\n return '`' + String(value) + '`';\n}\n\n/**\n * Formats an example object for code display\n */\nfunction formatExample(example: Record<string, any>): string {\n if (Object.keys(example).length === 0) return '{}';\n\n let result = '{\\n';\n for (const [key, value] of Object.entries(example)) {\n const valueStr =\n typeof value === 'string'\n ? `\"${value.replace(/\"/g, '\\\\\"')}\"`\n : JSON.stringify(value);\n result += ` ${key}: ${valueStr},\\n`;\n }\n result += '}';\n return result;\n}\n\n/**\n * Type guard for ExampleObject\n */\nfunction isExampleObject(obj: any): obj is ExampleObject {\n return obj && typeof obj === 'object' && 'value' in obj;\n}\n\n/**\n * Type guard for ReferenceObject\n */\nfunction isReferenceObject(obj: any): obj is ReferenceObject {\n return obj && typeof obj === 'object' && '$ref' in obj;\n}\n\n/**\n * Generate example parameters from the operation object and request body\n */\nfunction generateExampleParams(\n opObject: OperationObject | undefined,\n spec: OpenAPIObject,\n): Record<string, any> {\n if (!opObject) return {};\n\n const examples: Record<string, any> = {};\n\n // Handle parameters (path, query, header)\n if (opObject.parameters) {\n for (const param of opObject.parameters) {\n const parameter = isReferenceObject(param)\n ? (followRef(spec, param.$ref) as ParameterObject)\n : param;\n\n // Get example from parameter\n const exampleValue = extractParameterExample(parameter, spec);\n if (exampleValue !== undefined) {\n examples[parameter.name] = exampleValue;\n }\n }\n }\n\n // Handle request body\n if (opObject.requestBody) {\n Object.assign(\n examples,\n extractRequestBodyExamples(opObject.requestBody, spec),\n );\n }\n\n return examples;\n}\n\n/**\n * Extract example value from a parameter\n */\nfunction extractParameterExample(\n parameter: ParameterObject,\n spec: OpenAPIObject,\n): any {\n if (parameter.example !== undefined) {\n return parameter.example;\n }\n\n if (parameter.examples && Object.keys(parameter.examples).length > 0) {\n const firstExampleKey = Object.keys(parameter.examples)[0];\n const exampleObj = parameter.examples[firstExampleKey];\n\n if (isExampleObject(exampleObj)) {\n return exampleObj.value;\n }\n\n if (isReferenceObject(exampleObj)) {\n const refExample = followRef(spec, exampleObj.$ref);\n if (isExampleObject(refExample)) {\n return (refExample as any).value;\n }\n }\n }\n\n if (parameter.schema) {\n const schema = isReferenceObject(parameter.schema)\n ? (followRef(spec, parameter.schema.$ref) as SchemaObject)\n : parameter.schema;\n\n if (schema.example !== undefined) {\n return schema.example;\n }\n\n if (schema.examples && schema.examples.length > 0) {\n return schema.examples[0];\n }\n }\n\n return undefined;\n}\n\n/**\n * Extract examples from request body\n */\nfunction extractRequestBodyExamples(\n requestBody: RequestBodyObject | ReferenceObject,\n spec: OpenAPIObject,\n): Record<string, any> {\n const examples: Record<string, any> = {};\n\n const resolvedBody = isReferenceObject(requestBody)\n ? (followRef(spec, requestBody.$ref) as RequestBodyObject)\n : requestBody;\n\n if (!resolvedBody.content?.['application/json']) {\n return examples;\n }\n\n const content = resolvedBody.content['application/json'];\n\n // Check for examples object\n if (content.examples && Object.keys(content.examples).length > 0) {\n const firstExampleKey = Object.keys(content.examples)[0];\n const exampleObj = content.examples[firstExampleKey];\n\n if (isExampleObject(exampleObj)) {\n Object.assign(examples, exampleObj.value || {});\n } else if (isReferenceObject(exampleObj)) {\n const refExample = followRef(spec, exampleObj.$ref);\n if (isExampleObject(refExample)) {\n Object.assign(examples, (refExample as any).value || {});\n }\n }\n return examples;\n }\n\n // Check for direct example\n if (content.example) {\n Object.assign(examples, content.example);\n return examples;\n }\n\n // Check schema for examples\n if (content.schema) {\n const schema = isReferenceObject(content.schema)\n ? (followRef(spec, content.schema.$ref) as SchemaObject)\n : content.schema;\n\n if (schema.example) {\n Object.assign(examples, schema.example);\n return examples;\n }\n\n if (schema.properties) {\n // Get examples from properties\n for (const [propName, propSchema] of Object.entries(schema.properties)) {\n const propSchemaObj = isReferenceObject(propSchema)\n ? (followRef(spec, propSchema.$ref) as SchemaObject)\n : propSchema;\n\n if (propSchemaObj.example !== undefined) {\n examples[propName] = propSchemaObj.example;\n } else if (\n propSchemaObj.examples &&\n propSchemaObj.examples.length > 0\n ) {\n examples[propName] = propSchemaObj.examples[0];\n }\n }\n }\n }\n\n return examples;\n}\n\n/**\n * Find a parameter by name in the operation object\n */\nfunction findParameterByName(\n opObject: OperationObject | undefined,\n name: string,\n spec: OpenAPIObject,\n) {\n if (!opObject?.parameters) return undefined;\n\n // Look through parameters\n for (const param of opObject.parameters) {\n if (isReferenceObject(param)) {\n const resolvedParam = followRef(spec, param.$ref) as ParameterObject;\n if (resolvedParam.name === name) return resolvedParam;\n } else if (param.name === name) {\n return param;\n }\n }\n\n // Check requestBody for the parameter\n if (opObject.requestBody) {\n const requestBody = isReferenceObject(opObject.requestBody)\n ? (followRef(spec, opObject.requestBody.$ref) as RequestBodyObject)\n : opObject.requestBody;\n\n if (requestBody.content?.['application/json']?.schema) {\n const schema = requestBody.content['application/json'].schema;\n const schemaObj = isReferenceObject(schema)\n ? (followRef(spec, schema.$ref) as SchemaObject)\n : schema;\n\n if (schemaObj.properties?.[name]) {\n const propSchema = schemaObj.properties[name];\n return {\n name,\n in: 'body',\n required: schemaObj.required?.includes(name) ?? false,\n schema: propSchema,\n description: isReferenceObject(propSchema)\n ? undefined\n : propSchema.description,\n example: isReferenceObject(propSchema)\n ? undefined\n : propSchema.example,\n };\n }\n }\n }\n\n return undefined;\n}\n\n/**\n * Helper function to find operation in OpenAPI spec\n */\nfunction findOperationInSpec(\n spec: OpenAPIObject,\n path: string,\n method: Method,\n): OperationObject | undefined {\n const pathItem = spec.paths?.[path] as PathItemObject | undefined;\n if (!pathItem) return undefined;\n return pathItem[method] as OperationObject | undefined;\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["ts", "dirname", "join", "join", "dirname", "get", "camelcase", "pascalcase", "spinalcase", "it", "name", "spinalcase", "camelcase", "get", "pascalcase", "client_default", "
|
|
3
|
+
"sources": ["../src/lib/generate.ts", "../../core/src/lib/deriver.ts", "../../core/src/lib/program.ts", "../../core/src/lib/paths.ts", "../../core/src/lib/file-system.ts", "../../core/src/index.ts", "../src/lib/generator.ts", "../src/lib/json-zod.ts", "../src/lib/sdk.ts", "../src/lib/client.ts", "../src/lib/utils.ts", "../src/lib/http/client.txt", "../src/lib/http/parser.txt", "../src/lib/http/request.txt", "../src/lib/http/response.txt", "../src/lib/http/send-request.txt", "../src/lib/watcher.ts"],
|
|
4
|
+
"sourcesContent": ["import { join } from 'node:path';\nimport { npmRunPathEnv } from 'npm-run-path';\nimport type { OpenAPIObject } from 'openapi3-ts/oas31';\n\nimport { getFolderExports, methods, writeFiles } from '@sdk-it/core';\n\nimport { generateCode } from './generator.ts';\nimport clientTxt from './http/client.txt';\nimport parserTxt from './http/parser.txt';\nimport requestTxt from './http/request.txt';\nimport responseTxt from './http/response.txt';\nimport sendRequest from './http/send-request.txt';\nimport { generateClientSdk } from './sdk.ts';\nimport { securityToOptions } from './utils.ts';\n\nfunction security(spec: OpenAPIObject) {\n const security = spec.security || [];\n const components = spec.components || {};\n const securitySchemas = components.securitySchemes || {};\n const paths = Object.values(spec.paths ?? {});\n\n const options = securityToOptions(security, securitySchemas);\n\n for (const it of paths) {\n for (const method of methods) {\n const operation = it[method];\n if (!operation) {\n continue;\n }\n Object.assign(\n options,\n securityToOptions(operation.security || [], securitySchemas, 'input'),\n );\n }\n }\n return options;\n}\n\nexport async function generate(\n spec: OpenAPIObject,\n settings: {\n output: string;\n name?: string;\n mode?: 'full' | 'minimal';\n formatCode?: (options: {\n output: string;\n env: ReturnType<typeof npmRunPathEnv>;\n }) => void | Promise<void>;\n },\n) {\n const { commonSchemas, groups, outputs } = generateCode({\n spec,\n style: 'github',\n target: 'javascript',\n });\n\n const options = security(spec);\n\n const clientFiles = generateClientSdk({\n name: settings.name || 'Client',\n operations: groups,\n servers: spec.servers?.map((server) => server.url) || [],\n options: options,\n });\n\n // const readme = generateReadme(spec, {\n // name: settings.name || 'Client',\n // });\n\n await writeFiles(settings.output, {\n 'outputs/index.ts': '',\n 'inputs/index.ts': '',\n // 'README.md': readme,\n });\n\n await writeFiles(join(settings.output, 'http'), {\n 'parse-response.ts': clientTxt,\n 'send-request.ts': sendRequest,\n 'response.ts': responseTxt,\n 'parser.ts': parserTxt,\n 'request.ts': requestTxt,\n });\n\n await writeFiles(join(settings.output, 'outputs'), outputs);\n\n await writeFiles(settings.output, {\n ...clientFiles,\n 'zod.ts': `import z from 'zod';\\n${Object.entries(commonSchemas)\n .map(([name, schema]) => `export const ${name} = ${schema};`)\n .join('\\n')}`,\n });\n\n const [index, outputIndex, inputsIndex, httpIndex] = await Promise.all([\n getFolderExports(settings.output),\n getFolderExports(join(settings.output, 'outputs')),\n getFolderExports(join(settings.output, 'inputs')),\n getFolderExports(join(settings.output, 'http')),\n ]);\n\n await writeFiles(settings.output, {\n 'index.ts': index,\n 'outputs/index.ts': outputIndex,\n 'inputs/index.ts': inputsIndex,\n 'http/index.ts': httpIndex,\n });\n\n await settings.formatCode?.({\n output: settings.output,\n env: npmRunPathEnv(),\n });\n}\n", "import ts, { TypeFlags, symbolName } from 'typescript';\n\ntype Collector = Record<string, any>;\nexport const deriveSymbol = Symbol.for('serialize');\nexport const $types = Symbol.for('types');\nconst defaults: Record<string, string> = {\n ReadableStream: 'any',\n DateConstructor: 'string',\n ArrayBufferConstructor: 'any',\n SharedArrayBufferConstructor: 'any',\n Int8ArrayConstructor: 'any',\n Uint8Array: 'any',\n};\nexport class TypeDeriver {\n public readonly collector: Collector = {};\n public readonly checker: ts.TypeChecker;\n constructor(checker: ts.TypeChecker) {\n this.checker = checker;\n }\n\n serializeType(type: ts.Type): any {\n if (type.flags & TypeFlags.Any) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.flags & ts.TypeFlags.Boolean) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (type.isIntersection()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'intersection',\n optional,\n [$types]: types,\n };\n }\n if (type.isUnion()) {\n let optional: boolean | undefined;\n const types: any[] = [];\n for (const unionType of type.types) {\n if (optional === undefined) {\n optional = (unionType.flags & ts.TypeFlags.Undefined) !== 0;\n if (optional) {\n continue;\n }\n }\n\n types.push(this.serializeType(unionType));\n }\n return {\n [deriveSymbol]: true,\n kind: 'union',\n optional,\n [$types]: types,\n };\n }\n if (this.checker.isArrayLikeType(type)) {\n const [argType] = this.checker.getTypeArguments(type as ts.TypeReference);\n if (!argType) {\n const typeName = type.symbol?.getName() || '<unknown>';\n console.warn(\n `Could not find generic type argument for array type ${typeName}`,\n );\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: ['any'],\n };\n }\n const typeSymbol = argType.getSymbol();\n if (!typeSymbol) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'array',\n [$types]: [this.serializeType(argType)],\n };\n }\n\n if (typeSymbol.valueDeclaration) {\n return {\n kind: 'array',\n [deriveSymbol]: true,\n [$types]: [this.serializeNode(typeSymbol.valueDeclaration)],\n };\n }\n const maybeDeclaration = typeSymbol.declarations?.[0];\n if (maybeDeclaration) {\n if (ts.isMappedTypeNode(maybeDeclaration)) {\n const resolvedType = this.checker\n .getPropertiesOfType(argType)\n .reduce<Record<string, unknown>>((acc, prop) => {\n const propType = this.checker.getTypeOfSymbol(prop);\n acc[prop.name] = this.serializeType(propType);\n return acc;\n }, {});\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: [resolvedType],\n };\n } else {\n return {\n kind: 'array',\n ...this.serializeNode(maybeDeclaration),\n };\n }\n }\n\n return {\n kind: 'array',\n optional: false,\n [deriveSymbol]: true,\n [$types]: ['any'],\n };\n }\n if (type.isClass()) {\n const declaration = type.symbol?.valueDeclaration;\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n if (isInterfaceType(type)) {\n const valueDeclaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!valueDeclaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(valueDeclaration);\n }\n if (type.flags & TypeFlags.Null) {\n return {\n [deriveSymbol]: true,\n optional: true,\n [$types]: ['null'],\n };\n }\n if (type.flags & TypeFlags.Object) {\n if (defaults[symbolName(type.symbol)]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [defaults[type.symbol.name]],\n };\n }\n const properties = this.checker.getPropertiesOfType(type);\n if (properties.length > 0) {\n const serializedProps: Record<string, any> = {};\n for (const prop of properties) {\n if (\n (prop.getDeclarations() ?? []).some(\n (it) => ts.isPropertySignature(it) || ts.isPropertyAssignment(it),\n )\n ) {\n const propType = this.checker.getTypeOfSymbol(prop);\n serializedProps[prop.name] = this.serializeType(propType);\n }\n }\n return {\n [deriveSymbol]: true,\n kind: 'object',\n optional: false,\n [$types]: [serializedProps],\n };\n }\n const declaration =\n type.symbol.valueDeclaration ?? type.symbol.declarations?.[0];\n if (!declaration) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [type.symbol.getName()],\n };\n }\n return this.serializeNode(declaration);\n }\n\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [\n this.checker.typeToString(\n type,\n undefined,\n ts.TypeFormatFlags.NoTruncation,\n ),\n ],\n };\n }\n\n serializeNode(node: ts.Node): any {\n if (ts.isObjectLiteralExpression(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, any> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return props;\n }\n if (ts.isPropertyAccessExpression(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertySignature(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isPropertyDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n const type = this.checker.getTypeOfSymbol(symbol);\n return this.serializeType(type);\n }\n if (ts.isInterfaceDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Interface has no name');\n }\n if (defaults[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [defaults[node.name.text]],\n };\n }\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, any> = {};\n for (const member of node.members.filter(ts.isPropertySignature)) {\n members[member.name.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = members;\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n };\n }\n if (ts.isClassDeclaration(node)) {\n if (!node.name?.text) {\n throw new Error('Class has no name');\n }\n if (defaults[node.name.text]) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [defaults[node.name.text]],\n };\n }\n\n if (!this.collector[node.name.text]) {\n this.collector[node.name.text] = {};\n const members: Record<string, unknown> = {};\n for (const member of node.members.filter(ts.isPropertyDeclaration)) {\n members[member.name!.getText()] = this.serializeNode(member);\n }\n this.collector[node.name.text] = members;\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [`#/components/schemas/${node.name.text}`],\n $ref: `#/components/schemas/${node.name.text}`,\n };\n }\n if (ts.isVariableDeclaration(node)) {\n const symbol = this.checker.getSymbolAtLocation(node.name);\n if (!symbol) {\n console.warn(`No symbol found for ${node.name.getText()}`);\n return null;\n }\n if (!node.type) {\n console.warn(`No type found for ${node.name.getText()}`);\n return 'any';\n }\n const type = this.checker.getTypeFromTypeNode(node.type);\n return this.serializeType(type);\n }\n if (ts.isIdentifier(node)) {\n const symbol = this.checker.getSymbolAtLocation(node);\n if (!symbol) {\n console.warn(`Identifer: No symbol found for ${node.getText()}`);\n return null;\n }\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAwaitExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isCallExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isAsExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n if (ts.isTypeLiteralNode(node)) {\n const symbolType = this.checker.getTypeAtLocation(node);\n const props: Record<string, unknown> = {};\n for (const symbol of symbolType.getProperties()) {\n const type = this.checker.getTypeOfSymbol(symbol);\n props[symbol.name] = this.serializeType(type);\n }\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [props],\n };\n }\n if (node.kind === ts.SyntaxKind.NullKeyword) {\n return {\n [deriveSymbol]: true,\n optional: true,\n [$types]: ['null'],\n };\n }\n if (node.kind === ts.SyntaxKind.BooleanKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (\n node.kind === ts.SyntaxKind.TrueKeyword ||\n node.kind === ts.SyntaxKind.FalseKeyword\n ) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n if (ts.isArrayLiteralExpression(node)) {\n const type = this.checker.getTypeAtLocation(node);\n return this.serializeType(type);\n }\n\n console.warn(`Unhandled node: ${ts.SyntaxKind[node.kind]} ${node.flags}`);\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['any'],\n };\n }\n}\n\nfunction isInterfaceType(type: ts.Type): boolean {\n if (type.isClassOrInterface()) {\n // Check if it's an interface\n return !!(type.symbol.flags & ts.SymbolFlags.Interface);\n }\n return false;\n}\n", "import debug from 'debug';\nimport { dirname, join } from 'node:path';\nimport ts from 'typescript';\n\n\n\n\n\nconst logger = debug('january:client');\n\nexport function parseTsConfig(tsconfigPath: string) {\n logger(`Using TypeScript version: ${ts.version}`);\n const configContent = ts.readConfigFile(tsconfigPath, ts.sys.readFile);\n\n if (configContent.error) {\n console.error(\n `Failed to read tsconfig file:`,\n ts.formatDiagnosticsWithColorAndContext([configContent.error], {\n getCanonicalFileName: (path) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n }),\n );\n throw new Error('Failed to parse tsconfig.json');\n }\n\n const parsed = ts.parseJsonConfigFileContent(\n configContent.config,\n ts.sys,\n dirname(tsconfigPath),\n );\n\n if (parsed.errors.length > 0) {\n console.error(\n `Errors found in tsconfig.json:`,\n ts.formatDiagnosticsWithColorAndContext(parsed.errors, {\n getCanonicalFileName: (path) => path,\n getCurrentDirectory: ts.sys.getCurrentDirectory,\n getNewLine: () => ts.sys.newLine,\n }),\n );\n throw new Error('Failed to parse tsconfig.json');\n }\n return parsed;\n}\nexport function getProgram(tsconfigPath: string) {\n const tsConfigParseResult = parseTsConfig(tsconfigPath);\n logger(`Parsing tsconfig`);\n return ts.createProgram({\n options: {\n ...tsConfigParseResult.options,\n noEmit: true,\n incremental: true,\n tsBuildInfoFile: join(dirname(tsconfigPath), './.tsbuildinfo'), // not working atm\n },\n rootNames: tsConfigParseResult.fileNames,\n projectReferences: tsConfigParseResult.projectReferences,\n configFileParsingDiagnostics: tsConfigParseResult.errors,\n });\n}\nexport function getPropertyAssignment(node: ts.Node, name: string) {\n if (ts.isObjectLiteralExpression(node)) {\n return node.properties\n .filter((prop) => ts.isPropertyAssignment(prop))\n .find((prop) => prop.name!.getText() === name);\n }\n return undefined;\n}\nexport function isCallExpression(\n node: ts.Node,\n name: string,\n): node is ts.CallExpression {\n return (\n ts.isCallExpression(node) &&\n node.expression &&\n ts.isIdentifier(node.expression) &&\n node.expression.text === name\n );\n}\n\nexport function isInterfaceType(type: ts.Type): boolean {\n if (type.isClassOrInterface()) {\n // Check if it's an interface\n return !!(type.symbol.flags & ts.SymbolFlags.Interface);\n }\n return false;\n}", "import type {\n OperationObject,\n ParameterObject,\n PathsObject,\n ResponseObject,\n ResponsesObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nimport { $types } from './deriver.ts';\n\nexport type Method =\n | 'get'\n | 'post'\n | 'put'\n | 'patch'\n | 'delete'\n | 'trace'\n | 'head';\nexport const methods = [\n 'get',\n 'post',\n 'put',\n 'patch',\n 'delete',\n 'trace',\n 'head',\n] as const;\nexport type SemanticSource =\n | 'query'\n | 'queries'\n | 'body'\n | 'params'\n | 'headers';\n\nconst semanticSourceToOpenAPI = {\n queries: 'query',\n query: 'query',\n headers: 'header',\n params: 'path',\n} as const;\nexport interface Selector {\n name: string;\n select: string;\n against: string;\n source: SemanticSource;\n nullable: boolean;\n required: boolean;\n}\n\nexport interface ResponseItem {\n statusCode: string;\n response?: DateType;\n contentType: string;\n headers: string[];\n}\n\nexport type OnOperation = (\n sourceFile: string,\n method: Method,\n path: string,\n operation: OperationObject,\n) => PathsObject;\nexport class Paths {\n #commonZodImport?: string;\n #onOperation?: OnOperation;\n #operations: Array<{\n sourceFile: string;\n name: string;\n path: string;\n method: Method;\n selectors: Selector[];\n responses: ResponsesObject;\n tags?: string[];\n description?: string;\n }> = [];\n\n constructor(config: { commonZodImport?: string; onOperation?: OnOperation }) {\n this.#commonZodImport = config.commonZodImport;\n this.#onOperation = config.onOperation;\n }\n\n addPath(\n name: string,\n path: string,\n method: Method,\n selectors: Selector[],\n responses: ResponseItem[],\n sourceFile: string,\n tags?: string[],\n description?: string,\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n this.#operations.push({\n name,\n path,\n sourceFile,\n method,\n selectors,\n responses: responsesObject,\n tags,\n description,\n });\n return this;\n }\n\n #responseItemToResponses(responses: ResponseItem[]): ResponsesObject {\n const responsesObject: ResponsesObject = {};\n for (const item of responses) {\n const ct = item.contentType;\n const schema = item.response ? toSchema(item.response) : {};\n if (!responsesObject[item.statusCode]) {\n responsesObject[item.statusCode] = {\n description: `Response for ${item.statusCode}`,\n content: {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n },\n headers: item.headers.length\n ? item.headers.reduce(\n (acc, header) => ({\n ...acc,\n [header]: { schema: { type: 'string' } },\n }),\n {},\n )\n : undefined,\n } satisfies ResponseObject;\n } else {\n if (!responsesObject[item.statusCode].content[ct]) {\n responsesObject[item.statusCode].content[ct] = { schema };\n } else {\n const existing = responsesObject[item.statusCode].content[ct]\n .schema as SchemaObject;\n if (existing.oneOf) {\n if (\n !existing.oneOf.find(\n (it) => JSON.stringify(it) === JSON.stringify(schema),\n )\n ) {\n existing.oneOf.push(schema);\n }\n } else if (JSON.stringify(existing) !== JSON.stringify(schema)) {\n responsesObject[item.statusCode].content[ct].schema = {\n oneOf: [existing, schema],\n };\n }\n }\n }\n }\n return responsesObject;\n }\n\n async #selectosToParameters(selectors: Selector[]) {\n const parameters: ParameterObject[] = [];\n const bodySchemaProps: Record<string, SchemaObject> = {};\n for (const selector of selectors) {\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = await evalZod(\n selector.against,\n this.#commonZodImport,\n );\n continue;\n }\n\n const parameter: ParameterObject = {\n in: semanticSourceToOpenAPI[selector.source],\n name: selector.name,\n required: selector.required,\n schema: await evalZod(selector.against, this.#commonZodImport),\n };\n parameters.push(parameter);\n }\n return { parameters, bodySchemaProps };\n }\n\n async getPaths() {\n const operations: PathsObject = {};\n for (const operation of this.#operations) {\n const { path, method, selectors } = operation;\n const { parameters, bodySchemaProps } =\n await this.#selectosToParameters(selectors);\n const operationObject: OperationObject = {\n operationId: operation.name,\n parameters,\n tags: operation.tags,\n description: operation.description,\n requestBody: Object.keys(bodySchemaProps).length\n ? {\n content: {\n 'application/json': {\n schema: {\n type: 'object',\n properties: bodySchemaProps,\n },\n },\n },\n }\n : undefined,\n responses: operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n if (this.#onOperation) {\n const operations = this.#onOperation?.(\n operation.sourceFile,\n method,\n path,\n operationObject,\n );\n Object.assign(operations, operations ?? {});\n }\n }\n return operations;\n }\n}\n\nasync function evalZod(schema: string, commonZodImport?: string) {\n // https://github.com/nodejs/node/issues/51956\n const lines = [\n `import { createRequire } from \"node:module\";`,\n `const filename = \"${import.meta.url}\";`,\n `const require = createRequire(filename);`,\n `const z = require(\"zod\");`,\n commonZodImport ? `import * as commonZod from '${commonZodImport}';` : '',\n `const {zodToJsonSchema} = require('zod-to-json-schema');`,\n `const schema = ${schema.replace('.optional()', '')};`,\n `const jsonSchema = zodToJsonSchema(schema, {\n \t$refStrategy: 'root',\n \tbasePath: ['#', 'components', 'schemas']\n });`,\n `export default jsonSchema;`,\n ];\n const base64 = Buffer.from(lines.join('\\n')).toString('base64');\n return import(`data:text/javascript;base64,${base64}`)\n .then((mod) => mod.default)\n .then(({ $schema, ...result }) => result);\n}\n\ninterface DateType {\n [$types]: any[];\n kind: string;\n optional: boolean;\n}\n\nexport function toSchema(data: DateType | string | null | undefined): any {\n if (data === null || data === undefined) {\n return { type: 'any' };\n } else if (typeof data === 'string') {\n const isRef = data.startsWith('#');\n if (isRef) {\n return { $ref: data };\n }\n return { type: data };\n } else if (data.kind === 'array') {\n const items = data[$types].map(toSchema);\n return { type: 'array', items: data[$types].length ? items[0] : {} };\n } else if (data.kind === 'union') {\n return { oneOf: data[$types].map(toSchema) };\n } else if (data.kind === 'intersection') {\n return { allOf: data[$types].map(toSchema) };\n } else if ($types in data) {\n return data[$types].map(toSchema)[0] ?? {};\n } else {\n const props: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(data)) {\n props[key] = toSchema(value as any);\n }\n return {\n type: 'object',\n properties: props,\n additionalProperties: false,\n };\n }\n}\n\nexport function isHttpMethod(name: string): name is Method {\n return ['get', 'post', 'put', 'delete', 'patch'].includes(name);\n}\n", "import { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';\nimport { dirname, isAbsolute, join } from 'node:path';\n\nexport async function getFile(filePath: string) {\n if (await exist(filePath)) {\n return readFile(filePath, 'utf-8');\n }\n return null;\n}\n\nexport async function exist(file: string): Promise<boolean> {\n return stat(file)\n .then(() => true)\n .catch(() => false);\n}\n\nexport async function readFolder(path: string) {\n if (await exist(path)) {\n return readdir(path);\n }\n return [] as string[];\n}\n\nexport async function writeFiles(\n dir: string,\n contents: Record<\n string,\n string | { content: string; ignoreIfExists?: boolean }\n >,\n) {\n return Promise.all(\n Object.entries(contents).map(async ([file, content]) => {\n const filePath = isAbsolute(file) ? file : join(dir, file);\n await mkdir(dirname(filePath), { recursive: true });\n if (typeof content === 'string') {\n await writeFile(filePath, content, 'utf-8');\n } else {\n if (content.ignoreIfExists) {\n if (!(await exist(filePath))) {\n await writeFile(filePath, content.content, 'utf-8');\n }\n }\n }\n }),\n );\n}\n\nexport async function getFolderExports(folder: string, extensions = ['ts']) {\n const files = await readdir(folder, { withFileTypes: true });\n const exports: string[] = [];\n for (const file of files) {\n if (file.isDirectory()) {\n exports.push(`export * from './${file.name}';`);\n } else if (\n file.name !== 'index.ts' &&\n extensions.includes(getExt(file.name))\n ) {\n exports.push(`export * from './${file.name}';`);\n }\n }\n return exports.join('\\n');\n}\n\nexport const getExt = (fileName?: string) => {\n if (!fileName) {\n return ''; // shouldn't happen as there will always be a file name\n }\n const lastDot = fileName.lastIndexOf('.');\n if (lastDot === -1) {\n return '';\n }\n const ext = fileName\n .slice(lastDot + 1)\n .split('/')\n .filter(Boolean)\n .join('');\n if (ext === fileName) {\n // files that have no extension\n return '';\n }\n return ext || 'txt';\n};\n", "export * from './lib/deriver.ts';\nexport * from './lib/program.ts';\nexport * from './lib/paths.ts';\nexport * from './lib/file-system.ts';\n\nexport function removeDuplicates<T>(\n data: T[],\n accessor: (item: T) => T[keyof T],\n): T[] {\n return [...new Map(data.map((x) => [accessor(x), x])).values()];\n}\n\nexport type InferRecordValue<T> = T extends Record<string, infer U> ? U : any;\n\nexport function toLitObject<T extends Record<string, any>>(\n obj: T,\n accessor: (value: InferRecordValue<T>) => string = (value) => value,\n) {\n return `{${Object.keys(obj)\n .map((key) => `${key}: ${accessor(obj[key])}`)\n .join(', ')}}`;\n}\n", "import { get, merge } from 'lodash-es';\nimport type {\n ContentObject,\n OpenAPIObject,\n OperationObject,\n ParameterLocation,\n ParameterObject,\n ResponseObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase, pascalcase, spinalcase } from 'stringcase';\n\nimport { removeDuplicates } from '@sdk-it/core';\n\nimport { followRef, jsonSchemaToZod } from './json-zod.ts';\nimport { type Operation, type Spec } from './sdk.ts';\nimport { isRef, securityToOptions } from './utils.ts';\n\nexport interface NamedImport {\n name: string;\n alias?: string;\n isTypeOnly: boolean;\n}\nexport interface Import {\n isTypeOnly: boolean;\n moduleSpecifier: string;\n defaultImport: string | undefined;\n namedImports: NamedImport[];\n namespaceImport: string | undefined;\n}\n\nconst responses: Record<string, string> = {\n '400': 'BadRequest',\n '401': 'Unauthorized',\n '402': 'PaymentRequired',\n '403': 'Forbidden',\n '404': 'NotFound',\n '405': 'MethodNotAllowed',\n '406': 'NotAcceptable',\n '409': 'Conflict',\n '413': 'PayloadTooLarge',\n '410': 'Gone',\n '422': 'UnprocessableEntity',\n '429': 'TooManyRequests',\n '500': 'InternalServerError',\n '501': 'NotImplemented',\n '502': 'BadGateway',\n '503': 'ServiceUnavailable',\n '504': 'GatewayTimeout',\n};\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIObject;\n target?: 'javascript';\n /**\n * No support for jsdoc in vscode\n * @issue https://github.com/microsoft/TypeScript/issues/38106\n */\n style?: 'github';\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n}\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId'>> = {\n target: 'javascript',\n style: 'github',\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return spinalcase(operation.operationId);\n }\n return (\n operation.operationId ||\n camelcase(`${method} ${path.replace(/\\//g, ' ')}`)\n );\n },\n};\n\nexport function generateCode(config: GenerateSdkConfig) {\n const groups: Spec['operations'] = {};\n const commonSchemas: Record<string, string> = {};\n const outputs: Record<string, string> = {};\n\n for (const [path, methods] of Object.entries(config.spec.paths ?? {})) {\n for (const [method, operation] of Object.entries(methods) as [\n string,\n OperationObject,\n ][]) {\n const formatOperationId = config.operationId ?? defaults.operationId;\n const operationName = formatOperationId(operation, path, method);\n\n console.log(`Processing ${method} ${path}`);\n const groupName = (operation.tags ?? ['unknown'])[0];\n groups[groupName] ??= [];\n const inputs: Operation['inputs'] = {};\n const imports: Import[] = [];\n\n const additionalProperties: ParameterObject[] = [];\n for (const param of operation.parameters ?? []) {\n if (isRef(param)) {\n throw new Error(`Found reference in parameter ${param.$ref}`);\n }\n if (!param.schema) {\n throw new Error(`Schema not found for parameter ${param.name}`);\n }\n inputs[param.name] = {\n in: param.in,\n schema: '',\n };\n additionalProperties.push(param);\n }\n\n const security = operation.security ?? [];\n const securitySchemas = config.spec.components?.securitySchemes ?? {};\n\n const securityOptions = securityToOptions(security, securitySchemas);\n\n Object.assign(inputs, securityOptions);\n\n additionalProperties.push(\n ...Object.entries(securityOptions).map(\n ([name, value]) =>\n ({\n name: name,\n required: false,\n schema: {\n type: 'string',\n },\n in: value.in as ParameterLocation,\n }) satisfies ParameterObject,\n ),\n );\n\n const types: Record<string, string> = {};\n const shortContenTypeMap: Record<string, string> = {\n 'application/json': 'json',\n 'application/x-www-form-urlencoded': 'urlencoded',\n 'multipart/form-data': 'formdata',\n 'application/xml': 'xml',\n 'text/plain': 'text',\n };\n let contentType: string | undefined;\n if (operation.requestBody && Object.keys(operation.requestBody).length) {\n const content: ContentObject = isRef(operation.requestBody)\n ? get(followRef(config.spec, operation.requestBody.$ref), ['content'])\n : operation.requestBody.content;\n\n for (const type in content) {\n const schema = isRef(content[type].schema)\n ? followRef(config.spec, content[type].schema.$ref)\n : content[type].schema;\n\n types[shortContenTypeMap[type]] = jsonSchemaToZod(\n config.spec,\n merge(schema, {\n required: additionalProperties\n .filter((p) => p.required)\n .map((p) => p.name),\n properties: additionalProperties.reduce<Record<string, any>>(\n (acc, p) => ({\n ...acc,\n [p.name]: p.schema,\n }),\n {},\n ),\n }),\n true,\n (schemaName, zod) => {\n commonSchemas[schemaName] = zod;\n imports.push({\n defaultImport: undefined,\n isTypeOnly: false,\n moduleSpecifier: '../zod',\n namedImports: [{ isTypeOnly: false, name: schemaName }],\n namespaceImport: undefined,\n });\n },\n );\n }\n\n if (content['application/json']) {\n contentType = 'json';\n } else if (content['application/x-www-form-urlencoded']) {\n contentType = 'urlencoded';\n } else if (content['multipart/form-data']) {\n contentType = 'formdata';\n } else {\n contentType = 'json';\n }\n } else {\n types[shortContenTypeMap['application/json']] = jsonSchemaToZod(\n config.spec,\n {\n type: 'object',\n required: additionalProperties\n .filter((p) => p.required)\n .map((p) => p.name),\n properties: additionalProperties.reduce<Record<string, any>>(\n (acc, p) => ({\n ...acc,\n [p.name]: p.schema,\n }),\n {},\n ),\n },\n true,\n (schemaName, zod) => {\n commonSchemas[schemaName] = zod;\n imports.push({\n defaultImport: undefined,\n isTypeOnly: false,\n moduleSpecifier: './zod',\n namedImports: [{ isTypeOnly: false, name: schemaName }],\n namespaceImport: undefined,\n });\n },\n );\n }\n\n const errors: string[] = [];\n operation.responses ??= {};\n\n let foundResponse = false;\n const output = [`import z from 'zod';`];\n for (const status in operation.responses) {\n const response = operation.responses[status] as ResponseObject;\n const statusCode = +status;\n if (statusCode >= 400) {\n errors.push(responses[status] ?? 'ProblematicResponse');\n }\n if (statusCode >= 200 && statusCode < 300) {\n foundResponse = true;\n const responseContent = get(response, ['content']);\n const isJson = responseContent && responseContent['application/json'];\n // TODO: how the user is going to handle multiple response types\n const responseSchema = isJson\n ? jsonSchemaToZod(\n config.spec,\n responseContent['application/json'].schema!,\n true,\n (schemaName, zod) => {\n commonSchemas[schemaName] = zod;\n imports.push({\n defaultImport: undefined,\n isTypeOnly: false,\n moduleSpecifier: '../zod',\n namedImports: [{ isTypeOnly: false, name: schemaName }],\n namespaceImport: undefined,\n });\n },\n )\n : 'z.instanceof(ReadableStream)'; // non-json response treated as stream\n\n output.push(\n importsToString(mergeImports(Object.values(imports).flat())).join(\n '\\n',\n ),\n );\n output.push(\n `export const ${pascalcase(operationName + ' output')} = ${responseSchema}`,\n );\n }\n }\n\n if (!foundResponse) {\n output.push(\n `export const ${pascalcase(operationName + ' output')} = z.void()`,\n );\n }\n outputs[`${spinalcase(operationName)}.ts`] = output.join('\\n');\n groups[groupName].push({\n name: operationName,\n type: 'http',\n imports: mergeImports(Object.values(imports).flat()),\n inputs,\n errors: errors.length ? errors : ['ServerError'],\n contentType,\n schemas: types,\n formatOutput: () => ({\n import: pascalcase(operationName + ' output'),\n use: `z.infer<typeof ${pascalcase(operationName + ' output')}>`,\n }),\n trigger: {\n path,\n method,\n },\n });\n }\n }\n\n return { groups, commonSchemas, outputs };\n}\n\n// TODO - USE CASES\n// 1. Some parameters conflicts with request body\n// 2. Generate 400 and 500 response variations // done\n// 3. Generate 200 response variations\n// 3. Doc Security\n// 4. Operation Security\n// 5. JsDocs\n// 5. test all different types of parameters\n// 6. cookies\n// 6. x-www-form-urlencoded // done\n// 7. multipart/form-data // done\n// 7. application/octet-stream // done\n// 7. chunked response // done\n// we need to remove the stream fn in the backend\n\nfunction mergeImports(imports: Import[]) {\n const merged: Record<string, Import> = {};\n\n for (const i of imports) {\n merged[i.moduleSpecifier] = merged[i.moduleSpecifier] ?? {\n moduleSpecifier: i.moduleSpecifier,\n defaultImport: i.defaultImport,\n namespaceImport: i.namespaceImport,\n namedImports: [],\n };\n if (i.namedImports) {\n merged[i.moduleSpecifier].namedImports.push(...i.namedImports);\n }\n }\n\n return Object.values(merged);\n}\n\nfunction importsToString(imports: Import[]) {\n return imports.map((i) => {\n if (i.defaultImport) {\n return `import ${i.defaultImport} from '${i.moduleSpecifier}'`;\n }\n if (i.namespaceImport) {\n return `import * as ${i.namespaceImport} from '${i.moduleSpecifier}'`;\n }\n if (i.namedImports) {\n return `import {${removeDuplicates(i.namedImports, (it) => it.name)\n .map((n) => n.name)\n .join(', ')}} from '${i.moduleSpecifier}'`;\n }\n throw new Error(`Invalid import ${JSON.stringify(i)}`);\n });\n}\n", "import { get } from 'lodash-es';\nimport type {\n OpenAPIObject,\n ReferenceObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\n/**\n * Recursively resolve a $ref in the OpenAPI spec.\n */\n\nfunction cleanRef(ref: string) {\n return ref.replace(/^#\\//, '');\n}\n\nfunction parseRef(ref: string) {\n const parts = ref.split(ref);\n const [model] = parts.splice(-1);\n return { model, path: parts.join('/') };\n}\nexport function followRef(\n spec: OpenAPIObject,\n ref: string,\n): SchemaObject | ReferenceObject {\n // Adjust get(...) usage for your data structure\n const pathParts = cleanRef(ref).split('/');\n const entry = get(spec, pathParts) as SchemaObject | ReferenceObject;\n if (entry && '$ref' in entry) {\n return followRef(spec, entry.$ref);\n }\n return entry;\n}\n\ntype OnRefCallback = (ref: string, zod: string) => void;\n\n/**\n * Convert an OpenAPI (JSON Schema style) object into a Zod schema string,\n * adapted for OpenAPI 3.1 (fully aligned with JSON Schema 2020-12).\n */\n\nexport function jsonSchemaToZod(\n spec: OpenAPIObject,\n schema: SchemaObject | ReferenceObject,\n required = false,\n onRef: OnRefCallback,\n circularRefTracker = new Set<string>(), // Add as optional parameter with default value\n): string {\n // If it's a reference, resolve and recurse\n if ('$ref' in schema) {\n const schemaName = cleanRef(schema.$ref).split('/').pop()!;\n\n // Check for circular references\n if (circularRefTracker.has(schemaName)) {\n return schemaName;\n }\n\n circularRefTracker.add(schemaName);\n onRef(\n schemaName,\n jsonSchemaToZod(\n spec,\n followRef(spec, schema.$ref),\n required,\n onRef,\n circularRefTracker,\n ),\n );\n circularRefTracker.delete(schemaName);\n\n return schemaName;\n }\n\n // Handle allOf \u2192 intersection\n if (schema.allOf && Array.isArray(schema.allOf)) {\n const allOfSchemas = schema.allOf.map((sub) =>\n jsonSchemaToZod(spec, sub, true, onRef, circularRefTracker),\n );\n return allOfSchemas.length\n ? `z.intersection(${allOfSchemas.join(', ')})`\n : allOfSchemas[0];\n }\n\n // anyOf \u2192 union\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n const anyOfSchemas = schema.anyOf.map((sub) =>\n jsonSchemaToZod(spec, sub, false, onRef, circularRefTracker),\n );\n return anyOfSchemas.length > 1\n ? `z.union([${anyOfSchemas.join(', ')}])${appendOptional(required)}`\n : // Handle an invalid anyOf with one schema\n anyOfSchemas[0];\n }\n\n // oneOf \u2192 union\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n const oneOfSchemas = schema.oneOf.map((sub) => {\n if ('$ref' in sub) {\n const { model } = parseRef(sub.$ref);\n if (circularRefTracker.has(model)) {\n return model;\n }\n }\n return jsonSchemaToZod(spec, sub, false, onRef, circularRefTracker);\n });\n return oneOfSchemas.length > 1\n ? `z.union([${oneOfSchemas.join(', ')}])${appendOptional(required)}`\n : // Handle an invalid oneOf with one schema\n oneOfSchemas[0];\n }\n\n // enum\n if (schema.enum && Array.isArray(schema.enum)) {\n const enumVals = schema.enum.map((val) => JSON.stringify(val)).join(', ');\n return `z.enum([${enumVals}])${appendOptional(required)}`;\n }\n\n // 3.1 can have type: string or type: string[] (e.g. [\"string\",\"null\"])\n // Let's parse that carefully.\n const types = Array.isArray(schema.type)\n ? schema.type\n : schema.type\n ? [schema.type]\n : [];\n\n // If no explicit \"type\", fallback to unknown\n if (!types.length) {\n return `z.unknown()${appendOptional(required)}`;\n }\n\n // If it's a union type (like [\"string\", \"null\"]), we'll build a Zod union\n // or apply .nullable() if it's just \"type + null\".\n if (types.length > 1) {\n // If it\u2019s exactly one real type plus \"null\", we can do e.g. `z.string().nullable()`\n const realTypes = types.filter((t) => t !== 'null');\n if (realTypes.length === 1 && types.includes('null')) {\n // Single real type + \"null\"\n const typeZod = basicTypeToZod(\n realTypes[0],\n schema,\n spec,\n false,\n onRef,\n circularRefTracker,\n );\n return `${typeZod}.nullable()${appendOptional(required)}`;\n }\n // If multiple different types, build a union\n const subSchemas = types.map((t) =>\n basicTypeToZod(t, schema, spec, false, onRef, circularRefTracker),\n );\n return `z.union([${subSchemas.join(', ')}])${appendOptional(required)}`;\n }\n\n // If there's exactly one type\n return basicTypeToZod(\n types[0],\n schema,\n spec,\n required,\n onRef,\n circularRefTracker,\n );\n}\n\n/**\n * Convert a basic type (string | number | boolean | object | array, etc.) to Zod.\n * We'll also handle .optional() if needed.\n */\nfunction basicTypeToZod(\n type: string,\n schema: SchemaObject,\n spec: OpenAPIObject,\n required = false,\n onRef: OnRefCallback,\n refProcessingStack: Set<string>,\n): string {\n switch (type) {\n case 'string':\n return handleString(schema, required);\n case 'number':\n case 'integer':\n return handleNumber(schema, required);\n case 'boolean':\n return `z.boolean()${appendDefault(schema.default)}${appendOptional(required)}`;\n case 'object':\n return handleObject(schema, spec, required, onRef, refProcessingStack);\n case 'array':\n return handleArray(schema, spec, required, onRef, refProcessingStack);\n case 'null':\n // If \"type\": \"null\" alone, this is basically z.null()\n return `z.null()${appendOptional(required)}`;\n default:\n // Unknown type -> fallback\n return `z.unknown()${appendOptional(required)}`;\n }\n}\n\n/**\n * Handle a `string` schema with possible format keywords (JSON Schema).\n */\nfunction handleString(schema: SchemaObject, required?: boolean): string {\n let base = 'z.string()';\n\n // 3.1 replaces `example` in the schema with `examples` (array).\n // We do not strictly need them for the Zod type, so they\u2019re optional\n // for validation. However, we could keep them as metadata if you want.\n\n switch (schema.format) {\n case 'date-time':\n case 'datetime':\n // parse to JS Date\n base = 'z.coerce.date()';\n break;\n case 'date':\n base = 'z.coerce.date() /* or z.string() if you want raw date strings */';\n break;\n case 'time':\n base = 'z.string() /* optionally add .regex(...) for HH:MM:SS format */';\n break;\n case 'email':\n base = 'z.string().email()';\n break;\n case 'uuid':\n base = 'z.string().uuid()';\n break;\n case 'url':\n case 'uri':\n base = 'z.string().url()';\n break;\n case 'ipv4':\n base = 'z.string().ip({version: \"v4\"})';\n break;\n case 'ipv6':\n base = 'z.string().ip({version: \"v6\"})';\n break;\n case 'phone':\n base = 'z.string() /* or add .regex(...) for phone formats */';\n break;\n case 'byte':\n case 'binary':\n base = 'z.instanceof(Blob) /* consider base64 check if needed */';\n break;\n case 'int64':\n // JS numbers can't reliably store int64, consider z.bigint() or keep as string\n base = 'z.string() /* or z.bigint() if your app can handle it */';\n break;\n default:\n // No special format\n break;\n }\n\n return `${base}${appendDefault(schema.default)}${appendOptional(required)}`;\n}\n\n/**\n * Handle number/integer constraints from OpenAPI/JSON Schema.\n * In 3.1, exclusiveMinimum/Maximum hold the actual numeric threshold,\n * rather than a boolean toggling `minimum`/`maximum`.\n */\nfunction handleNumber(schema: SchemaObject, required?: boolean): string {\n let defaultValue =\n schema.default !== undefined ? `.default(${schema.default})` : ``;\n let base = 'z.number()';\n if (schema.format === 'int64') {\n base = 'z.bigint()';\n if (schema.default !== undefined) {\n defaultValue = `.default(BigInt(${schema.default}))`;\n }\n }\n\n if (schema.format === 'int32') {\n // 32-bit integer\n base += '.int()';\n }\n\n // If we see exclusiveMinimum as a number in 3.1:\n if (typeof schema.exclusiveMinimum === 'number') {\n // Zod doesn\u2019t have a direct \"exclusiveMinimum\" method, so we can do .gt()\n // If exclusiveMinimum=7 => .gt(7)\n base += `.gt(${schema.exclusiveMinimum})`;\n }\n // Similarly for exclusiveMaximum\n if (typeof schema.exclusiveMaximum === 'number') {\n // If exclusiveMaximum=10 => .lt(10)\n base += `.lt(${schema.exclusiveMaximum})`;\n }\n\n // If standard minimum/maximum\n if (typeof schema.minimum === 'number') {\n base +=\n schema.format === 'int64'\n ? `.min(BigInt(${schema.minimum}))`\n : `.min(${schema.minimum})`;\n }\n if (typeof schema.maximum === 'number') {\n base +=\n schema.format === 'int64'\n ? `.max(BigInt(${schema.maximum}))`\n : `.max(${schema.maximum})`;\n }\n\n // multipleOf\n if (typeof schema.multipleOf === 'number') {\n // There's no direct multipleOf in Zod. Some folks do a custom refine.\n // For example:\n base += `.refine((val) => Number.isInteger(val / ${schema.multipleOf}), \"Must be a multiple of ${schema.multipleOf}\")`;\n }\n\n return `${base}${defaultValue}${appendOptional(required)}`;\n}\n\n/**\n * Handle objects (properties, additionalProperties).\n */\nfunction handleObject(\n schema: SchemaObject,\n spec: OpenAPIObject,\n required = false,\n onRef: OnRefCallback,\n refProcessingStack: Set<string>,\n): string {\n const properties = schema.properties || {};\n\n // Convert each property\n const propEntries = Object.entries(properties).map(([key, propSchema]) => {\n const isRequired = (schema.required ?? []).includes(key);\n const zodPart = jsonSchemaToZod(\n spec,\n propSchema,\n isRequired,\n onRef,\n refProcessingStack,\n );\n return `'${key}': ${zodPart}`;\n });\n\n // additionalProperties\n let additionalProps = '';\n if (schema.additionalProperties) {\n if (typeof schema.additionalProperties === 'object') {\n // e.g. z.record() if it\u2019s an object schema\n const addPropZod = jsonSchemaToZod(\n spec,\n schema.additionalProperties,\n true,\n onRef,\n refProcessingStack,\n );\n additionalProps = `.catchall(${addPropZod})`;\n } else if (schema.additionalProperties === true) {\n // free-form additional props\n additionalProps = `.catchall(z.unknown())`;\n }\n }\n\n const objectSchema = `z.object({${propEntries.join(', ')}})${additionalProps}`;\n return `${objectSchema}${appendOptional(required)}`;\n}\n\n/**\n * Handle arrays (items could be a single schema or a tuple (array of schemas)).\n * In JSON Schema 2020-12, `items` can be an array \u2192 tuple style.\n */\nfunction handleArray(\n schema: SchemaObject,\n spec: OpenAPIObject,\n required = false,\n onRef: OnRefCallback,\n refProcessingStack: Set<string>,\n): string {\n const { items } = schema;\n if (!items) {\n // No items => z.array(z.unknown())\n return `z.array(z.unknown())${appendOptional(required)}`;\n }\n\n // If items is an array => tuple\n if (Array.isArray(items)) {\n // Build a Zod tuple\n const tupleItems = items.map((sub) =>\n jsonSchemaToZod(spec, sub, true, onRef, refProcessingStack),\n );\n const base = `z.tuple([${tupleItems.join(', ')}])`;\n // // If we have additionalItems: false => that\u2019s a fixed length\n // // If additionalItems is a schema => rest(...)\n // if (schema.additionalItems) {\n // if (typeof schema.additionalItems === 'object') {\n // const restSchema = jsonSchemaToZod(spec, schema.additionalItems, true);\n // base += `.rest(${restSchema})`;\n // }\n // // If `additionalItems: false`, no rest is allowed => do nothing\n // }\n return `${base}${appendOptional(required)}`;\n }\n\n // If items is a single schema => standard z.array(...)\n const itemsSchema = jsonSchemaToZod(\n spec,\n items,\n true,\n onRef,\n refProcessingStack,\n );\n return `z.array(${itemsSchema})${appendOptional(required)}`;\n}\n\n/**\n * Append .optional() if not required\n */\nfunction appendOptional(isRequired?: boolean) {\n return isRequired ? '' : '.optional()';\n}\nfunction appendDefault(defaultValue?: any) {\n return defaultValue !== undefined\n ? `.default(${JSON.stringify(defaultValue)})`\n : '';\n}\n\n// Todo: convert openapi 3.0 to 3.1 before proccesing\n", "import { camelcase, pascalcase, spinalcase } from 'stringcase';\n\nimport { removeDuplicates, toLitObject } from '@sdk-it/core';\n\nimport backend from './client.ts';\n\nexport interface Import {\n isTypeOnly: boolean;\n moduleSpecifier: string;\n defaultImport: string | undefined;\n namedImports: NamedImport[];\n namespaceImport: string | undefined;\n}\nexport interface NamedImport {\n name: string;\n alias?: string;\n isTypeOnly: boolean;\n}\n\nclass SchemaEndpoint {\n #imports: string[] = [\n `import z from 'zod';`,\n 'import type { Endpoints } from \"./endpoints.ts\";',\n `import { toRequest, json, urlencoded, formdata, createUrl } from './http/request.ts';`,\n `import type { ParseError } from './http/parser.ts';`,\n ];\n #endpoints: string[] = [];\n addEndpoint(endpoint: string, operation: any) {\n this.#endpoints.push(` \"${endpoint}\": ${operation},`);\n }\n addImport(value: string) {\n this.#imports.push(value);\n }\n complete() {\n return `${this.#imports.join('\\n')}\\nexport default {\\n${this.#endpoints.join('\\n')}\\n}`;\n }\n}\nclass Emitter {\n protected imports: string[] = [\n `import z from 'zod';`,\n `import type { ParseError } from './http/parser.ts';`,\n ];\n protected endpoints: string[] = [];\n addEndpoint(endpoint: string, operation: any) {\n this.endpoints.push(` \"${endpoint}\": ${operation};`);\n }\n addImport(value: string) {\n this.imports.push(value);\n }\n complete() {\n return `${this.imports.join('\\n')}\\nexport interface Endpoints {\\n${this.endpoints.join('\\n')}\\n}`;\n }\n}\nclass StreamEmitter extends Emitter {\n override complete() {\n return `${this.imports.join('\\n')}\\nexport interface StreamEndpoints {\\n${this.endpoints.join('\\n')}\\n}`;\n }\n}\n\nexport interface SdkConfig {\n /**\n * The name of the sdk client\n */\n name: string;\n packageName?: string;\n options?: Record<string, any>;\n emptyBodyAsNull?: boolean;\n stripBodyFromGetAndHead?: boolean;\n output: string;\n}\n\nexport type Options = Record<\n string,\n {\n in: string;\n schema: string;\n optionName?: string;\n }\n>;\nexport interface Spec {\n operations: Record<string, Operation[]>;\n commonZod?: string;\n name: string;\n options: Options;\n servers: string[];\n}\n\nexport interface OperationInput {\n in: string;\n schema: string;\n}\nexport interface Operation {\n name: string;\n errors: string[];\n type: string;\n imports: Import[];\n trigger: Record<string, any>;\n contentType?: string;\n schemas: Record<string, string>;\n schema?: string;\n inputs: Record<string, OperationInput>;\n formatOutput: () => { import: string; use: string };\n}\n\nexport function generateClientSdk(spec: Spec) {\n const emitter = new Emitter();\n const streamEmitter = new StreamEmitter();\n const schemas: Record<string, string[]> = {};\n const schemasImports: string[] = [];\n const schemaEndpoint = new SchemaEndpoint();\n const errors: string[] = [];\n for (const [name, operations] of Object.entries(spec.operations)) {\n const featureSchemaFileName = camelcase(name);\n schemas[featureSchemaFileName] = [`import z from 'zod';`];\n emitter.addImport(\n `import * as ${featureSchemaFileName} from './inputs/${featureSchemaFileName}.ts';`,\n );\n streamEmitter.addImport(\n `import * as ${featureSchemaFileName} from './inputs/${featureSchemaFileName}.ts';`,\n );\n schemaEndpoint.addImport(\n `import * as ${featureSchemaFileName} from './inputs/${featureSchemaFileName}.ts';`,\n );\n for (const operation of operations) {\n const schemaName = camelcase(`${operation.name} schema`);\n\n const schema = `export const ${schemaName} = ${\n Object.keys(operation.schemas).length === 1\n ? Object.values(operation.schemas)[0]\n : toLitObject(operation.schemas)\n };`;\n\n schemas[featureSchemaFileName].push(schema);\n schemasImports.push(\n ...operation.imports\n .map((it) => (it.namedImports ?? []).map((it) => it.name))\n .flat(),\n );\n const schemaRef = `${featureSchemaFileName}.${schemaName}`;\n const output = operation.formatOutput();\n const inputHeaders: string[] = [];\n const inputQuery: string[] = [];\n const inputBody: string[] = [];\n const inputParams: string[] = [];\n for (const [name, prop] of Object.entries(operation.inputs)) {\n if (prop.in === 'headers' || prop.in === 'header') {\n inputHeaders.push(`\"${name}\"`);\n } else if (prop.in === 'query') {\n inputQuery.push(`\"${name}\"`);\n } else if (prop.in === 'body') {\n inputBody.push(`\"${name}\"`);\n } else if (prop.in === 'path') {\n inputParams.push(`\"${name}\"`);\n } else if (prop.in === 'internal') {\n // ignore internal sources\n continue;\n } else {\n throw new Error(\n `Unknown source ${prop.in} in ${name} ${JSON.stringify(\n prop,\n )} in ${operation.name}`,\n );\n }\n }\n if (operation.type === 'sse') {\n const input = `z.infer<typeof ${schemaRef}>`;\n const endpoint = `${operation.trigger.method.toUpperCase()} ${operation.trigger.path}`;\n streamEmitter.addImport(\n `import type {${pascalcase(operation.name)}} from './outputs/${spinalcase(operation.name)}';`,\n );\n streamEmitter.addEndpoint(\n endpoint,\n `{input: ${input}, output: ${output.use}}`,\n );\n schemaEndpoint.addEndpoint(\n endpoint,\n `{\n schema: ${schemaRef},\n toRequest(input: StreamEndpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Partial<Record<string, string>>}) {\n const endpoint = '${endpoint}';\n return toRequest(endpoint, json(input, {\n inputHeaders: [${inputHeaders}],\n inputQuery: [${inputQuery}],\n inputBody: [${inputBody}],\n inputParams: [${inputParams}],\n }), init);\n },\n }`,\n );\n } else {\n emitter.addImport(\n `import type {${output.import}} from './outputs/${spinalcase(operation.name)}';`,\n );\n errors.push(...(operation.errors ?? []));\n\n const addTypeParser = Object.keys(operation.schemas).length > 1;\n for (const type in operation.schemas ?? {}) {\n let typePrefix = '';\n if (addTypeParser && type !== 'json') {\n typePrefix = `${type} `;\n }\n const input = `typeof ${schemaRef}${addTypeParser ? `.${type}` : ''}`;\n\n const endpoint = `${typePrefix}${operation.trigger.method.toUpperCase()} ${operation.trigger.path}`;\n emitter.addEndpoint(\n endpoint,\n `{input: z.infer<${input}>; output: ${output.use}; error: ${(operation.errors ?? ['ServerError']).concat(`ParseError<${input}>`).join('|')}}`,\n );\n schemaEndpoint.addEndpoint(\n endpoint,\n `{\n schema: ${schemaRef}${addTypeParser ? `.${type}` : ''},\n toRequest(input: Endpoints['${endpoint}']['input'], init: {baseUrl:string; headers?: Partial<Record<string, string>>}) {\n const endpoint = '${endpoint}';\n return toRequest(endpoint, ${operation.contentType || 'json'}(input, {\n inputHeaders: [${inputHeaders}],\n inputQuery: [${inputQuery}],\n inputBody: [${inputBody}],\n inputParams: [${inputParams}],\n }), init);\n },\n }`,\n );\n }\n }\n }\n }\n\n emitter.addImport(\n `import type { ${removeDuplicates(errors, (it) => it).join(', ')} } from './http/response.ts';`,\n );\n return {\n ...Object.fromEntries(\n Object.entries(schemas).map(([key, value]) => [\n `inputs/${key}.ts`,\n [\n schemasImports.length\n ? `import {${removeDuplicates(schemasImports, (it) => it)}} from '../zod';`\n : '',\n spec.commonZod ? 'import * as commonZod from \"../zod.ts\";' : '',\n ...value,\n ]\n .map((it) => it.trim())\n .filter(Boolean)\n .join('\\n') + '\\n', // add a newline at the end\n ]),\n ),\n 'client.ts': backend(spec),\n 'schemas.ts': schemaEndpoint.complete(),\n 'endpoints.ts': emitter.complete(),\n };\n}\n", "import { toLitObject } from '@sdk-it/core';\n\nimport type { Spec } from './sdk.ts';\n\nexport default (spec: Spec) => {\n const optionsEntries = Object.entries(spec.options).map(\n ([key, value]) => [`'${key}'`, value] as const,\n );\n const defaultHeaders = `{${optionsEntries\n .filter(([, value]) => value.in === 'header')\n .map(\n ([key, value]) =>\n `${key}: this.options[${value.optionName ? `'${value.optionName}'` : key}]`,\n )\n .join(',\\n')}}`;\n const defaultInputs = `{${optionsEntries\n .filter(([, value]) => value.in === 'input')\n .map(\n ([key, value]) =>\n `${key}: this.options[${value.optionName ? `'${value.optionName}'` : key}]`,\n )\n .join(',\\n')}}`;\n const specOptions: Record<string, { schema: string }> = {\n ...Object.fromEntries(\n optionsEntries.map(([key, value]) => [value.optionName ?? key, value]),\n ),\n fetch: {\n schema: 'fetchType',\n },\n baseUrl: {\n schema: spec.servers.length\n ? `z.enum(servers).default(servers[0])`\n : 'z.string()',\n },\n };\n\n return `\nimport { fetchType, sendRequest } from './http/send-request.ts';\nimport z from 'zod';\nimport type { Endpoints } from './endpoints.ts';\nimport schemas from './schemas.ts';\n${spec.servers.length ? `const servers = ${JSON.stringify(spec.servers, null, 2)} as const` : ''}\nconst optionsSchema = z.object(${toLitObject(specOptions, (x) => x.schema)});\n\ntype ${spec.name}Options = z.infer<typeof optionsSchema>;\n\nexport class ${spec.name} {\n\n constructor(public options: ${spec.name}Options) {}\n\n async request<E extends keyof Endpoints>(\n endpoint: E,\n input: Endpoints[E]['input'],\n ): Promise<readonly [Endpoints[E]['output'], Endpoints[E]['error'] | null]> {\n const route = schemas[endpoint];\n return sendRequest(Object.assign(this.#defaultInputs, input), route, {\n baseUrl: this.options.baseUrl,\n fetch: this.options.fetch,\n headers: this.defaultHeaders,\n });\n }\n\n get defaultHeaders() {\n return ${defaultHeaders}\n }\n\n get #defaultInputs() {\n return ${defaultInputs}\n }\n\n setOptions(options: Partial<${spec.name}Options>) {\n const validated = optionsSchema.partial().parse(options);\n\n for (const key of Object.keys(validated) as (keyof ${spec.name}Options)[]) {\n if (validated[key] !== undefined) {\n (this.options[key] as typeof validated[typeof key]) = validated[key]!;\n }\n }\n }\n}`;\n};\n", "import type {\n ComponentsObject,\n ReferenceObject,\n SecurityRequirementObject,\n} from 'openapi3-ts/oas31';\n\nimport { type Options } from './sdk.ts';\n\nexport function isRef(obj: any): obj is ReferenceObject {\n return '$ref' in obj;\n}\nexport function securityToOptions(\n security: SecurityRequirementObject[],\n securitySchemas: ComponentsObject['securitySchemes'],\n staticIn?: string,\n) {\n securitySchemas ??= {};\n const options: Options = {};\n for (const it of security) {\n const [name] = Object.keys(it);\n const schema = securitySchemas[name];\n if (isRef(schema)) {\n throw new Error(`Ref security schemas are not supported`);\n }\n if (schema.type === 'http') {\n options['authorization'] = {\n in: staticIn ?? 'header',\n schema: 'z.string().optional()',\n optionName: 'token',\n };\n continue;\n }\n if (schema.type === 'apiKey') {\n if (!schema.in) {\n throw new Error(`apiKey security schema must have an \"in\" field`);\n }\n if (!schema.name) {\n throw new Error(`apiKey security schema must have a \"name\" field`);\n }\n options[schema.name] = {\n in: staticIn ?? schema.in,\n schema: 'z.string().optional()',\n };\n continue;\n }\n }\n return options;\n}\n", "import { parse } from 'fast-content-type-parse';\n\nexport async function handleError(response: Response) {\n try {\n if (response.status >= 400 && response.status < 500) {\n const body = (await response.json()) as Record<string, any>;\n return {\n status: response.status,\n body: body,\n };\n }\n return new Error(\n `An error occurred while fetching the data. Status: ${response.status}`,\n );\n } catch (error) {\n return error as any;\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 async function parseResponse(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 const isChunked = response.headers.get('Transfer-Encoding') === 'chunked';\n if (isChunked) {\n return response.body!;\n // return handleChunkedResponse(response, contentType);\n }\n\n const { type } = parse(contentType);\n switch (type) {\n case 'application/json':\n return response.json();\n case 'text/plain':\n return response.text();\n case 'text/html':\n return response.text();\n case 'text/xml':\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", "import { z } from 'zod';\n\nexport type ParseError<T extends z.ZodType<any, any, any>> = {\n kind: 'parse';\n} & z.inferFlattenedErrors<T>;\n\nexport function parse<T extends z.ZodType>(\n schema: T,\n input: unknown,\n) {\n const result = schema.safeParse(input);\n if (!result.success) {\n const errors = result.error.flatten((issue) => issue);\n return [null, errors];\n }\n return [result.data as z.infer<T>, null];\n}\n", "type Method = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\ntype ContentType = 'xml' | 'json' | 'urlencoded' | 'multipart';\ntype Endpoint = `${ContentType} ${Method} ${string}` | `${Method} ${string}`;\n\nexport function createUrl(base: string, path: string, query: URLSearchParams) {\n const url = new URL(path, base);\n url.search = query.toString();\n return url;\n}\nfunction template(\n templateString: string,\n templateVariables: Record<string, any>,\n): string {\n const nargs = /{([0-9a-zA-Z_]+)}/g;\n return templateString.replace(nargs, (match, key: string, index: number) => {\n // Handle escaped double braces\n if (\n templateString[index - 1] === '{' &&\n templateString[index + match.length] === '}'\n ) {\n return key;\n }\n\n const result = key in templateVariables ? templateVariables[key] : null;\n return result === null || result === undefined ? '' : String(result);\n });\n}\n\ninterface ToRequest {\n <T extends Endpoint>(\n endpoint: T,\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n defaults: {\n baseUrl: string;\n headers?: Partial<Record<string, string>>;\n },\n ): Request;\n urlencoded: <T extends Endpoint>(\n endpoint: T,\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n defaults: {\n baseUrl: string;\n headers?: Partial<Record<string, string>>;\n },\n ) => Request;\n}\n\nfunction _json(\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n) {\n const headers = new Headers({});\n for (const header of props.inputHeaders) {\n headers.set(header, input[header]);\n }\n\n const body: Record<string, any> = {};\n for (const prop of props.inputBody) {\n body[prop] = input[prop];\n }\n\n const query = new URLSearchParams();\n for (const key of props.inputQuery) {\n const value = input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = props.inputParams.reduce<Record<string, any>>((acc, key) => {\n acc[key] = input[key];\n return acc;\n }, {});\n\n return {\n body: JSON.stringify(body),\n query,\n params,\n headers: { 'Content-Type': 'application/json', Accept: 'application/json' },\n };\n}\n\ntype Input = Record<string, any>;\ntype Props = {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n};\n\nabstract class Serializer {\n constructor(\n protected input: Input,\n protected props: Props,\n ) {}\n abstract getBody(): BodyInit | null;\n abstract getHeaders(): Partial<Record<string, string>>;\n serialize(): Serialized {\n const headers = new Headers({});\n for (const header of this.props.inputHeaders) {\n headers.set(header, this.input[header]);\n }\n\n const query = new URLSearchParams();\n for (const key of this.props.inputQuery) {\n const value = this.input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = this.props.inputParams.reduce<Record<string, any>>(\n (acc, key) => {\n acc[key] = this.input[key];\n return acc;\n },\n {},\n );\n\n return {\n body: this.getBody(),\n query,\n params,\n headers: this.getHeaders(),\n };\n }\n}\n\ninterface Serialized {\n body: BodyInit | null;\n query: URLSearchParams;\n params: Record<string, any>;\n headers: Partial<Record<string, string>>;\n}\n\nclass JsonSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body: Record<string, any> = {};\n for (const prop of this.props.inputBody) {\n body[prop] = this.input[prop];\n }\n return JSON.stringify(body);\n }\n getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n };\n }\n}\n\nclass UrlencodedSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new URLSearchParams();\n for (const prop of this.props.inputBody) {\n body.set(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nclass FormDataSerializer extends Serializer {\n getBody(): BodyInit | null {\n const body = new FormData();\n for (const prop of this.props.inputBody) {\n body.append(prop, this.input[prop]);\n }\n return body;\n }\n getHeaders(): Record<string, string> {\n return {};\n }\n}\n\nexport function json(input: Input, props: Props) {\n return new JsonSerializer(input, props).serialize();\n}\nexport function urlencoded(input: Input, props: Props) {\n return new UrlencodedSerializer(input, props).serialize();\n}\nexport function formdata(input: Input, props: Props) {\n return new FormDataSerializer(input, props).serialize();\n}\n\nexport function _urlencoded(\n input: Record<string, any>,\n props: {\n inputHeaders: string[];\n inputQuery: string[];\n inputBody: string[];\n inputParams: string[];\n },\n) {\n const headers = new Headers({});\n for (const header of props.inputHeaders) {\n headers.set(header, input[header]);\n }\n\n const body = new URLSearchParams();\n for (const prop of props.inputBody) {\n body.set(prop, input[prop]);\n }\n\n const query = new URLSearchParams();\n for (const key of props.inputQuery) {\n const value = input[key];\n if (value !== undefined) {\n query.set(key, String(value));\n }\n }\n\n const params = props.inputParams.reduce<Record<string, any>>((acc, key) => {\n acc[key] = input[key];\n return acc;\n }, {});\n\n return {\n body,\n query,\n params,\n headers: {},\n };\n}\n\nexport function toRequest<T extends Endpoint>(\n endpoint: T,\n input: Serialized,\n defaults: {\n baseUrl: string;\n headers?: Partial<Record<string, string>>;\n },\n): Request {\n const [method, path] = endpoint.split(' ');\n\n const headers = new Headers(\n Object.entries({\n ...defaults?.headers,\n ...input.headers,\n }).filter(truthyEntry),\n );\n const pathVariable = template(path, input.params);\n\n const url = createUrl(defaults.baseUrl, pathVariable, input.query);\n return new Request(url, {\n method: method,\n headers: headers,\n body: method === 'GET' ? undefined : input.body,\n });\n}\n\nfunction truthyEntry(entry: [string, unknown]): entry is [string, string] {\n return entry[1] !== undefined;\n}\n", "export interface ApiResponse<Status extends number, Body extends unknown> {\n kind: 'response';\n status: Status;\n body: Body;\n}\n\n// 4xx Client Errors\nexport type BadRequest = ApiResponse<400, { message: string }>;\nexport type Unauthorized = ApiResponse<401, { message: string }>;\nexport type PaymentRequired = ApiResponse<402, { message: string }>;\nexport type Forbidden = ApiResponse<403, { message: string }>;\nexport type NotFound = ApiResponse<404, { message: string }>;\nexport type MethodNotAllowed = ApiResponse<405, { message: string }>;\nexport type NotAcceptable = ApiResponse<406, { message: string }>;\nexport type Conflict = ApiResponse<409, { message: string }>;\nexport type Gone = ApiResponse<410, { message: string }>;\nexport type UnprocessableEntity = ApiResponse<422, { message: string; errors?: Record<string, string[]> }>;\nexport type TooManyRequests = ApiResponse<429, { message: string; retryAfter?: string }>;\nexport type PayloadTooLarge = ApiResponse<413, { message: string; }>;\nexport type UnsupportedMediaType = ApiResponse<415, { message: string; }>;\n\n// 5xx Server Errors\nexport type InternalServerError = ApiResponse<500, { message: string }>;\nexport type NotImplemented = ApiResponse<501, { message: string }>;\nexport type BadGateway = ApiResponse<502, { message: string }>;\nexport type ServiceUnavailable = ApiResponse<503, { message: string; retryAfter?: string }>;\nexport type GatewayTimeout = ApiResponse<504, { message: string }>;\n\nexport type ClientError =\n | BadRequest\n | Unauthorized\n | PaymentRequired\n | Forbidden\n | NotFound\n | MethodNotAllowed\n | NotAcceptable\n | Conflict\n | Gone\n | UnprocessableEntity\n | TooManyRequests;\n\nexport type ServerError =\n | InternalServerError\n | NotImplemented\n | BadGateway\n | ServiceUnavailable\n | GatewayTimeout;\n\nexport type ProblematicResponse = ClientError | ServerError;\n", "import z from 'zod';\n\nimport { handleError, parseResponse } from './parse-response.ts';\nimport { parse } from './parser.ts';\n\nexport interface RequestSchema {\n schema: z.ZodType;\n toRequest: (\n input: any,\n init: { baseUrl: string; headers?: Partial<Record<string, string>> },\n ) => any;\n}\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 sendRequest(\n input: any,\n route: RequestSchema,\n options: {\n baseUrl: string;\n fetch?: z.infer<typeof fetchType>;\n headers?: Partial<Record<string, string>>;\n },\n) {\n const [parsedInput, parseError] = parse(route.schema, input);\n if (parseError) {\n return [null as never, { ...parseError, kind: 'parse' } as never] as const;\n }\n const request = route.toRequest(parsedInput as never, {\n headers: options.headers,\n baseUrl: options.baseUrl,\n });\n const response = await (options.fetch ?? fetch)(request);\n if (response.ok) {\n const data = await parseResponse(response);\n return [data, null] as const;\n }\n const error = await handleError(response);\n return [null as never, { ...error, kind: 'response' }] as const;\n}\n", "import { watch as nodeWatch } from 'node:fs/promises';\nimport { debounceTime, from } from 'rxjs';\n\nexport function watch(path: string) {\n return from(\n nodeWatch(path, {\n persistent: true,\n recursive: true,\n }),\n ).pipe(debounceTime(400));\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["ts", "dirname", "join", "join", "dirname", "get", "camelcase", "pascalcase", "spinalcase", "it", "name", "security", "spinalcase", "camelcase", "methods", "security", "get", "pascalcase", "client_default", "security", "client_default"]
|
|
7
7
|
}
|
package/dist/lib/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/lib/client.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;+BAEf,IAAI;AAA1B,wBA4EE"}
|
package/dist/lib/generate.d.ts
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
+
import { npmRunPathEnv } from 'npm-run-path';
|
|
1
2
|
import type { OpenAPIObject } from 'openapi3-ts/oas31';
|
|
2
3
|
export declare function generate(spec: OpenAPIObject, settings: {
|
|
3
4
|
output: string;
|
|
4
5
|
name?: string;
|
|
6
|
+
mode?: 'full' | 'minimal';
|
|
7
|
+
formatCode?: (options: {
|
|
8
|
+
output: string;
|
|
9
|
+
env: ReturnType<typeof npmRunPathEnv>;
|
|
10
|
+
}) => void | Promise<void>;
|
|
5
11
|
}): Promise<void>;
|
|
6
12
|
//# sourceMappingURL=generate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/lib/generate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/lib/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAoCvD,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE;IACR,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE;QACrB,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;KACvC,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B,iBA8DF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/lib/generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,aAAa,EACb,eAAe,
|
|
1
|
+
{"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../../src/lib/generator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAEV,aAAa,EACb,eAAe,EAIhB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAAE,KAAK,SAAS,EAAa,MAAM,UAAU,CAAC;AAGrD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AACD,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AAsBD,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,WAAW,CAAC,EAAE,CACZ,SAAS,EAAE,eAAe,EAC1B,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,KACX,MAAM,CAAC;CACb;AAED,eAAO,MAAM,QAAQ,EAAE,OAAO,CAAC,iBAAiB,CAAC,GAC/C,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,aAAa,CAAC,CAYhD,CAAC;AAEF,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB;;;;EAqNrD"}
|
package/dist/lib/sdk.d.ts
CHANGED
|
@@ -10,13 +10,6 @@ export interface NamedImport {
|
|
|
10
10
|
alias?: string;
|
|
11
11
|
isTypeOnly: boolean;
|
|
12
12
|
}
|
|
13
|
-
export interface SecurityScheme {
|
|
14
|
-
bearerAuth: {
|
|
15
|
-
type: 'http';
|
|
16
|
-
scheme: 'bearer';
|
|
17
|
-
bearerFormat: 'JWT';
|
|
18
|
-
};
|
|
19
|
-
}
|
|
20
13
|
export interface SdkConfig {
|
|
21
14
|
/**
|
|
22
15
|
* The name of the sdk client
|
|
@@ -26,23 +19,22 @@ export interface SdkConfig {
|
|
|
26
19
|
options?: Record<string, any>;
|
|
27
20
|
emptyBodyAsNull?: boolean;
|
|
28
21
|
stripBodyFromGetAndHead?: boolean;
|
|
29
|
-
securityScheme?: SecurityScheme;
|
|
30
22
|
output: string;
|
|
31
|
-
formatGeneratedCode?: boolean;
|
|
32
23
|
}
|
|
24
|
+
export type Options = Record<string, {
|
|
25
|
+
in: string;
|
|
26
|
+
schema: string;
|
|
27
|
+
optionName?: string;
|
|
28
|
+
}>;
|
|
33
29
|
export interface Spec {
|
|
34
|
-
|
|
30
|
+
operations: Record<string, Operation[]>;
|
|
35
31
|
commonZod?: string;
|
|
36
32
|
name: string;
|
|
37
|
-
options
|
|
38
|
-
|
|
39
|
-
schema: string;
|
|
40
|
-
}>;
|
|
41
|
-
securityScheme?: SecurityScheme;
|
|
42
|
-
servers?: string[];
|
|
33
|
+
options: Options;
|
|
34
|
+
servers: string[];
|
|
43
35
|
}
|
|
44
36
|
export interface OperationInput {
|
|
45
|
-
|
|
37
|
+
in: string;
|
|
46
38
|
schema: string;
|
|
47
39
|
}
|
|
48
40
|
export interface Operation {
|
|
@@ -61,7 +53,7 @@ export interface Operation {
|
|
|
61
53
|
};
|
|
62
54
|
}
|
|
63
55
|
export declare function generateClientSdk(spec: Spec): {
|
|
64
|
-
'
|
|
56
|
+
'client.ts': string;
|
|
65
57
|
'schemas.ts': string;
|
|
66
58
|
'endpoints.ts': string;
|
|
67
59
|
};
|
package/dist/lib/sdk.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/lib/sdk.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AA0CD,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../src/lib/sdk.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,MAAM;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;CACrC;AACD,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,OAAO,CAAC;CACrB;AA0CD,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC9B,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,OAAO,GAAG,MAAM,CAC1B,MAAM,EACN;IACE,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CACF,CAAC;AACF,MAAM,WAAW,IAAI;IACnB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AACD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IACvC,YAAY,EAAE,MAAM;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACrD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,IAAI;;;;EAmJ3C"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ComponentsObject, ReferenceObject, SecurityRequirementObject } from 'openapi3-ts/oas31';
|
|
2
|
+
import { type Options } from './sdk.ts';
|
|
3
|
+
export declare function isRef(obj: any): obj is ReferenceObject;
|
|
4
|
+
export declare function securityToOptions(security: SecurityRequirementObject[], securitySchemas: ComponentsObject['securitySchemes'], staticIn?: string): Options;
|
|
5
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,yBAAyB,EAC1B,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,UAAU,CAAC;AAExC,wBAAgB,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,IAAI,eAAe,CAEtD;AACD,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,yBAAyB,EAAE,EACrC,eAAe,EAAE,gBAAgB,CAAC,iBAAiB,CAAC,EACpD,QAAQ,CAAC,EAAE,MAAM,WAiClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/lib/watcher.ts"],"names":[],"mappings":"AAGA,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,2EAOjC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdk-it/typescript",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -21,11 +21,11 @@
|
|
|
21
21
|
"!**/*.tsbuildinfo"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@sdk-it/core": "0.
|
|
25
|
-
"debug": "^4.4.0",
|
|
24
|
+
"@sdk-it/core": "0.6.0",
|
|
26
25
|
"openapi3-ts": "^4.4.0",
|
|
27
26
|
"stringcase": "^4.3.1",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
27
|
+
"lodash-es": "^4.17.21",
|
|
28
|
+
"npm-run-path": "6.0.0",
|
|
29
|
+
"lodash": "4.17.21"
|
|
30
30
|
}
|
|
31
31
|
}
|