@sdk-it/dart 0.18.0 → 0.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.js +216 -96
- package/dist/index.js.map +4 -4
- package/dist/lib/dart-emitter.d.ts.map +1 -1
- package/dist/lib/generate.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './lib/generate.
|
|
1
|
+
export * from './lib/generate.js';
|
|
2
2
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -2,20 +2,142 @@
|
|
|
2
2
|
import { parse as partContentType } from "fast-content-type-parse";
|
|
3
3
|
import { merge as merge2 } from "lodash-es";
|
|
4
4
|
import assert2 from "node:assert";
|
|
5
|
-
import { writeFile } from "node:fs/promises";
|
|
6
|
-
import { join } from "node:path";
|
|
5
|
+
import { writeFile as writeFile2 } from "node:fs/promises";
|
|
6
|
+
import { join as join2 } from "node:path";
|
|
7
7
|
import { camelcase as camelcase3 } from "stringcase";
|
|
8
8
|
import yaml from "yaml";
|
|
9
|
+
|
|
10
|
+
// packages/core/dist/index.js
|
|
9
11
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
pascalcase as _pascalcase,
|
|
13
|
+
snakecase as _snakecase,
|
|
14
|
+
spinalcase as _spinalcase
|
|
15
|
+
} from "stringcase";
|
|
16
|
+
import ts, { TypeFlags, symbolName } from "typescript";
|
|
17
|
+
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
18
|
+
import { dirname, extname, isAbsolute, join } from "node:path";
|
|
19
|
+
import debug from "debug";
|
|
20
|
+
import ts2 from "typescript";
|
|
21
|
+
import { get } from "lodash-es";
|
|
22
|
+
var deriveSymbol = Symbol.for("serialize");
|
|
23
|
+
var $types = Symbol.for("types");
|
|
24
|
+
async function exist(file) {
|
|
25
|
+
return stat(file).then(() => true).catch(() => false);
|
|
26
|
+
}
|
|
27
|
+
async function writeFiles(dir, contents) {
|
|
28
|
+
await Promise.all(
|
|
29
|
+
Object.entries(contents).map(async ([file, content]) => {
|
|
30
|
+
if (content === null) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const filePath = isAbsolute(file) ? file : join(dir, file);
|
|
34
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
35
|
+
if (typeof content === "string") {
|
|
36
|
+
await writeFile(filePath, content, "utf-8");
|
|
37
|
+
} else {
|
|
38
|
+
if (content.ignoreIfExists) {
|
|
39
|
+
if (!await exist(filePath)) {
|
|
40
|
+
await writeFile(filePath, content.content, "utf-8");
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
await writeFile(filePath, content.content, "utf-8");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
async function getFolderExportsV2(folder, options = {
|
|
50
|
+
extensions: "ts",
|
|
51
|
+
ignore: () => false,
|
|
52
|
+
includeExtension: true,
|
|
53
|
+
exportSyntax: "export * from "
|
|
54
|
+
}) {
|
|
55
|
+
options.includeExtension ??= true;
|
|
56
|
+
if (!await exist(folder)) {
|
|
57
|
+
return "";
|
|
58
|
+
}
|
|
59
|
+
const files = await readdir(folder, { withFileTypes: true });
|
|
60
|
+
const exports = [];
|
|
61
|
+
for (const file of files) {
|
|
62
|
+
if (options.ignore?.(file)) {
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (file.isDirectory()) {
|
|
66
|
+
if (await exist(
|
|
67
|
+
`${file.parentPath}/${file.name}/index.${options.extensions}`
|
|
68
|
+
)) {
|
|
69
|
+
exports.push(
|
|
70
|
+
`${options.exportSyntax} './${file.name}/index${options.includeExtension ? `.${options.extensions}` : ""}';`
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
} else if (file.name !== `index.${options.extensions}` && options.extensions.includes(getExt(file.name))) {
|
|
74
|
+
exports.push(
|
|
75
|
+
`${options.exportSyntax} './${options.includeExtension ? file.name : file.name.replace(extname(file.name), "")}';`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return exports.join("\n");
|
|
80
|
+
}
|
|
81
|
+
var getExt = (fileName) => {
|
|
82
|
+
if (!fileName) {
|
|
83
|
+
return "";
|
|
84
|
+
}
|
|
85
|
+
const lastDot = fileName.lastIndexOf(".");
|
|
86
|
+
if (lastDot === -1) {
|
|
87
|
+
return "";
|
|
88
|
+
}
|
|
89
|
+
const ext = fileName.slice(lastDot + 1).split("/").filter(Boolean).join("");
|
|
90
|
+
if (ext === fileName) {
|
|
91
|
+
return "";
|
|
92
|
+
}
|
|
93
|
+
return ext || "txt";
|
|
94
|
+
};
|
|
95
|
+
var logger = debug("january:client");
|
|
96
|
+
function isRef(obj) {
|
|
97
|
+
return obj && "$ref" in obj;
|
|
98
|
+
}
|
|
99
|
+
function notRef(obj) {
|
|
100
|
+
return !isRef(obj);
|
|
101
|
+
}
|
|
102
|
+
function cleanRef(ref) {
|
|
103
|
+
return ref.replace(/^#\//, "");
|
|
104
|
+
}
|
|
105
|
+
function parseRef(ref) {
|
|
106
|
+
const parts = ref.split("/");
|
|
107
|
+
const [model] = parts.splice(-1);
|
|
108
|
+
const [namespace] = parts.splice(-1);
|
|
109
|
+
return {
|
|
110
|
+
model,
|
|
111
|
+
namespace,
|
|
112
|
+
path: cleanRef(parts.join("/"))
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function followRef(spec, ref) {
|
|
116
|
+
const pathParts = cleanRef(ref).split("/");
|
|
117
|
+
const entry = get(spec, pathParts);
|
|
118
|
+
if (entry && "$ref" in entry) {
|
|
119
|
+
return followRef(spec, entry.$ref);
|
|
120
|
+
}
|
|
121
|
+
return entry;
|
|
122
|
+
}
|
|
123
|
+
function isEmpty(value) {
|
|
124
|
+
if (value === null || value === void 0 || value === "") {
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (Array.isArray(value) && value.length === 0) {
|
|
128
|
+
return true;
|
|
129
|
+
}
|
|
130
|
+
if (typeof value === "object" && Object.keys(value).length === 0) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
function pascalcase(value) {
|
|
136
|
+
return _pascalcase(value.split("/").join(" "));
|
|
137
|
+
}
|
|
138
|
+
function snakecase(value) {
|
|
139
|
+
return _snakecase(value.split("/").join(" "));
|
|
140
|
+
}
|
|
19
141
|
|
|
20
142
|
// packages/spec/dist/lib/loaders/local-loader.js
|
|
21
143
|
import { parse } from "yaml";
|
|
@@ -312,16 +434,7 @@ function isSuccessStatusCode(statusCode) {
|
|
|
312
434
|
// packages/dart/src/lib/dart-emitter.ts
|
|
313
435
|
import { merge } from "lodash-es";
|
|
314
436
|
import assert from "node:assert";
|
|
315
|
-
import { camelcase as camelcase2, snakecase } from "stringcase";
|
|
316
|
-
import {
|
|
317
|
-
cleanRef,
|
|
318
|
-
followRef,
|
|
319
|
-
isEmpty,
|
|
320
|
-
isRef,
|
|
321
|
-
notRef,
|
|
322
|
-
parseRef,
|
|
323
|
-
pascalcase
|
|
324
|
-
} from "@sdk-it/core";
|
|
437
|
+
import { camelcase as camelcase2, snakecase as snakecase2 } from "stringcase";
|
|
325
438
|
var formatName = (it) => {
|
|
326
439
|
const startsWithDigitPattern = /^-?\d/;
|
|
327
440
|
if (typeof it === "number") {
|
|
@@ -349,9 +462,9 @@ var formatName = (it) => {
|
|
|
349
462
|
if (nameToFormat.endsWith("]")) {
|
|
350
463
|
nameToFormat = nameToFormat.slice(0, -1);
|
|
351
464
|
}
|
|
352
|
-
return
|
|
465
|
+
return snakecase2(nameToFormat);
|
|
353
466
|
}
|
|
354
|
-
return
|
|
467
|
+
return snakecase2(String(it));
|
|
355
468
|
};
|
|
356
469
|
var DartSerializer = class {
|
|
357
470
|
#spec;
|
|
@@ -454,12 +567,12 @@ var DartSerializer = class {
|
|
|
454
567
|
if (required) {
|
|
455
568
|
matches.push(`(
|
|
456
569
|
json.containsKey('${camelcase2(propName)}')
|
|
457
|
-
? ${nullable2 ? `json['${propName}'] == null` : `json['${propName}'] != null`}
|
|
570
|
+
? ${nullable2 ? `json['${propName}'] == null` : `json['${propName}'] != null`} ${typeStr.matches ? `&& ${typeStr.matches}` : ""}
|
|
458
571
|
: false)`);
|
|
459
572
|
} else {
|
|
460
573
|
matches.push(`(
|
|
461
574
|
json.containsKey('${camelcase2(propName)}')
|
|
462
|
-
? ${nullable2 ? `json['${propName}'] == null` : `json['${propName}'] != null`}
|
|
575
|
+
? ${nullable2 ? `json['${propName}'] == null` : `json['${propName}'] != null`} ${typeStr.matches ? `|| ${typeStr.matches}` : ""}
|
|
463
576
|
: true)`);
|
|
464
577
|
}
|
|
465
578
|
}
|
|
@@ -496,18 +609,17 @@ return ${matches.join(" && ")};
|
|
|
496
609
|
return required ? `this.${camelcase2(accces)}.toJson()` : `this.${camelcase2(accces)} != null ? this.${camelcase2(accces)}!.toJson() : null`;
|
|
497
610
|
}
|
|
498
611
|
#array(className, schema, required = false, context) {
|
|
499
|
-
let serialized;
|
|
500
612
|
if (!schema.items) {
|
|
501
|
-
|
|
613
|
+
return {
|
|
502
614
|
content: "",
|
|
503
615
|
use: "List<dynamic>",
|
|
504
616
|
toJson: "",
|
|
505
617
|
fromJson: `List<dynamic>.from(${context.name ? `json['${context.name}']` : `json`})})`,
|
|
506
618
|
matches: ""
|
|
507
619
|
};
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
|
|
620
|
+
}
|
|
621
|
+
const itemsType = this.handle(className, schema.items, true, context);
|
|
622
|
+
const fromJson = required ? context.name ? `(json['${context.name}'] as List<${itemsType.simple ? itemsType.use : "dynamic"}>)
|
|
511
623
|
.map((it) => ${itemsType.simple ? "it" : `${itemsType.use}.fromJson(it)`})
|
|
512
624
|
.toList()` : `(json as List<${itemsType.simple ? itemsType.use : "dynamic"}>)
|
|
513
625
|
.map((it) => ${itemsType.simple ? "it" : `${itemsType.use}.fromJson(it)`})
|
|
@@ -520,16 +632,14 @@ return ${matches.join(" && ")};
|
|
|
520
632
|
.map((it) => ${itemsType.simple ? "it" : `${itemsType.use}.fromJson(it)`})
|
|
521
633
|
.toList()
|
|
522
634
|
: null`;
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
}
|
|
532
|
-
return serialized;
|
|
635
|
+
return {
|
|
636
|
+
encode: `input.map((it) => ${itemsType.simple ? "it" : `it.toJson()`}).toList()`,
|
|
637
|
+
content: "",
|
|
638
|
+
use: `List<${itemsType.use}>`,
|
|
639
|
+
fromJson,
|
|
640
|
+
toJson: `${context.required ? `this.${camelcase2(context.name)}${itemsType.simple ? "" : ".map((it) => it.toJson()).toList()"}` : `this.${camelcase2(context.name)}!= null? this.${camelcase2(context.name)}${itemsType.simple ? "" : "!.map((it) => it.toJson()).toList()"} : null`}`,
|
|
641
|
+
matches: `json['${camelcase2(context.name)}'].every((it) => ${itemsType.matches})`
|
|
642
|
+
};
|
|
533
643
|
}
|
|
534
644
|
/**
|
|
535
645
|
* Convert a basic type to Dart
|
|
@@ -564,6 +674,7 @@ return ${matches.join(" && ")};
|
|
|
564
674
|
return {
|
|
565
675
|
content: "",
|
|
566
676
|
use: "dynamic",
|
|
677
|
+
nullable: false,
|
|
567
678
|
toJson: `${camelcase2(context.name)}`,
|
|
568
679
|
fromJson: `json['${context.name}']`
|
|
569
680
|
};
|
|
@@ -603,6 +714,7 @@ return ${matches.join(" && ")};
|
|
|
603
714
|
if (schemas.length === 0) {
|
|
604
715
|
return {
|
|
605
716
|
content: "",
|
|
717
|
+
nullable: false,
|
|
606
718
|
use: "dynamic",
|
|
607
719
|
toJson: `${camelcase2(context.name)}`,
|
|
608
720
|
fromJson: `json['${context.name}']`
|
|
@@ -640,6 +752,7 @@ return ${matches.join(" && ")};
|
|
|
640
752
|
if (schemas.length === 0) {
|
|
641
753
|
return {
|
|
642
754
|
content: "",
|
|
755
|
+
nullable: false,
|
|
643
756
|
use: "dynamic",
|
|
644
757
|
toJson: `${camelcase2(context.name)}`,
|
|
645
758
|
fromJson: `json['${context.name}']`
|
|
@@ -906,12 +1019,12 @@ return false;
|
|
|
906
1019
|
if (schema.allOf && Array.isArray(schema.allOf)) {
|
|
907
1020
|
return this.#allOf(className, schema.allOf, context);
|
|
908
1021
|
}
|
|
909
|
-
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
910
|
-
return this.#anyOf(className, schema.anyOf, context);
|
|
911
|
-
}
|
|
912
1022
|
if (schema.oneOf && Array.isArray(schema.oneOf)) {
|
|
913
1023
|
return this.#oneOf(className, schema.oneOf, context);
|
|
914
1024
|
}
|
|
1025
|
+
if (schema.anyOf && Array.isArray(schema.anyOf)) {
|
|
1026
|
+
return this.#anyOf(className, schema.anyOf, context);
|
|
1027
|
+
}
|
|
915
1028
|
if (schema.enum && Array.isArray(schema.enum)) {
|
|
916
1029
|
return this.#enum(className, schema, context);
|
|
917
1030
|
}
|
|
@@ -935,7 +1048,10 @@ return false;
|
|
|
935
1048
|
content: "",
|
|
936
1049
|
use: "dynamic",
|
|
937
1050
|
toJson: `${camelcase2(context.name)}`,
|
|
938
|
-
fromJson: `json['${context.name}']
|
|
1051
|
+
fromJson: `json['${context.name}']`,
|
|
1052
|
+
nullable: false,
|
|
1053
|
+
matches: ""
|
|
1054
|
+
// keep it empty as 'type is dynamic' is always true
|
|
939
1055
|
};
|
|
940
1056
|
}
|
|
941
1057
|
return this.#primitive(
|
|
@@ -965,39 +1081,45 @@ function isObjectSchema(schema) {
|
|
|
965
1081
|
}
|
|
966
1082
|
|
|
967
1083
|
// packages/dart/src/lib/http/dispatcher.txt
|
|
968
|
-
var dispatcher_default = "import '
|
|
1084
|
+
var dispatcher_default = "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:http/http.dart' as http;\nimport 'package:http_parser/http_parser.dart';\nimport 'package:mime/mime.dart' as mime;\n\nimport './interceptors.dart';\nimport './responses.dart';\n\nclass Dispatcher {\n final List<Interceptor> interceptors;\n\n Dispatcher(this.interceptors);\n\n Future<http.StreamedResponse> multipart(\n RequestConfig config,\n Map<String, dynamic> body,\n ) async {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.MultipartRequest(\n modifiedConfig.method,\n modifiedConfig.url,\n );\n request.headers.addAll(modifiedConfig.headers);\n for (var entry in body.entries) {\n final key = entry.key;\n final value = entry.value;\n if (value is File) {\n final mimeType = mime.lookupMimeType(value.path);\n request.files.add(\n http.MultipartFile(\n key,\n value.openRead(),\n await value.length(),\n filename: value.uri.pathSegments.last,\n contentType: mimeType != null ? MediaType.parse(mimeType) : null,\n ),\n );\n } else {\n request.fields[key] = value.toString();\n }\n }\n\n return request.send();\n }\n\n Future<http.StreamedResponse> empty(RequestConfig config) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n return request.send();\n }\n\n Future<http.StreamedResponse> json(RequestConfig config, dynamic body) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n\n request.headers['Content-Type'] = 'application/json';\n if ((body is Map || body is List)) {\n request.body = jsonEncode(body);\n } else if (body is String) {\n request.body = body;\n } else {\n throw ArgumentError('Unsupported body type: ${body.runtimeType}');\n }\n\n return request.send();\n }\n}\n\nclass Receiver {\n final List<Interceptor> interceptors;\n Receiver(this.interceptors);\n\n dynamic _parse(http.Response response) {\n final contentTypeHeader = response.headers['content-type'];\n final parsed = parseContentType(contentTypeHeader);\n if (parsed.type == 'application/json') {\n return jsonDecode(response.body);\n } else if (parsed.type == 'text/plain') {\n return response.body;\n } else if (parsed.type == 'application/octet-stream') {\n return response.bodyBytes;\n } else {\n throw UnsupportedError('Unsupported content type: ${parsed.type}');\n }\n }\n\n dynamic json(http.StreamedResponse stream) async {\n if (stream.statusCode >= 200 && stream.statusCode < 300) {\n final response = await http.Response.fromStream(stream);\n return _parse(response);\n }\n switch (stream.statusCode) {\n case 400:\n throw BadRequestError('');\n case 401:\n throw UnauthorizedError('');\n case 403:\n throw ForbiddenError('');\n case 404:\n throw NotFoundError('');\n case 500:\n throw InternalServerError('');\n case 402:\n throw PaymentRequiredError('');\n case 405:\n throw MethodNotAllowedError('');\n case 406:\n throw NotAcceptableError('');\n case 409:\n throw ConflictError('');\n case 410:\n throw GoneError('');\n case 422:\n throw UnprocessableEntityError('');\n case 429:\n throw TooManyRequestsError('');\n case 413:\n throw PayloadTooLargeError('');\n case 415:\n throw UnsupportedMediaTypeError('');\n case 501:\n throw NotImplementedError('');\n case 502:\n throw BadGatewayError('');\n case 503:\n throw ServiceUnavailableError('');\n case 504:\n throw GatewayTimeoutError('');\n default:\n throw UnknownApiError('', stream.statusCode);\n }\n }\n}\n\n({String type, Map<String, String> parameters}) parseContentType(\n String? contentTypeHeader,\n) {\n if (contentTypeHeader == null || contentTypeHeader.isEmpty) {\n return (type: '', parameters: {});\n }\n final parts = contentTypeHeader.split(';');\n final type = parts[0].trim();\n final parameters = <String, String>{};\n for (var i = 1; i < parts.length; i++) {\n final param = parts[i].split('=');\n if (param.length == 2) {\n parameters[param[0].trim()] = param[1].trim();\n }\n }\n\n return (type: type, parameters: parameters);\n}\n";
|
|
969
1085
|
|
|
970
1086
|
// packages/dart/src/lib/http/interceptors.txt
|
|
971
1087
|
var interceptors_default = "abstract class Interceptor {\n RequestConfig before(RequestConfig config);\n void after();\n}\n\nclass BaseUrlInterceptor extends Interceptor {\n final String Function() getBaseUrl;\n BaseUrlInterceptor(this.getBaseUrl);\n\n @override\n RequestConfig before(RequestConfig config) {\n final baseUrl = getBaseUrl();\n if (config.url.scheme.isEmpty) {\n config.url = Uri.parse(baseUrl + config.url.toString());\n }\n return config;\n }\n\n @override\n void after() {\n //\n }\n}\n\nclass RequestConfig {\n final String method;\n Uri url;\n final Map<String, String> headers;\n RequestConfig({required this.method, required this.url, required this.headers});\n}\n";
|
|
972
1088
|
|
|
1089
|
+
// packages/dart/src/lib/http/responses.txt
|
|
1090
|
+
var responses_default = "sealed class ApiError {\n final String message;\n final int? statusCode;\n final String status;\n const ApiError(this.message, {this.statusCode, this.status = ''});\n\n @override\n String toString() =>\n 'ApiError(status: $status, statusCode: $statusCode, message: $message)';\n}\n\nbase class BadRequestError extends ApiError {\n const BadRequestError(String message)\n : super(message, statusCode: 400, status: 'BadRequest');\n}\n\nbase class UnauthorizedError extends ApiError {\n const UnauthorizedError(String message)\n : super(message, statusCode: 401, status: 'Unauthorized');\n}\n\nbase class ForbiddenError extends ApiError {\n const ForbiddenError(String message)\n : super(message, statusCode: 403, status: 'Forbidden');\n}\n\nbase class NotFoundError extends ApiError {\n const NotFoundError(String message)\n : super(message, statusCode: 404, status: 'NotFound');\n}\n\nbase class InternalServerError extends ApiError {\n const InternalServerError(String message)\n : super(message, statusCode: 500, status: 'InternalServerError');\n}\n\nbase class UnknownApiError extends ApiError {\n const UnknownApiError(String message, int statusCode)\n : super(message, statusCode: statusCode, status: 'UnknownApiError');\n}\n\nbase class PaymentRequiredError extends ApiError {\n const PaymentRequiredError(String message)\n : super(message, statusCode: 402, status: 'PaymentRequired');\n}\n\nbase class MethodNotAllowedError extends ApiError {\n const MethodNotAllowedError(String message)\n : super(message, statusCode: 405, status: 'MethodNotAllowed');\n}\n\nbase class NotAcceptableError extends ApiError {\n const NotAcceptableError(String message)\n : super(message, statusCode: 406, status: 'NotAcceptable');\n}\n\nbase class ConflictError extends ApiError {\n const ConflictError(String message)\n : super(message, statusCode: 409, status: 'Conflict');\n}\n\nbase class GoneError extends ApiError {\n const GoneError(String message)\n : super(message, statusCode: 410, status: 'Gone');\n}\n\nbase class UnprocessableEntityError extends ApiError {\n const UnprocessableEntityError(String message)\n : super(message, statusCode: 422, status: 'UnprocessableEntity');\n}\n\nbase class TooManyRequestsError extends ApiError {\n const TooManyRequestsError(String message)\n : super(message, statusCode: 429, status: 'TooManyRequests');\n}\n\nbase class PayloadTooLargeError extends ApiError {\n const PayloadTooLargeError(String message)\n : super(message, statusCode: 413, status: 'PayloadTooLarge');\n}\n\nbase class UnsupportedMediaTypeError extends ApiError {\n const UnsupportedMediaTypeError(String message)\n : super(message, statusCode: 415, status: 'UnsupportedMediaType');\n}\n\nbase class NotImplementedError extends ApiError {\n const NotImplementedError(String message)\n : super(message, statusCode: 501, status: 'NotImplemented');\n}\n\nbase class BadGatewayError extends ApiError {\n const BadGatewayError(String message)\n : super(message, statusCode: 502, status: 'BadGateway');\n}\n\nbase class ServiceUnavailableError extends ApiError {\n const ServiceUnavailableError(String message)\n : super(message, statusCode: 503, status: 'ServiceUnavailable');\n}\n\nbase class GatewayTimeoutError extends ApiError {\n const GatewayTimeoutError(String message)\n : super(message, statusCode: 504, status: 'GatewayTimeout');\n}\n";
|
|
1091
|
+
|
|
973
1092
|
// packages/dart/src/lib/generate.ts
|
|
974
1093
|
function tuneSpec(spec, schemas, refs) {
|
|
975
1094
|
for (const [name, schema] of Object.entries(schemas)) {
|
|
976
|
-
if (
|
|
1095
|
+
if (isRef(schema))
|
|
977
1096
|
continue;
|
|
978
|
-
if (
|
|
1097
|
+
if (!isEmpty(schema.anyOf) && !isEmpty(schema.oneOf)) {
|
|
1098
|
+
delete schema.anyOf;
|
|
1099
|
+
}
|
|
1100
|
+
if (!isEmpty(schema.allOf)) {
|
|
979
1101
|
const schemas2 = schema.allOf;
|
|
980
|
-
const refs2 = schemas2.filter(
|
|
981
|
-
const nonRefs = schemas2.filter(
|
|
1102
|
+
const refs2 = schemas2.filter(isRef);
|
|
1103
|
+
const nonRefs = schemas2.filter(notRef);
|
|
982
1104
|
if (nonRefs.some((it) => it.type && it.type !== "object")) {
|
|
983
1105
|
assert2(false, `allOf ${name} must be an object`);
|
|
984
1106
|
}
|
|
985
1107
|
const objectSchema = merge2(
|
|
986
1108
|
{},
|
|
987
1109
|
...nonRefs,
|
|
988
|
-
...refs2.map((ref) =>
|
|
1110
|
+
...refs2.map((ref) => followRef(spec, ref.$ref))
|
|
989
1111
|
);
|
|
990
1112
|
delete objectSchema.allOf;
|
|
991
1113
|
delete schema.allOf;
|
|
992
1114
|
Object.assign(schema, objectSchema);
|
|
993
1115
|
}
|
|
994
1116
|
if (schema.type === "object") {
|
|
995
|
-
if (!
|
|
1117
|
+
if (!isEmpty(schema.oneOf)) {
|
|
996
1118
|
for (const oneOfIdx in schema.oneOf) {
|
|
997
1119
|
const oneOf = schema.oneOf[oneOfIdx];
|
|
998
|
-
if (
|
|
1120
|
+
if (isRef(oneOf))
|
|
999
1121
|
continue;
|
|
1000
|
-
if (!
|
|
1122
|
+
if (!isEmpty(oneOf.required) && schema.properties) {
|
|
1001
1123
|
schema.oneOf[oneOfIdx] = schema.properties[oneOf.required[0]];
|
|
1002
1124
|
}
|
|
1003
1125
|
}
|
|
@@ -1007,22 +1129,22 @@ function tuneSpec(spec, schemas, refs) {
|
|
|
1007
1129
|
}
|
|
1008
1130
|
schema.properties ??= {};
|
|
1009
1131
|
for (const [propName, value] of Object.entries(schema.properties)) {
|
|
1010
|
-
if (
|
|
1132
|
+
if (isRef(value))
|
|
1011
1133
|
continue;
|
|
1012
|
-
const refName =
|
|
1134
|
+
const refName = pascalcase(`${name} ${propName.replace("[]", "")}`);
|
|
1013
1135
|
refs.push({ name: refName, value });
|
|
1014
1136
|
schema.properties[propName] = {
|
|
1015
1137
|
$ref: `#/components/schemas/${refName}`
|
|
1016
1138
|
};
|
|
1017
1139
|
const props = Object.fromEntries(
|
|
1018
1140
|
Object.entries(value.properties ?? {}).map(([key, value2]) => {
|
|
1019
|
-
return [
|
|
1141
|
+
return [pascalcase(`${refName} ${key}`), value2];
|
|
1020
1142
|
})
|
|
1021
1143
|
);
|
|
1022
1144
|
tuneSpec(spec, props, refs);
|
|
1023
1145
|
}
|
|
1024
1146
|
} else if (schema.type === "array") {
|
|
1025
|
-
if (
|
|
1147
|
+
if (isRef(schema.items))
|
|
1026
1148
|
continue;
|
|
1027
1149
|
const refName = name;
|
|
1028
1150
|
refs.push({ name: refName, value: schema.items ?? {} });
|
|
@@ -1034,7 +1156,7 @@ function tuneSpec(spec, schemas, refs) {
|
|
|
1034
1156
|
}
|
|
1035
1157
|
async function generate(spec, settings) {
|
|
1036
1158
|
const clientName = settings.name || "Client";
|
|
1037
|
-
const output =
|
|
1159
|
+
const output = join2(settings.output, "lib");
|
|
1038
1160
|
const groups = {};
|
|
1039
1161
|
spec.components ??= {};
|
|
1040
1162
|
spec.components.schemas ??= {};
|
|
@@ -1042,19 +1164,19 @@ async function generate(spec, settings) {
|
|
|
1042
1164
|
const outputs = {};
|
|
1043
1165
|
forEachOperation({ spec }, (entry, operation) => {
|
|
1044
1166
|
operation.responses ??= {};
|
|
1167
|
+
spec.components ??= {};
|
|
1168
|
+
spec.components.schemas ??= {};
|
|
1045
1169
|
for (const status in operation.responses) {
|
|
1046
1170
|
if (!isSuccessStatusCode(status))
|
|
1047
1171
|
continue;
|
|
1048
|
-
const response2 =
|
|
1049
|
-
if (
|
|
1172
|
+
const response2 = isRef(operation.responses[status]) ? followRef(spec, operation.responses[status].$ref) : operation.responses[status];
|
|
1173
|
+
if (!isEmpty(response2.content)) {
|
|
1050
1174
|
for (const [contentType, mediaType] of Object.entries(
|
|
1051
1175
|
response2.content
|
|
1052
1176
|
)) {
|
|
1053
1177
|
if (parseJsonContentType(contentType)) {
|
|
1054
|
-
if (mediaType.schema && !
|
|
1055
|
-
|
|
1056
|
-
spec.components.schemas ??= {};
|
|
1057
|
-
const outputName = pascalcase2(`${operation.operationId} output`);
|
|
1178
|
+
if (mediaType.schema && !isRef(mediaType.schema)) {
|
|
1179
|
+
const outputName = pascalcase(`${operation.operationId} output`);
|
|
1058
1180
|
spec.components.schemas[outputName] = mediaType.schema;
|
|
1059
1181
|
operation.responses[status].content[contentType].schema = {
|
|
1060
1182
|
$ref: `#/components/schemas/${outputName}`
|
|
@@ -1067,7 +1189,7 @@ async function generate(spec, settings) {
|
|
|
1067
1189
|
console.log(`Processing ${entry.method} ${entry.path}`);
|
|
1068
1190
|
const group = groups[entry.groupName] ?? (groups[entry.groupName] = {
|
|
1069
1191
|
methods: [],
|
|
1070
|
-
use: `final ${entry.groupName} = new ${
|
|
1192
|
+
use: `final ${entry.groupName} = new ${pascalcase(entry.groupName)}();`
|
|
1071
1193
|
});
|
|
1072
1194
|
const input = toInputs(spec, { entry, operation });
|
|
1073
1195
|
Object.assign(inputs, input.inputs);
|
|
@@ -1077,7 +1199,7 @@ async function generate(spec, settings) {
|
|
|
1077
1199
|
}
|
|
1078
1200
|
group.methods.push(`
|
|
1079
1201
|
Future<${response ? response.returnType : "http.StreamedResponse"}> ${camelcase3(operation.operationId)}(
|
|
1080
|
-
${
|
|
1202
|
+
${isEmpty(operation.requestBody) ? "" : `${input.inputName} input`}
|
|
1081
1203
|
) async {
|
|
1082
1204
|
final stream = await this.dispatcher.${input.contentType}(RequestConfig(
|
|
1083
1205
|
method: '${entry.method}',
|
|
@@ -1093,24 +1215,24 @@ async function generate(spec, settings) {
|
|
|
1093
1215
|
for (const ref of newRefs) {
|
|
1094
1216
|
spec.components.schemas[ref.name] = ref.value;
|
|
1095
1217
|
}
|
|
1096
|
-
await
|
|
1097
|
-
|
|
1218
|
+
await writeFile2(
|
|
1219
|
+
join2(process.cwd(), "openai.json"),
|
|
1098
1220
|
JSON.stringify(spec, null, 2)
|
|
1099
1221
|
);
|
|
1100
1222
|
const models = Object.entries(spec.components.schemas).reduce((acc, [name, schema]) => {
|
|
1101
1223
|
const serializer = new DartSerializer(spec, (name2, content) => {
|
|
1102
|
-
acc[`models/${
|
|
1224
|
+
acc[`models/${snakecase(name2)}.dart`] = `import 'dart:io';import 'dart:typed_data'; import './index.dart';
|
|
1103
1225
|
|
|
1104
1226
|
${content}`;
|
|
1105
1227
|
});
|
|
1106
|
-
serializer.handle(
|
|
1228
|
+
serializer.handle(pascalcase(name), schema);
|
|
1107
1229
|
return acc;
|
|
1108
1230
|
}, {});
|
|
1109
1231
|
const clazzez = Object.entries(groups).reduce(
|
|
1110
1232
|
(acc, [name, { methods }]) => {
|
|
1111
1233
|
return {
|
|
1112
1234
|
...acc,
|
|
1113
|
-
[`api/${
|
|
1235
|
+
[`api/${snakecase(name)}.dart`]: `
|
|
1114
1236
|
import 'dart:convert';
|
|
1115
1237
|
|
|
1116
1238
|
import 'package:http/http.dart' as http;
|
|
@@ -1121,9 +1243,10 @@ import '../outputs/index.dart';
|
|
|
1121
1243
|
import '../models/index.dart';
|
|
1122
1244
|
import '../http.dart';
|
|
1123
1245
|
|
|
1124
|
-
class ${
|
|
1246
|
+
class ${pascalcase(name)}Client {
|
|
1125
1247
|
final Dispatcher dispatcher;
|
|
1126
|
-
|
|
1248
|
+
final Receiver receiver;
|
|
1249
|
+
${pascalcase(name)}Client(this.dispatcher, this.receiver);
|
|
1127
1250
|
${methods.join("\n")}
|
|
1128
1251
|
}
|
|
1129
1252
|
`
|
|
@@ -1132,19 +1255,20 @@ import '../http.dart';
|
|
|
1132
1255
|
{}
|
|
1133
1256
|
);
|
|
1134
1257
|
const client = `
|
|
1135
|
-
${Object.keys(groups).map((name) => `import './api/${
|
|
1258
|
+
${Object.keys(groups).map((name) => `import './api/${snakecase(name)}.dart';`).join("\n")}
|
|
1136
1259
|
import './interceptors.dart';
|
|
1137
1260
|
import './http.dart';
|
|
1138
1261
|
|
|
1139
1262
|
class ${clientName} {
|
|
1140
1263
|
final Options options;
|
|
1141
|
-
${Object.keys(groups).map((name) => `late final ${
|
|
1264
|
+
${Object.keys(groups).map((name) => `late final ${pascalcase(name)}Client ${camelcase3(name)};`).join("\n")}
|
|
1142
1265
|
|
|
1143
1266
|
${clientName}(this.options) {
|
|
1144
|
-
final interceptors = [
|
|
1145
|
-
final dispatcher =
|
|
1267
|
+
final interceptors = [BaseUrlInterceptor(() => this.options.baseUrl)];
|
|
1268
|
+
final dispatcher = Dispatcher(interceptors);
|
|
1269
|
+
final receiver = Receiver(interceptors);
|
|
1146
1270
|
${Object.keys(groups).map(
|
|
1147
|
-
(name) => `this.${camelcase3(name)} =
|
|
1271
|
+
(name) => `this.${camelcase3(name)} = ${pascalcase(name)}Client(dispatcher, receiver);`
|
|
1148
1272
|
).join("\n")}
|
|
1149
1273
|
|
|
1150
1274
|
}
|
|
@@ -1169,24 +1293,25 @@ class Options {
|
|
|
1169
1293
|
...outputs
|
|
1170
1294
|
});
|
|
1171
1295
|
await writeFiles(output, {
|
|
1172
|
-
"models/index.dart": await getFolderExportsV2(
|
|
1296
|
+
"models/index.dart": await getFolderExportsV2(join2(output, "models"), {
|
|
1173
1297
|
exportSyntax: "export",
|
|
1174
1298
|
extensions: "dart"
|
|
1175
1299
|
}),
|
|
1176
|
-
"inputs/index.dart": await getFolderExportsV2(
|
|
1300
|
+
"inputs/index.dart": await getFolderExportsV2(join2(output, "inputs"), {
|
|
1177
1301
|
exportSyntax: "export",
|
|
1178
1302
|
extensions: "dart"
|
|
1179
1303
|
}),
|
|
1180
|
-
"outputs/index.dart": await getFolderExportsV2(
|
|
1304
|
+
"outputs/index.dart": await getFolderExportsV2(join2(output, "outputs"), {
|
|
1181
1305
|
exportSyntax: "export",
|
|
1182
1306
|
extensions: "dart"
|
|
1183
1307
|
}),
|
|
1184
1308
|
"interceptors.dart": interceptors_default,
|
|
1185
1309
|
"http.dart": dispatcher_default,
|
|
1310
|
+
"responses.dart": responses_default,
|
|
1186
1311
|
...clazzez
|
|
1187
1312
|
});
|
|
1188
1313
|
await writeFiles(output, {
|
|
1189
|
-
"package.dart": `${await getFolderExportsV2(
|
|
1314
|
+
"package.dart": `${await getFolderExportsV2(join2(output), {
|
|
1190
1315
|
exportSyntax: "export",
|
|
1191
1316
|
extensions: "dart",
|
|
1192
1317
|
ignore(dirent) {
|
|
@@ -1198,7 +1323,7 @@ class Options {
|
|
|
1198
1323
|
"pubspec.yaml": {
|
|
1199
1324
|
ignoreIfExists: true,
|
|
1200
1325
|
content: yaml.stringify({
|
|
1201
|
-
name: settings.name ? `${
|
|
1326
|
+
name: settings.name ? `${snakecase(clientName.toLowerCase())}_sdk` : "sdk",
|
|
1202
1327
|
version: "0.0.1",
|
|
1203
1328
|
environment: {
|
|
1204
1329
|
sdk: "^3.7.2"
|
|
@@ -1216,13 +1341,13 @@ class Options {
|
|
|
1216
1341
|
}
|
|
1217
1342
|
function toInputs(spec, { entry, operation }) {
|
|
1218
1343
|
const inputs = {};
|
|
1219
|
-
const inputName =
|
|
1344
|
+
const inputName = pascalcase(`${operation.operationId} input`);
|
|
1220
1345
|
let contentType = "empty";
|
|
1221
1346
|
let encode = "";
|
|
1222
|
-
if (!
|
|
1223
|
-
const requestBody =
|
|
1347
|
+
if (!isEmpty(operation.requestBody)) {
|
|
1348
|
+
const requestBody = isRef(operation.requestBody) ? followRef(spec, operation.requestBody.$ref) : operation.requestBody;
|
|
1224
1349
|
for (const type in requestBody.content) {
|
|
1225
|
-
const ctSchema =
|
|
1350
|
+
const ctSchema = isRef(requestBody.content[type].schema) ? followRef(spec, requestBody.content[type].schema.$ref) : requestBody.content[type].schema;
|
|
1226
1351
|
if (!ctSchema) {
|
|
1227
1352
|
console.warn(
|
|
1228
1353
|
`Schema not found for ${type} in ${entry.method} ${entry.path}`
|
|
@@ -1230,7 +1355,7 @@ function toInputs(spec, { entry, operation }) {
|
|
|
1230
1355
|
continue;
|
|
1231
1356
|
}
|
|
1232
1357
|
const serializer = new DartSerializer(spec, (name, content) => {
|
|
1233
|
-
inputs[
|
|
1358
|
+
inputs[join2(`inputs/${name}.dart`)] = `import 'dart:io';import 'dart:typed_data';import '../models/index.dart'; import './index.dart';
|
|
1234
1359
|
|
|
1235
1360
|
${content}`;
|
|
1236
1361
|
});
|
|
@@ -1238,11 +1363,6 @@ ${content}`;
|
|
|
1238
1363
|
alias: isObjectSchema(ctSchema) ? void 0 : inputName
|
|
1239
1364
|
});
|
|
1240
1365
|
encode = serialized.encode;
|
|
1241
|
-
if (contentType) {
|
|
1242
|
-
console.warn(
|
|
1243
|
-
`${entry.method} ${entry.path} have more than one content type`
|
|
1244
|
-
);
|
|
1245
|
-
}
|
|
1246
1366
|
const [mediaType, mediaSubType] = partContentType(type).type.split("/");
|
|
1247
1367
|
if (mediaType === "application") {
|
|
1248
1368
|
contentType = parseJsonContentType(type);
|
|
@@ -1254,11 +1374,11 @@ ${content}`;
|
|
|
1254
1374
|
return { inputs, inputName, contentType, encode };
|
|
1255
1375
|
}
|
|
1256
1376
|
function toOutput(spec, operation) {
|
|
1257
|
-
const outputName =
|
|
1377
|
+
const outputName = pascalcase(`${operation.operationId} output`);
|
|
1258
1378
|
operation.responses ??= {};
|
|
1259
1379
|
const outputs = {};
|
|
1260
1380
|
for (const status in operation.responses) {
|
|
1261
|
-
const response =
|
|
1381
|
+
const response = isRef(operation.responses[status]) ? followRef(spec, operation.responses[status].$ref) : operation.responses[status];
|
|
1262
1382
|
for (const type in response.content) {
|
|
1263
1383
|
const { schema } = response.content[type];
|
|
1264
1384
|
if (!schema) {
|
|
@@ -1287,7 +1407,7 @@ function toOutput(spec, operation) {
|
|
|
1287
1407
|
type: "json",
|
|
1288
1408
|
outputName,
|
|
1289
1409
|
outputs,
|
|
1290
|
-
decode: `final
|
|
1410
|
+
decode: `final json = await this.receiver.json(stream); return ${serialized.fromJson}`,
|
|
1291
1411
|
returnType: serialized.use
|
|
1292
1412
|
};
|
|
1293
1413
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/lib/generate.ts", "../../spec/src/lib/loaders/local-loader.ts", "../../spec/src/lib/loaders/remote-loader.ts", "../../spec/src/lib/operation.ts", "../src/lib/dart-emitter.ts", "../src/lib/http/dispatcher.txt", "../src/lib/http/interceptors.txt"],
|
|
4
|
-
"sourcesContent": ["import { parse as partContentType } from 'fast-content-type-parse';\nimport { merge } from 'lodash-es';\nimport assert from 'node:assert';\nimport { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type {\n OpenAPIObject,\n OperationObject,\n ReferenceObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\nimport yaml from 'yaml';\n\nimport {\n followRef,\n getFolderExportsV2,\n isEmpty,\n isRef,\n notRef,\n pascalcase,\n snakecase,\n writeFiles,\n} from '@sdk-it/core';\nimport {\n type Operation,\n forEachOperation,\n isStreamingContentType,\n isSuccessStatusCode,\n parseJsonContentType,\n} from '@sdk-it/spec';\n\nimport { DartSerializer, isObjectSchema } from './dart-emitter.ts';\nimport dispatcherTxt from './http/dispatcher.txt';\nimport interceptorsTxt from './http/interceptors.txt';\n\nfunction tuneSpec(\n spec: OpenAPIObject,\n schemas: Record<string, SchemaObject | ReferenceObject>,\n refs: { name: string; value: SchemaObject }[],\n) {\n for (const [name, schema] of Object.entries(schemas)) {\n if (isRef(schema)) continue;\n\n if (schema.allOf && Array.isArray(schema.allOf) && schema.allOf.length) {\n const schemas = schema.allOf;\n const refs = schemas.filter(isRef);\n const nonRefs = schemas.filter(notRef);\n if (nonRefs.some((it) => it.type && it.type !== 'object')) {\n assert(false, `allOf ${name} must be an object`);\n }\n const objectSchema = merge(\n {},\n ...nonRefs,\n ...refs.map((ref) => followRef(spec, ref.$ref)),\n );\n delete objectSchema.allOf;\n delete schema.allOf;\n Object.assign(schema, objectSchema);\n }\n\n if (schema.type === 'object') {\n if (!isEmpty(schema.oneOf)) {\n for (const oneOfIdx in schema.oneOf) {\n const oneOf = schema.oneOf[oneOfIdx];\n if (isRef(oneOf)) continue;\n if (!isEmpty(oneOf.required) && schema.properties) {\n schema.oneOf[oneOfIdx] = schema.properties[oneOf.required[0]];\n }\n }\n\n delete schema.type;\n tuneSpec(spec, schemas, refs);\n continue;\n }\n\n schema.properties ??= {};\n\n for (const [propName, value] of Object.entries(schema.properties)) {\n if (isRef(value)) continue;\n const refName = pascalcase(`${name} ${propName.replace('[]', '')}`);\n refs.push({ name: refName, value });\n schema.properties[propName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n const props = Object.fromEntries(\n Object.entries(value.properties ?? {}).map(([key, value]) => {\n return [pascalcase(`${refName} ${key}`), value];\n }),\n );\n tuneSpec(spec, props, refs);\n // if (value.oneOf && Array.isArray(value.oneOf) && value.oneOf.length) {\n // for (const oneOfIdx in value.oneOf) {\n // const oneOf = value.oneOf[oneOfIdx];\n // if (isRef(oneOf)) continue;\n // if (oneOf.type === 'string') {\n // console.log(refName);\n // // const refName= pascalcase(`${name} ${key} ${oneOfIdx}`);\n // // schema.oneOf[oneOfIdx] = {\n // // $ref: `#/components/schemas/${refName}`,\n // // };\n // }\n // }\n // }\n }\n } else if (schema.type === 'array') {\n if (isRef(schema.items)) continue;\n const refName = name;\n refs.push({ name: refName, value: schema.items ?? {} });\n schema.items = {\n $ref: `#/components/schemas/${refName}`,\n };\n }\n }\n}\nexport async function generate(\n spec: OpenAPIObject,\n settings: {\n output: string;\n name?: string;\n /**\n * full: generate a full project including package.json and tsconfig.json. useful for monorepo/workspaces\n * minimal: generate only the client sdk\n */\n mode?: 'full' | 'minimal';\n formatCode?: (options: { output: string }) => void | Promise<void>;\n },\n) {\n const clientName = settings.name || 'Client';\n const output = join(settings.output, 'lib');\n const groups: Record<\n string,\n {\n use: string;\n methods: string[];\n }\n > = {};\n spec.components ??= {};\n spec.components.schemas ??= {};\n const inputs: Record<string, string> = {};\n const outputs: Record<string, string> = {};\n forEachOperation({ spec }, (entry, operation) => {\n // if (entry.path !== '/beneficiary') {\n // return;\n // }\n operation.responses ??= {};\n for (const status in operation.responses) {\n if (!isSuccessStatusCode(status)) continue;\n const response = isRef(operation.responses[status] as ReferenceObject)\n ? followRef<ResponseObject>(spec, operation.responses[status].$ref)\n : (operation.responses[status] as ResponseObject);\n if (response.content && Object.keys(response.content).length) {\n for (const [contentType, mediaType] of Object.entries(\n response.content,\n )) {\n if (parseJsonContentType(contentType)) {\n if (mediaType.schema && !isRef(mediaType.schema)) {\n spec.components ??= {};\n spec.components.schemas ??= {};\n const outputName = pascalcase(`${operation.operationId} output`);\n spec.components.schemas[outputName] = mediaType.schema;\n operation.responses[status].content[contentType].schema = {\n $ref: `#/components/schemas/${outputName}`,\n };\n }\n }\n }\n }\n }\n console.log(`Processing ${entry.method} ${entry.path}`);\n const group =\n groups[entry.groupName] ??\n (groups[entry.groupName] = {\n methods: [],\n use: `final ${entry.groupName} = new ${pascalcase(entry.groupName)}();`,\n });\n\n const input = toInputs(spec, { entry, operation });\n Object.assign(inputs, input.inputs);\n\n const response = toOutput(spec, operation);\n if (response) {\n Object.assign(outputs, response.outputs);\n }\n group.methods.push(`\n Future<${response ? response.returnType : 'http.StreamedResponse'}> ${camelcase(operation.operationId)}(\n ${isEmpty(operation.requestBody) ? '' : `${input.inputName} input`}\n ) async {\n final stream = await this.dispatcher.${input.contentType}(RequestConfig(\n method: '${entry.method}',\n url: Uri.parse('${entry.path}'),\n headers: {},\n ), ${['json', 'multipart'].includes(input.contentType) ? input.encode : ``});\n ${response ? `${response.decode};` : 'return stream;'}\n }\n `);\n });\n\n const newRefs: { name: string; value: SchemaObject }[] = [];\n tuneSpec(spec, spec.components.schemas, newRefs);\n for (const ref of newRefs) {\n spec.components.schemas[ref.name] = ref.value;\n }\n await writeFile(\n join(process.cwd(), 'openai.json'),\n JSON.stringify(spec, null, 2),\n );\n\n const models = Object.entries(spec.components.schemas).reduce<\n Record<string, string>\n >((acc, [name, schema]) => {\n const serializer = new DartSerializer(spec, (name, content) => {\n acc[`models/${snakecase(name)}.dart`] =\n `import 'dart:io';import 'dart:typed_data'; import './index.dart';\\n\\n${content}`;\n });\n serializer.handle(pascalcase(name), schema);\n return acc;\n }, {});\n\n const clazzez = Object.entries(groups).reduce<Record<string, string>>(\n (acc, [name, { methods }]) => {\n return {\n ...acc,\n [`api/${snakecase(name)}.dart`]: `\nimport 'dart:convert';\n\nimport 'package:http/http.dart' as http;\n\nimport '../interceptors.dart';\nimport '../inputs/index.dart';\nimport '../outputs/index.dart';\nimport '../models/index.dart';\nimport '../http.dart';\n\n class ${pascalcase(name)}Client {\n final Dispatcher dispatcher;\n ${pascalcase(name)}Client(this.dispatcher);\n ${methods.join('\\n')}\n }\n `,\n };\n },\n {},\n );\n\n const client = `\n ${Object.keys(groups)\n .map((name) => `import './api/${snakecase(name)}.dart';`)\n .join('\\n')}\nimport './interceptors.dart';\nimport './http.dart';\n\n class ${clientName} {\n final Options options;\n${Object.keys(groups)\n .map((name) => `late final ${pascalcase(name)}Client ${camelcase(name)};`)\n .join('\\n')}\n\n ${clientName}(this.options) {\n final interceptors = [new BaseUrlInterceptor(() => this.options.baseUrl)];\n final dispatcher = new Dispatcher(interceptors);\n ${Object.keys(groups)\n .map(\n (name) =>\n `this.${camelcase(name)} = new ${pascalcase(name)}Client(dispatcher);`,\n )\n .join('\\n')}\n\n }\n\n void setOptions({String? baseUrl}) {\n if (baseUrl != null) {\n options.baseUrl = baseUrl;\n }\n }\n }\n\n\nclass Options {\n String baseUrl;\n Options({required this.baseUrl});\n}\n\n `;\n await writeFiles(output, {\n ...models,\n ...inputs,\n ...outputs,\n });\n\n await writeFiles(output, {\n 'models/index.dart': await getFolderExportsV2(join(output, 'models'), {\n exportSyntax: 'export',\n extensions: 'dart',\n }),\n 'inputs/index.dart': await getFolderExportsV2(join(output, 'inputs'), {\n exportSyntax: 'export',\n extensions: 'dart',\n }),\n 'outputs/index.dart': await getFolderExportsV2(join(output, 'outputs'), {\n exportSyntax: 'export',\n extensions: 'dart',\n }),\n 'interceptors.dart': interceptorsTxt,\n 'http.dart': dispatcherTxt,\n ...clazzez,\n });\n await writeFiles(output, {\n 'package.dart': `${await getFolderExportsV2(join(output), {\n exportSyntax: 'export',\n extensions: 'dart',\n ignore(dirent) {\n return dirent.isFile() && dirent.name === 'package.dart';\n },\n })}${client}`,\n });\n\n await writeFiles(settings.output, {\n 'pubspec.yaml': {\n ignoreIfExists: true,\n content: yaml.stringify({\n name: settings.name\n ? `${snakecase(clientName.toLowerCase())}_sdk`\n : 'sdk',\n version: '0.0.1',\n environment: {\n sdk: '^3.7.2',\n },\n dependencies: {\n http: '^1.3.0',\n mime: '^2.0.0',\n },\n }),\n },\n });\n\n await settings.formatCode?.({\n output: output,\n });\n}\n\nfunction toInputs(spec: OpenAPIObject, { entry, operation }: Operation) {\n const inputs: Record<string, unknown> = {};\n const inputName = pascalcase(`${operation.operationId} input`);\n let contentType = 'empty';\n let encode = '';\n if (!isEmpty(operation.requestBody)) {\n const requestBody = isRef(operation.requestBody)\n ? followRef<RequestBodyObject>(spec, operation.requestBody.$ref)\n : operation.requestBody;\n\n for (const type in requestBody.content) {\n const ctSchema = isRef(requestBody.content[type].schema)\n ? followRef(spec, requestBody.content[type].schema.$ref)\n : requestBody.content[type].schema;\n if (!ctSchema) {\n console.warn(\n `Schema not found for ${type} in ${entry.method} ${entry.path}`,\n );\n continue;\n }\n\n const serializer = new DartSerializer(spec, (name, content) => {\n inputs[join(`inputs/${name}.dart`)] =\n `import 'dart:io';import 'dart:typed_data';import '../models/index.dart'; import './index.dart';\\n\\n${content}`;\n });\n const serialized = serializer.handle(inputName, ctSchema, true, {\n alias: isObjectSchema(ctSchema) ? undefined : inputName,\n });\n encode = serialized.encode as string;\n if (contentType) {\n console.warn(\n `${entry.method} ${entry.path} have more than one content type`,\n );\n }\n\n const [mediaType, mediaSubType] = partContentType(type).type.split('/');\n if (mediaType === 'application') {\n contentType = parseJsonContentType(type) as string;\n } else {\n contentType = mediaType;\n }\n\n // const schema = merge({}, objectSchema, {\n // required: additionalProperties\n // .filter((p) => p.required)\n // .map((p) => p.name),\n // properties: additionalProperties.reduce<Record<string, unknown>>(\n // (acc, p) => ({\n // ...acc,\n // [p.name]: p.schema,\n // }),\n // {},\n // ),\n // });\n\n // Object.assign(inputs, bodyInputs(config, objectSchema));\n // schemas[shortContenTypeMap[type]] = zodDeserialzer.handle(schema, true);\n }\n }\n\n return { inputs, inputName, contentType, encode };\n}\n\nfunction toOutput(spec: OpenAPIObject, operation: OperationObject) {\n const outputName = pascalcase(`${operation.operationId} output`);\n operation.responses ??= {};\n const outputs: Record<string, string> = {};\n for (const status in operation.responses) {\n const response = isRef(operation.responses[status] as ReferenceObject)\n ? followRef<ResponseObject>(spec, operation.responses[status].$ref)\n : (operation.responses[status] as ResponseObject);\n for (const type in response.content) {\n const { schema } = response.content[type];\n if (!schema) {\n console.warn(\n `Schema not found for ${type} in ${operation.operationId}`,\n );\n continue;\n }\n const serializer = new DartSerializer(spec, (name, content) => {\n // outputs[join(`outputs/${name}.dart`)] =\n // `import 'dart:typed_data'; import '../models/index.dart'; \\n\\n${content}`;\n });\n if (isStreamingContentType(type)) {\n return {\n type: 'stream',\n outputName,\n outputs,\n decode: `return stream`,\n returnType: `http.StreamedResponse`,\n };\n }\n if (parseJsonContentType(type)) {\n const serialized = serializer.handle(outputName, schema, true, {\n // alias: outputName,\n noEmit: true,\n });\n return {\n type: 'json',\n outputName,\n outputs,\n decode: `final response = await http.Response.fromStream(stream);final dynamic json = jsonDecode(response.body); return ${serialized.fromJson}`,\n returnType: serialized.use,\n };\n }\n }\n }\n return null;\n}\n", "import { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { parse } from 'yaml';\n\nexport async function loadLocal(location: string) {\n const extName = extname(location);\n const text = await readFile(location, 'utf-8');\n switch (extName) {\n case '.json':\n return JSON.parse(text);\n case '.yaml':\n case '.yml':\n return parse(text);\n default:\n throw new Error(`Unsupported file extension: ${extName}`);\n }\n}\n", "import { extname } from 'node:path';\nimport type { OpenAPIObject } from 'openapi3-ts/oas31';\nimport { parse } from 'yaml';\n\nexport async function loadRemote(location: string): Promise<OpenAPIObject> {\n const extName = extname(location);\n const response = await fetch(location);\n switch (extName) {\n case '.json':\n return response.json() as Promise<OpenAPIObject>;\n case '.yaml':\n case '.yml': {\n const text = await response.text();\n return parse(text);\n }\n default:\n try {\n // try to parse it as json first\n return response.json() as Promise<OpenAPIObject>;\n } catch {\n // parse as yaml\n const text = await response.text();\n return parse(text) as Promise<OpenAPIObject>;\n }\n }\n}\n", "import type {\n OpenAPIObject,\n OperationObject,\n ParameterObject,\n ReferenceObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId' | 'tag'>> = {\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return camelcase(operation.operationId);\n }\n const metadata = operation['x-oaiMeta'];\n if (metadata && metadata.name) {\n return camelcase(metadata.name);\n }\n return camelcase(\n [method, ...path.replace(/[\\\\/\\\\{\\\\}]/g, ' ').split(' ')]\n .filter(Boolean)\n .join(' ')\n .trim(),\n );\n },\n tag: (operation, path) => {\n return operation.tags?.[0] || determineGenericTag(path, operation);\n },\n};\n\nexport type TunedOperationObject = OperationObject & {\n operationId: string;\n parameters: (ParameterObject | ReferenceObject)[];\n};\n\nexport interface OperationEntry {\n name?: string;\n method: string;\n path: string;\n groupName: string;\n tag: string;\n}\nexport type Operation = {\n entry: OperationEntry;\n operation: TunedOperationObject;\n};\n\nexport function forEachOperation<T>(\n config: GenerateSdkConfig,\n callback: (entry: OperationEntry, operation: TunedOperationObject) => T,\n) {\n const result: T[] = [];\n for (const [path, pathItem] of Object.entries(config.spec.paths ?? {})) {\n const { parameters = [], ...methods } = pathItem;\n\n // Convert Express-style routes (:param) to OpenAPI-style routes ({param})\n const fixedPath = path.replace(/:([^/]+)/g, '{$1}');\n\n for (const [method, operation] of Object.entries(methods) as [\n string,\n OperationObject,\n ][]) {\n const formatOperationId = config.operationId ?? defaults.operationId;\n const formatTag = config.tag ?? defaults.tag;\n const operationName = formatOperationId(operation, fixedPath, method);\n const operationTag = formatTag(operation, fixedPath);\n const metadata = operation['x-oaiMeta'] ?? {};\n result.push(\n callback(\n {\n name: metadata.name,\n method,\n path: fixedPath,\n groupName: operationTag,\n tag: operationTag,\n },\n {\n ...operation,\n parameters: [...parameters, ...(operation.parameters ?? [])],\n operationId: operationName,\n },\n ),\n );\n }\n }\n return result;\n}\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIObject;\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n tag?: (operation: OperationObject, path: string) => string;\n}\n\n// --- Function Definition (determineGenericTag, sanitizeTag, reservedKeywords, commonVerbs) ---\n/**\n * Set of reserved TypeScript keywords and common verbs potentially used as tags.\n */\nconst reservedKeywords = new Set([\n 'abstract',\n 'arguments',\n 'await',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n // Potentially problematic identifiers / Common Verbs used as tags\n 'object',\n 'string',\n 'number',\n 'any',\n 'unknown',\n 'never',\n 'get',\n 'list',\n 'create',\n 'update',\n 'delete',\n 'post',\n 'put',\n 'patch',\n 'do',\n 'send',\n 'add',\n 'remove',\n 'set',\n 'find',\n 'search',\n 'check',\n 'make', // Added make, check\n]);\n\n/**\n * Sanitizes a potential tag name (assumed to be already camelCased)\n * to avoid conflicts with reserved keywords or invalid starting characters (numbers).\n * Appends an underscore if the tag matches a reserved keyword.\n * Prepends an underscore if the tag starts with a number.\n * @param camelCasedTag The potential tag name, already camelCased.\n * @returns The sanitized tag name.\n */\nfunction sanitizeTag(camelCasedTag: string): string {\n // Prepend underscore if starts with a number\n if (/^\\d/.test(camelCasedTag)) {\n return `_${camelCasedTag}`;\n }\n // Append underscore if it's a reserved keyword\n return reservedKeywords.has(camelCasedTag)\n ? `${camelCasedTag}_`\n : camelCasedTag;\n}\n\n/**\n * Attempts to determine a generic tag for an OpenAPI operation based on path and operationId.\n * Rules and fallbacks are documented within the code.\n * @param pathString The path string.\n * @param operation The OpenAPI Operation Object.\n * @returns A sanitized, camelCased tag name string.\n */\nexport function determineGenericTag(\n pathString: string,\n operation: OperationObject,\n): string {\n const operationId = operation.operationId || '';\n const VERSION_REGEX = /^[vV]\\d+$/;\n const commonVerbs = new Set([\n // Verbs to potentially strip from operationId prefix\n 'get',\n 'list',\n 'create',\n 'update',\n 'delete',\n 'post',\n 'put',\n 'patch',\n 'do',\n 'send',\n 'add',\n 'remove',\n 'set',\n 'find',\n 'search',\n 'check',\n 'make', // Added make\n ]);\n\n const segments = pathString.split('/').filter(Boolean);\n\n const potentialCandidates = segments.filter(\n (segment) =>\n segment &&\n !segment.startsWith('{') &&\n !segment.endsWith('}') &&\n !VERSION_REGEX.test(segment),\n );\n\n // --- Heuristic 1: Last non-'@' path segment ---\n for (let i = potentialCandidates.length - 1; i >= 0; i--) {\n const segment = potentialCandidates[i];\n if (!segment.startsWith('@')) {\n // Sanitize just before returning\n return sanitizeTag(camelcase(segment));\n }\n }\n\n const canFallbackToPathSegment = potentialCandidates.length > 0;\n\n // --- Heuristic 2: OperationId parsing ---\n if (operationId) {\n const lowerOpId = operationId.toLowerCase();\n const parts = operationId\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')\n .replace(/([a-zA-Z])(\\d)/g, '$1_$2')\n .replace(/(\\d)([a-zA-Z])/g, '$1_$2')\n .toLowerCase()\n .split(/[_-\\s]+/);\n\n const validParts = parts.filter(Boolean);\n\n // Quick skip: If opId is just a verb and we can use Heuristic 3, prefer that.\n if (\n commonVerbs.has(lowerOpId) &&\n validParts.length === 1 &&\n canFallbackToPathSegment\n ) {\n // Proceed directly to Heuristic 3\n }\n // Only process if there are valid parts and the quick skip didn't happen\n else if (validParts.length > 0) {\n const firstPart = validParts[0];\n const isFirstPartVerb = commonVerbs.has(firstPart);\n\n // Case 2a: Starts with verb, has following parts\n if (isFirstPartVerb && validParts.length > 1) {\n const verbPrefixLength = firstPart.length;\n let nextPartStartIndex = -1;\n if (operationId.length > verbPrefixLength) {\n // Simplified check for next part start\n const charAfterPrefix = operationId[verbPrefixLength];\n if (charAfterPrefix >= 'A' && charAfterPrefix <= 'Z') {\n nextPartStartIndex = verbPrefixLength;\n } else if (charAfterPrefix >= '0' && charAfterPrefix <= '9') {\n nextPartStartIndex = verbPrefixLength;\n } else if (['_', '-'].includes(charAfterPrefix)) {\n nextPartStartIndex = verbPrefixLength + 1;\n } else {\n const match = operationId\n .substring(verbPrefixLength)\n .match(/[A-Z0-9]/);\n if (match && match.index !== undefined) {\n nextPartStartIndex = verbPrefixLength + match.index;\n }\n if (\n nextPartStartIndex === -1 &&\n operationId.length > verbPrefixLength\n ) {\n nextPartStartIndex = verbPrefixLength; // Default guess\n }\n }\n }\n\n if (\n nextPartStartIndex !== -1 &&\n nextPartStartIndex < operationId.length\n ) {\n const remainingOriginalSubstring =\n operationId.substring(nextPartStartIndex);\n const potentialTag = camelcase(remainingOriginalSubstring);\n if (potentialTag) {\n // Sanitize just before returning\n return sanitizeTag(potentialTag);\n }\n }\n\n // Fallback: join remaining lowercased parts\n const potentialTagJoined = camelcase(validParts.slice(1).join('_'));\n if (potentialTagJoined) {\n // Sanitize just before returning\n return sanitizeTag(potentialTagJoined);\n }\n }\n\n // Case 2b: Doesn't start with verb, or only one part (might be verb)\n const potentialTagFull = camelcase(operationId);\n if (potentialTagFull) {\n const isResultSingleVerb = validParts.length === 1 && isFirstPartVerb;\n\n // Avoid returning only a verb if Heuristic 3 is possible\n if (!(isResultSingleVerb && canFallbackToPathSegment)) {\n if (potentialTagFull.length > 0) {\n // Sanitize just before returning\n return sanitizeTag(potentialTagFull);\n }\n }\n }\n\n // Case 2c: Further fallbacks within OpId if above failed/skipped\n const firstPartCamel = camelcase(firstPart);\n if (firstPartCamel) {\n const isFirstPartCamelVerb = commonVerbs.has(firstPartCamel);\n if (\n !isFirstPartCamelVerb ||\n validParts.length === 1 ||\n !canFallbackToPathSegment\n ) {\n // Sanitize just before returning\n return sanitizeTag(firstPartCamel);\n }\n }\n if (\n isFirstPartVerb &&\n validParts.length > 1 &&\n validParts[1] &&\n canFallbackToPathSegment\n ) {\n const secondPartCamel = camelcase(validParts[1]);\n if (secondPartCamel) {\n // Sanitize just before returning\n return sanitizeTag(secondPartCamel);\n }\n }\n } // End if(validParts.length > 0) after quick skip check\n } // End if(operationId)\n\n // --- Heuristic 3: First path segment (stripping '@') ---\n if (potentialCandidates.length > 0) {\n let firstCandidate = potentialCandidates[0];\n if (firstCandidate.startsWith('@')) {\n firstCandidate = firstCandidate.substring(1);\n }\n if (firstCandidate) {\n // Sanitize just before returning\n return sanitizeTag(camelcase(firstCandidate));\n }\n }\n\n // --- Heuristic 4: Default ---\n console.warn(\n `Could not determine a suitable tag for path: ${pathString}, operationId: ${operationId}. Using 'unknown'.`,\n );\n return 'unknown'; // 'unknown' is safe\n}\n\nexport function parseJsonContentType(contentType: string | null | undefined) {\n if (!contentType) {\n return null;\n }\n\n // 1. Trim whitespace\n let mainType = contentType.trim();\n\n // 2. Remove parameters (anything after the first ';')\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n mainType = mainType.substring(0, semicolonIndex).trim(); // Trim potential space before ';'\n }\n\n // 3. Convert to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n if (mainType.endsWith('/json')) {\n return mainType.split('/')[1];\n } else if (mainType.endsWith('+json')) {\n return mainType.split('+')[1];\n }\n return null;\n}\n\n/**\n * Checks if a given content type string represents Server-Sent Events (SSE).\n * Handles case-insensitivity, parameters (like charset), and leading/trailing whitespace.\n *\n * @param contentType The content type string to check (e.g., from a Content-Type header).\n * @returns True if the content type is 'text/event-stream', false otherwise.\n */\nexport function isSseContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false; // Handle null, undefined, or empty string\n }\n\n // 1. Trim whitespace from the input string\n let mainType = contentType.trim();\n\n // 2. Find the position of the first semicolon (if any) to remove parameters\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n // Extract the part before the semicolon and trim potential space\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n\n // 3. Convert the main type part to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n // 4. Compare against the standard SSE MIME type\n return mainType === 'text/event-stream';\n}\n\nexport function isStreamingContentType(\n contentType: string | null | undefined,\n): boolean {\n return contentType === 'application/octet-stream';\n}\n\nexport function isSuccessStatusCode(statusCode: number | string): boolean {\n statusCode = Number(statusCode);\n return statusCode >= 200 && statusCode < 300;\n}\n", "import { merge } from 'lodash-es';\nimport assert from 'node:assert';\nimport type {\n OpenAPIObject,\n ReferenceObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase, snakecase } from 'stringcase';\n\nimport {\n cleanRef,\n followRef,\n isEmpty,\n isRef,\n notRef,\n parseRef,\n pascalcase,\n} from '@sdk-it/core';\n\nconst formatName = (it: any): string => {\n const startsWithDigitPattern = /^-?\\d/;\n // 1. Handle numbers\n if (typeof it === 'number') {\n if (Math.sign(it) === -1) {\n return `$_${Math.abs(it)}`;\n }\n return `$${it}`;\n }\n\n // 2. Handle the specific string 'default'\n if (it === 'default') {\n return '$default';\n }\n\n // 3. Handle other strings\n if (typeof it === 'string') {\n // 3a. Check if the string starts with a digit FIRST\n if (startsWithDigitPattern.test(it)) {\n if (typeof it === 'number') {\n if (Math.sign(it) === -1) {\n return `$_${Math.abs(it)}`;\n }\n return `$${it}`;\n }\n }\n\n // 3b. If not starting with a digit, handle brackets and snake_case\n let nameToFormat = it;\n\n // Remove a single leading '[' if present\n if (nameToFormat.startsWith('[')) {\n nameToFormat = nameToFormat.slice(1);\n }\n\n // Remove a single trailing ']' if present\n if (nameToFormat.endsWith(']')) {\n nameToFormat = nameToFormat.slice(0, -1);\n }\n\n // Apply snakecase to the (potentially modified) string\n return snakecase(nameToFormat);\n }\n\n // 4. Fallback for any other types (e.g., null, undefined, objects)\n // Convert to string first, then apply snakecase\n return snakecase(String(it));\n};\n\ntype Context = Record<string, any>;\ntype Serialized = {\n nullable?: boolean;\n encode?: string;\n use: string;\n toJson: string;\n matches?: string;\n fromJson: string;\n type?: string;\n content: string;\n simple?: boolean;\n};\ntype Emit = (name: string, content: string) => void;\n/**\n * Convert an OpenAPI (JSON Schema style) object into Dart classes\n */\nexport class DartSerializer {\n #spec: OpenAPIObject;\n #emit: Emit;\n\n constructor(spec: OpenAPIObject, emit: Emit) {\n this.#spec = spec;\n this.#emit = emit;\n }\n\n #getRefUsage(schemaName: string, list: string[] = []): string[] {\n this.#spec.components ??= {};\n this.#spec.components.schemas ??= {};\n this.#spec.components.responses ??= {};\n\n const checkSchema = (schema: SchemaObject | ReferenceObject): boolean => {\n if (isRef(schema)) {\n const { model } = parseRef(schema.$ref);\n return model === schemaName;\n }\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return (schema.oneOf as Array<SchemaObject | ReferenceObject>).some(\n (subSchema) => checkSchema(subSchema),\n );\n }\n if (\n schema.type === 'array' &&\n schema.items &&\n notRef(schema.items) &&\n schema.items.oneOf\n ) {\n return checkSchema(schema.items);\n }\n return false;\n };\n\n for (const [key, value] of Object.entries(this.#spec.components.schemas)) {\n if (checkSchema(value)) {\n list.push(key);\n }\n }\n\n return list;\n }\n\n #object(\n className: string,\n schema: SchemaObject,\n context: Context,\n ): Serialized {\n if (schema.additionalProperties) {\n this.#emit(className, `typedef ${className} = Map<String, dynamic>;`);\n return {\n content: '',\n use: 'Map<String, dynamic>',\n encode: 'input',\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${camelcase(context.name)}']`,\n matches: `json['${camelcase(context.name)}'] is Map<String, dynamic>`,\n };\n }\n if (isEmpty(schema.properties)) {\n if (context.noEmit !== true) {\n this.#emit(\n className,\n `class ${className} {\n const ${className}(); // Add const constructor\n\n factory ${className}.fromJson(Map<String, dynamic> json) {\n return const ${className}();\n }\n\n Map<String, dynamic> toJson() => {};\n\n /// Determines if a given map can be parsed into an instance of this class.\n /// Returns true for any map since this class has no properties.\n static bool matches(Map<String, dynamic> json) {\n return true; // Any map is fine for an empty object\n }\n}`,\n );\n }\n return {\n content: '',\n encode: 'input.toJson()',\n use: className,\n toJson: `${this.#safe(context.name as string, context.required)}`,\n fromJson: `${className}.fromJson(json['${context.name}'])`,\n matches: `${className}.matches(json['${context.name}'])`,\n };\n }\n\n const props: string[] = [];\n const toJsonProperties: string[] = [];\n const constructorParams: string[] = [];\n const fromJsonParams: string[] = [];\n const matches: string[] = [];\n\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const propName = key.replace('[]', '');\n const required = (schema.required ?? []).includes(key);\n const typeStr = this.handle(className, propSchema, required, {\n name: propName,\n required,\n propName: [className, propName].filter(Boolean).join('_'),\n });\n const nullable = typeStr.nullable || !required;\n const nullableSuffix = nullable ? '?' : '';\n props.push(\n `final ${typeStr.use}${nullableSuffix} ${camelcase(propName)};`,\n );\n fromJsonParams.push(`${camelcase(propName)}: ${typeStr.fromJson}`);\n toJsonProperties.push(`'${propName}': ${typeStr.toJson}`);\n constructorParams.push(\n `${required ? 'required ' : ''}this.${camelcase(propName)},`,\n );\n if (required) {\n matches.push(`(\n json.containsKey('${camelcase(propName)}')\n ? ${nullable ? `json['${propName}'] == null` : `json['${propName}'] != null`} && ${typeStr.matches}\n : false)`);\n } else {\n matches.push(`(\n json.containsKey('${camelcase(propName)}')\n ? ${nullable ? `json['${propName}'] == null` : `json['${propName}'] != null`} || ${typeStr.matches}\n : true)`);\n }\n }\n\n const { mixins, withMixins } = this.#mixinise(className, context);\n const content = `class ${className} ${withMixins} {\n ${props.join('\\n')}\n ${!mixins.length ? 'const' : ''} ${className}({\n ${constructorParams.join('\\n')}})${mixins.length > 1 ? '' : `:super()`};\n factory ${className}.fromJson(Map<String, dynamic> json) {\nreturn ${className}(\\n${fromJsonParams.join(',\\n')});\n }\n Map<String, dynamic> toJson() => {\n${toJsonProperties.join(',\\n')}\n };\n static bool matches(Map<String, dynamic> json) {\nreturn ${matches.join(' && ')};\n }\n }`;\n if (context.noEmit !== true) {\n this.#emit(className, content);\n }\n const nullable = !context.required || context.nullable === true;\n return {\n use: className,\n content,\n encode: 'input.toJson()',\n toJson: `${this.#safe(context.name, context.required)}`,\n fromJson: context.name\n ? `${context.forJson || className}.fromJson(json['${context.name}'])`\n : `${context.forJson || className}.fromJson(json)`,\n matches: `${className}.matches(json['${context.name}'])`,\n };\n }\n\n #safe(accces: string, required: boolean) {\n return required\n ? `this.${camelcase(accces)}.toJson()`\n : `this.${camelcase(accces)} != null ? this.${camelcase(accces)}!.toJson() : null`;\n }\n\n #array(\n className: string,\n schema: SchemaObject,\n required = false,\n context: Context,\n ): Serialized {\n let serialized: Serialized;\n if (!schema.items) {\n serialized = {\n content: '',\n use: 'List<dynamic>',\n toJson: '',\n fromJson: `List<dynamic>.from(${context.name ? `json['${context.name}']` : `json`})})`,\n matches: '',\n };\n } else {\n const itemsType = this.handle(className, schema.items, true, context);\n const fromJson = required\n ? context.name\n ? `(json['${context.name}'] as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()`\n : `(json as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()`\n : context.name\n ? `json['${context.name}'] != null\n ? (json['${context.name}'] as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()\n : null`\n : `json != null\n ? (json as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()\n : null`;\n\n serialized = {\n encode: `input.map((it) => ${itemsType.simple ? 'it' : `it.toJson()`}).toList()`,\n content: '',\n use: `List<${itemsType.use}>`,\n fromJson,\n toJson: `${context.required ? `this.${camelcase(context.name)}${itemsType.simple ? '' : '.map((it) => it.toJson()).toList()'}` : `this.${camelcase(context.name)}!= null? this.${camelcase(context.name)}${itemsType.simple ? '' : '!.map((it) => it.toJson()).toList()'} : null`}`,\n matches: `json['${camelcase(context.name)}'].every((it) => ${itemsType.matches})`,\n };\n }\n\n return serialized;\n }\n\n /**\n * Convert a basic type to Dart\n */\n #primitive(\n className: string,\n type: string,\n schema: SchemaObject,\n context: Record<string, unknown>,\n required = false,\n ): Serialized {\n switch (type) {\n case 'string':\n return this.#string(schema, context);\n case 'number':\n case 'integer':\n return this.number(schema, context);\n case 'boolean':\n return {\n content: '',\n use: 'bool',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is bool`,\n };\n case 'object':\n return this.#object(className, schema, context);\n case 'array':\n return this.#array(className, schema, required, context);\n case 'null':\n return {\n content: '',\n use: 'Null',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n default:\n // Unknown type -> fallback\n return {\n content: '',\n use: 'dynamic',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n }\n }\n\n #ref(\n className: string,\n $ref: string,\n required: boolean,\n context: Context,\n ): Serialized {\n const schemaName = cleanRef($ref).split('/').pop()!;\n\n const serialized = this.handle(\n schemaName,\n followRef<SchemaObject>(this.#spec, $ref),\n required,\n {\n ...context,\n propName: schemaName,\n noEmit: !!context.alias || !!className || !context.forceEmit,\n },\n );\n return serialized;\n }\n\n // fixme: this method should no longer be needed because the logic in it is being preprocessed before emitting begins\n #allOf(\n className: string,\n schemas: (SchemaObject | ReferenceObject)[],\n context: Context,\n ): Serialized {\n const name = pascalcase(context.propName || className); // className in case is top level\n\n const refs = schemas.filter(isRef);\n const nonRefs = schemas.filter(notRef);\n if (nonRefs.some((it) => it.type && it.type !== 'object')) {\n assert(false, `allOf ${name} must be an object`);\n }\n const objectSchema = merge(\n {},\n ...nonRefs,\n ...refs.map((ref) => followRef(this.#spec, ref.$ref)),\n );\n delete objectSchema.allOf;\n return this.handle(name, objectSchema, true, context);\n }\n\n #anyOf(\n className: string,\n schemas: (SchemaObject | ReferenceObject)[],\n context: Record<string, unknown>,\n ): Serialized {\n // fixme: handle\n if (schemas.length === 0) {\n return {\n content: '',\n use: 'dynamic',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n }\n const nullSchemaIndex = schemas.findIndex((schema) => {\n if (isRef(schema)) {\n const refSchema = followRef(this.#spec, schema.$ref);\n return refSchema.type === 'null';\n }\n return schema.type === 'null';\n });\n const anyOfSchemas = schemas.slice(0);\n if (nullSchemaIndex >= 0) {\n anyOfSchemas.splice(nullSchemaIndex, 1); // remove null schema\n }\n\n return this.handle(className, anyOfSchemas[0], true, {\n ...context,\n nullable: nullSchemaIndex >= 0,\n });\n }\n\n #mixinise(name: string, context: Context) {\n const mixins = this.#getRefUsage(name);\n if (context.mixin) {\n mixins.unshift(context.mixin);\n }\n const withMixins =\n mixins.length > 1\n ? ` with ${mixins.join(', ')}`\n : mixins.length === 1\n ? `extends ${mixins[0]}`\n : '';\n return {\n withMixins,\n mixins,\n };\n }\n\n #oneOf(\n className: string,\n schemas: (SchemaObject | ReferenceObject)[],\n context: Context,\n ): Serialized {\n const name = pascalcase(context.propName || className); // className in case is top level\n\n if (schemas.length === 0) {\n return {\n content: '',\n use: 'dynamic',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n }\n const content: string[] = [];\n const patterns: { pattern: string; name: string }[] = [];\n // FIXME: if there is just one type then no need to add the discriminator\n const objects = schemas.filter(notRef).filter((it) => it.type === 'object');\n for (const schema of schemas) {\n if (isRef(schema)) {\n const refType = this.#ref(className, schema.$ref, true, context);\n patterns.push({\n pattern: `case ${refType.type || 'Map<String, dynamic>'} map when ${refType.use}.matches(map): return ${refType.use}.fromJson(map);`,\n name: refType.use,\n });\n } else if (schema.type === 'string') {\n // todo: make this into a schema with ref (preproccesing)\n content.push(`class ${name}Text with ${name} {\n final String value;\n ${name}Text(this.value);\n @override\n dynamic toJson() => value;\n static bool matches(dynamic value) {\n return value is String;\n }}\n `);\n patterns.push({\n pattern: `case String(): return ${name}Text(json);`,\n name: `${name}Text`,\n });\n } else if (schema.type === 'array') {\n // todo: make this into a schema with ref (preproccesing) with all varients types (integer, string)\n // todo: this can be abstracted so the varients somehow dynamic without having to replicate the same classes all the time\n const itemsType = this.handle(name, schema.items!, true, {\n ...context,\n noEmit: true,\n });\n content.push(`class ${name}List with ${name} {\n final List<${itemsType.use}> value;\n ${name}List(this.value);\n @override\n dynamic toJson() => value;\n static bool matches(dynamic value) {\n return value is List;\n }}`);\n patterns.push({\n pattern: `case List(): return ${name}List(List<${itemsType.use}>.from(json));`,\n name: `${name}List`,\n });\n }\n }\n if (objects.length) {\n // todo: take a look at CompoundFilterFilters at the end\n const candidates: Record<string, Set<string>> = {};\n for (const schema of objects) {\n if (schema.additionalProperties === true) {\n continue;\n }\n assert(\n schema.properties,\n `Schema ${name} has no properties which are required in oneOf in order to determine the discriminator.`,\n );\n for (const [propName, propSchema] of Object.entries(\n schema.properties,\n )) {\n if (\n notRef(propSchema) &&\n propSchema.enum &&\n // fixme: the enum can have more than one value as long as it is not duplicated else where on the other schemas\n propSchema.enum.length === 1\n ) {\n candidates[propName] ??= new Set();\n candidates[propName].add(String(propSchema.enum[0]));\n }\n }\n }\n\n let discriminatorProp: string | undefined;\n\n for (const [name, values] of Object.entries(candidates)) {\n if (\n // make sure we pick the prop that exists on all objects\n values.size === objects.filter((it) => it.properties?.[name]).length\n ) {\n discriminatorProp = name;\n break;\n }\n }\n\n // if (objects.filter((it) => it.additionalProperties !== true).length) {\n // }\n // assert(discriminatorProp, `No discriminator property found in ${name}`);\n\n if (discriminatorProp) {\n for (const schema of objects) {\n const discriminatorValue: string = (\n (schema as SchemaObject).properties![\n discriminatorProp!\n ] as SchemaObject\n ).enum?.[0];\n\n const varientName = `${name}${pascalcase(discriminatorValue)}`;\n patterns.push({\n pattern: `case Map<String, dynamic> map when ${varientName}.matches(json): return ${varientName}.fromJson(map);`,\n name: varientName,\n });\n\n const objResult = this.#object(varientName, schema, {\n ...context,\n noEmit: true,\n mixin: name,\n });\n content.push(objResult.content);\n }\n }\n }\n\n const { mixins, withMixins } = this.#mixinise(name, context);\n content.unshift(`abstract ${mixins.length ? '' : 'mixin'} class ${name} ${withMixins} {\n dynamic toJson();\n ${\n patterns.length\n ? `static ${name} fromJson(dynamic json) {\n switch (json){\n ${patterns.map((it) => it.pattern).join('\\n')}\n default:\n throw ArgumentError(\"Invalid type for query property: \\${json}\");\n }\n }\n\n\n ${\n patterns.length\n ? ` static bool matches(dynamic value) {\n return ${patterns.map((it) => `value is ${it.name}`).join(' || ')};\n }`\n : ''\n }\n\n `\n : ''\n }\n }`);\n this.#emit(name, content.join('\\n'));\n\n return {\n content: content.join('\\n'),\n use: name,\n toJson: `${this.#safe(context.name as string, context.required)}`,\n fromJson: `${name}.fromJson(json['${context.name}'])`,\n matches: `${name}.matches(json['${context.name}'])`,\n };\n }\n\n #simple(type: string) {\n switch (type) {\n case 'string':\n return 'String';\n case 'number':\n return 'double';\n case 'integer':\n return 'int';\n case 'boolean':\n return 'bool';\n default:\n return 'dynamic';\n }\n }\n\n #enum(className: string, schema: SchemaObject, context: Context): Serialized {\n const name = context.propName || className; // className in case enum is top level\n const values = schema.enum as string[];\n const valType = this.#simple((schema.type as string) || 'string');\n // fixme: if enum have one value and cannot be null then use it as default value\n\n const { mixins, withMixins } = this.#mixinise(className, context);\n\n const content = `\n class _EnumValue implements ${pascalcase(name)} {\n final ${valType} value;\n const _EnumValue(this.value);\n @override\n toJson() {return this.value;}\n}\n abstract ${mixins.length ? '' : 'mixin'} class ${pascalcase(name)} ${withMixins} {\n ${values.map((it) => `static const _EnumValue ${formatName(it)} = _EnumValue(${typeof it === 'number' ? it : `'${it}'`});`).join('\\n')}\n dynamic toJson();\n\n ${valType} get value;\n\n static _EnumValue fromJson(${valType} value) {\n switch (value) {\n${values\n .map(\n (it) =>\n `case ${typeof it === 'number' ? it : `'${it}'`}: return ${formatName(it)};`,\n )\n .join('\\n')}\ndefault:\n throw ArgumentError.value(value, \"value\", \"No enum value with that name\");\n }\n }\n\n static bool matches(${valType} value) {\n try {\nfromJson(value);\nreturn true;\n } catch (error) {\nreturn false;\n }\n }\n\n }`;\n if (context.noEmit !== true) {\n this.#emit(name, content);\n }\n return {\n type: Array.isArray(schema.type)\n ? this.#simple(schema.type[0])\n : schema.type\n ? this.#simple(schema.type)\n : undefined,\n content: content,\n use: pascalcase(name),\n toJson: `${context.required ? `this.${camelcase(context.name)}.toJson()` : `this.${camelcase(context.name)} != null ? this.${camelcase(context.name)}!.toJson() : null`}`,\n fromJson: `${pascalcase(name)}.fromJson(json['${context.name}'])`,\n matches: `${pascalcase(name)}.matches(json['${context.name}'])`,\n };\n }\n\n /**\n * Handle string type with formats\n */\n #string(schema: SchemaObject, context: Context): Serialized {\n switch (schema.format) {\n case 'date-time':\n case 'datetime':\n case 'date':\n return {\n content: '',\n use: 'DateTime',\n simple: true,\n toJson: context.required\n ? `this.${camelcase(context.name)}.toIso8601String()`\n : `this.${camelcase(context.name)} != null ? this.${camelcase(\n context.name,\n )}!.toIso8601String() : null`,\n fromJson: context.name\n ? `json['${context.name}'] != null ? DateTime.parse(json['${context.name}']) : null`\n : 'json',\n matches: `json['${context.name}'] is String`,\n };\n case 'binary':\n case 'byte':\n return {\n content: '',\n use: 'File',\n toJson: `this.${camelcase(context.name)}`,\n simple: true,\n fromJson: context.name ? `json['${context.name}']` : 'json',\n matches: `json['${context.name}'] is Uint8List`,\n };\n default:\n return {\n encode: 'input',\n use: `String`,\n content: '',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: context.name ? `json['${context.name}'] as String` : 'json',\n matches: `json['${context.name}'] is String`,\n };\n }\n }\n\n /**\n * Handle number/integer types with formats\n */\n number(schema: SchemaObject, context: Context): Serialized {\n if (schema.type === 'integer') {\n return {\n content: '',\n use: 'int',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is int`,\n };\n }\n if (['float', 'double'].includes(schema.format as string)) {\n return {\n content: '',\n use: 'double',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is double`,\n };\n }\n return {\n content: '',\n use: 'num',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is double`,\n };\n }\n\n #serialize(\n className: string,\n schema: SchemaObject | ReferenceObject,\n required = true,\n context: Context = {},\n ): Serialized {\n if (isRef(schema)) {\n return this.#ref(className, schema.$ref, required, context);\n }\n if (schema.allOf && Array.isArray(schema.allOf)) {\n return this.#allOf(className, schema.allOf, context);\n }\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return this.#anyOf(className, schema.anyOf, context);\n }\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return this.#oneOf(className, schema.oneOf, context);\n }\n if (schema.enum && Array.isArray(schema.enum)) {\n return this.#enum(className, schema, context);\n }\n // Handle types\n const types = Array.isArray(schema.type)\n ? schema.type\n : schema.type\n ? [schema.type]\n : [];\n\n let nullable = false;\n if ('nullable' in schema && schema.nullable) {\n nullable = true;\n } else if (schema.default === null) {\n nullable = true;\n } else if (types.includes('null')) {\n nullable = true;\n }\n\n // If no explicit \"type\", fallback to dynamic\n if (!types.length) {\n // unless properties are defined then assume object\n if ('properties' in schema) {\n return this.#object(className, schema, context);\n }\n if ('items' in schema) {\n return this.#array(className, schema, true, context);\n }\n return {\n content: '',\n use: 'dynamic',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n }\n return this.#primitive(\n className,\n types[0],\n schema,\n { ...context, nullable },\n required,\n );\n }\n\n handle(\n className: string,\n schema: SchemaObject | ReferenceObject,\n required = true,\n context: Context = {},\n ): Serialized {\n const alias = context.alias;\n context.alias = undefined;\n const serialized = this.#serialize(className, schema, required, {\n ...context,\n forJson: alias,\n });\n\n if (alias) {\n this.#emit(className, `typedef ${alias} = ${serialized.use};`);\n return serialized;\n }\n return serialized;\n }\n}\n\nexport function isObjectSchema(\n schema: SchemaObject | ReferenceObject,\n): schema is SchemaObject {\n return !isRef(schema) && (schema.type === 'object' || !!schema.properties);\n}\n", "import 'package:mime/mime.dart' as mime;\nimport 'dart:convert';\nimport 'dart:io';\n\nimport './interceptors.dart';\nimport 'package:http/http.dart' as http;\nimport 'package:http_parser/http_parser.dart';\n\nclass Dispatcher {\n final List<Interceptor> interceptors;\n\n Dispatcher(this.interceptors);\n\n Future<http.StreamedResponse> multipart(\n RequestConfig config,\n Map<String, dynamic> body,\n ) async {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.MultipartRequest(\n modifiedConfig.method,\n modifiedConfig.url,\n );\n request.headers.addAll(modifiedConfig.headers);\n for (var entry in body.entries) {\n final key = entry.key;\n final value = entry.value;\n if (value is File) {\n final mimeType = mime.lookupMimeType(value.path);\n request.files.add(\n http.MultipartFile(\n key,\n value.openRead(),\n await value.length(),\n filename: value.uri.pathSegments.last,\n contentType: mimeType != null ? MediaType.parse(mimeType) : null,\n ),\n );\n } else {\n request.fields[key] = value.toString();\n }\n }\n\n return request.send();\n }\n\n Future<http.StreamedResponse> empty(RequestConfig config) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n return request.send();\n }\n\n Future<http.StreamedResponse> json(RequestConfig config, dynamic body) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n\n if ((body is Map || body is List)) {\n request.headers['Content-Type'] = 'application/json';\n request.body = jsonEncode(body);\n } else if (body is String) {\n request.body = body;\n } else {\n throw ArgumentError('Unsupported body type: ${body.runtimeType}');\n }\n\n return request.send();\n }\n}\n", "abstract class Interceptor {\n RequestConfig before(RequestConfig config);\n void after();\n}\n\nclass BaseUrlInterceptor extends Interceptor {\n final String Function() getBaseUrl;\n BaseUrlInterceptor(this.getBaseUrl);\n\n @override\n RequestConfig before(RequestConfig config) {\n final baseUrl = getBaseUrl();\n if (config.url.scheme.isEmpty) {\n config.url = Uri.parse(baseUrl + config.url.toString());\n }\n return config;\n }\n\n @override\n void after() {\n //\n }\n}\n\nclass RequestConfig {\n final String method;\n Uri url;\n final Map<String, String> headers;\n RequestConfig({required this.method, required this.url, required this.headers});\n}\n"],
|
|
5
|
-
"mappings": ";AAAA,SAAS,SAAS,uBAAuB;AACzC,SAAS,SAAAA,cAAa;AACtB,OAAOC,aAAY;AACnB,SAAS,iBAAiB;AAC1B,SAAS,YAAY;AASrB,SAAS,aAAAC,kBAAiB;AAC1B,OAAO,UAAU;AAEjB;AAAA,EACE,aAAAC;AAAA,EACA;AAAA,EACA,WAAAC;AAAA,EACA,SAAAC;AAAA,EACA,UAAAC;AAAA,EACA,cAAAC;AAAA,EACA,aAAAC;AAAA,EACA;AAAA,OACK;;;ACvBP,SAAS,aAAa;;;ACAtB,SAAS,SAAAC,cAAa;;;ACItB,SAAS,iBAAiB;AAEnB,IAAM,WACgD;EAC3D,aAAa,CAAC,WAAW,MAAM,WAAW;AACxC,QAAI,UAAU,aAAa;AACzB,aAAO,UAAU,UAAU,WAAW;IACxC;AACA,UAAM,WAAW,UAAU,WAAW;AACtC,QAAI,YAAY,SAAS,MAAM;AAC7B,aAAO,UAAU,SAAS,IAAI;IAChC;AACA,WAAO;MACL,CAAC,QAAQ,GAAG,KAAK,QAAQ,gBAAgB,GAAG,EAAE,MAAM,GAAG,CAAC,EACrD,OAAO,OAAO,EACd,KAAK,GAAG,EACR,KAAK;IACV;EACF;EACA,KAAK,CAAC,WAAW,SAAS;AACxB,WAAO,UAAU,OAAO,CAAC,KAAK,oBAAoB,MAAM,SAAS;EACnE;AACF;AAmBO,SAAS,iBACd,QACA,UACA;AACA,QAAM,SAAc,CAAC;AACrB,aAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,OAAO,KAAK,SAAS,CAAC,CAAC,GAAG;AACtE,UAAM,EAAE,aAAa,CAAC,GAAG,GAAG,QAAQ,IAAI;AAGxC,UAAM,YAAY,KAAK,QAAQ,aAAa,MAAM;AAElD,eAAW,CAAC,QAAQ,SAAS,KAAK,OAAO,QAAQ,OAAO,GAGnD;AACH,YAAM,oBAAoB,OAAO,eAAe,SAAS;AACzD,YAAM,YAAY,OAAO,OAAO,SAAS;AACzC,YAAM,gBAAgB,kBAAkB,WAAW,WAAW,MAAM;AACpE,YAAM,eAAe,UAAU,WAAW,SAAS;AACnD,YAAM,WAAW,UAAU,WAAW,KAAK,CAAC;AAC5C,aAAO;QACL;UACE;YACE,MAAM,SAAS;YACf;YACA,MAAM;YACN,WAAW;YACX,KAAK;UACP;UACA;YACE,GAAG;YACH,YAAY,CAAC,GAAG,YAAY,GAAI,UAAU,cAAc,CAAC,CAAE;YAC3D,aAAa;UACf;QACF;MACF;IACF;EACF;AACA,SAAO;AACT;AAgBA,IAAM,mBAAmB,oBAAI,IAAI;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACF,CAAC;AAUD,SAAS,YAAY,eAA+B;AAElD,MAAI,MAAM,KAAK,aAAa,GAAG;AAC7B,WAAO,IAAI,aAAa;EAC1B;AAEA,SAAO,iBAAiB,IAAI,aAAa,IACrC,GAAG,aAAa,MAChB;AACN;AASO,SAAS,oBACd,YACA,WACQ;AACR,QAAM,cAAc,UAAU,eAAe;AAC7C,QAAM,gBAAgB;AACtB,QAAM,cAAc,oBAAI,IAAI;;IAE1B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EACF,CAAC;AAED,QAAM,WAAW,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAErD,QAAM,sBAAsB,SAAS;IACnC,CAAC,YACC,WACA,CAAC,QAAQ,WAAW,GAAG,KACvB,CAAC,QAAQ,SAAS,GAAG,KACrB,CAAC,cAAc,KAAK,OAAO;EAC/B;AAGA,WAAS,IAAI,oBAAoB,SAAS,GAAG,KAAK,GAAG,KAAK;AACxD,UAAM,UAAU,oBAAoB,CAAC;AACrC,QAAI,CAAC,QAA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",
|
|
6
|
-
"names": ["merge", "assert", "
|
|
3
|
+
"sources": ["../src/lib/generate.ts", "../../core/src/index.ts", "../../core/src/lib/deriver.ts", "../../core/src/lib/file-system.ts", "../../core/src/lib/paths.ts", "../../core/src/lib/program.ts", "../../core/src/lib/ref.ts", "../../spec/src/lib/loaders/local-loader.ts", "../../spec/src/lib/loaders/remote-loader.ts", "../../spec/src/lib/operation.ts", "../src/lib/dart-emitter.ts", "../src/lib/http/dispatcher.txt", "../src/lib/http/interceptors.txt", "../src/lib/http/responses.txt"],
|
|
4
|
+
"sourcesContent": ["import { parse as partContentType } from 'fast-content-type-parse';\nimport { merge } from 'lodash-es';\nimport assert from 'node:assert';\nimport { writeFile } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport type {\n OpenAPIObject,\n OperationObject,\n ReferenceObject,\n RequestBodyObject,\n ResponseObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\nimport yaml from 'yaml';\n\nimport {\n followRef,\n getFolderExportsV2,\n isEmpty,\n isRef,\n notRef,\n pascalcase,\n snakecase,\n writeFiles,\n} from '@sdk-it/core';\nimport {\n type Operation,\n forEachOperation,\n isStreamingContentType,\n isSuccessStatusCode,\n parseJsonContentType,\n} from '@sdk-it/spec';\n\nimport { DartSerializer, isObjectSchema } from './dart-emitter.ts';\nimport dispatcherTxt from './http/dispatcher.txt';\nimport interceptorsTxt from './http/interceptors.txt';\nimport responsesTxt from './http/responses.txt';\n\nfunction tuneSpec(\n spec: OpenAPIObject,\n schemas: Record<string, SchemaObject | ReferenceObject>,\n refs: { name: string; value: SchemaObject }[],\n) {\n for (const [name, schema] of Object.entries(schemas)) {\n if (isRef(schema)) continue;\n\n if (!isEmpty(schema.anyOf) && !isEmpty(schema.oneOf)) {\n delete schema.anyOf;\n }\n if (!isEmpty(schema.allOf)) {\n const schemas = schema.allOf;\n const refs = schemas.filter(isRef);\n const nonRefs = schemas.filter(notRef);\n if (nonRefs.some((it) => it.type && it.type !== 'object')) {\n assert(false, `allOf ${name} must be an object`);\n }\n const objectSchema = merge(\n {},\n ...nonRefs,\n ...refs.map((ref) => followRef(spec, ref.$ref)),\n );\n delete objectSchema.allOf;\n delete schema.allOf;\n Object.assign(schema, objectSchema);\n }\n\n if (schema.type === 'object') {\n if (!isEmpty(schema.oneOf)) {\n for (const oneOfIdx in schema.oneOf) {\n const oneOf = schema.oneOf[oneOfIdx];\n if (isRef(oneOf)) continue;\n if (!isEmpty(oneOf.required) && schema.properties) {\n schema.oneOf[oneOfIdx] = schema.properties[oneOf.required[0]];\n }\n }\n\n delete schema.type;\n tuneSpec(spec, schemas, refs);\n continue;\n }\n\n schema.properties ??= {};\n\n for (const [propName, value] of Object.entries(schema.properties)) {\n if (isRef(value)) continue;\n const refName = pascalcase(`${name} ${propName.replace('[]', '')}`);\n refs.push({ name: refName, value });\n schema.properties[propName] = {\n $ref: `#/components/schemas/${refName}`,\n };\n const props = Object.fromEntries(\n Object.entries(value.properties ?? {}).map(([key, value]) => {\n return [pascalcase(`${refName} ${key}`), value];\n }),\n );\n tuneSpec(spec, props, refs);\n // if (value.oneOf && Array.isArray(value.oneOf) && value.oneOf.length) {\n // for (const oneOfIdx in value.oneOf) {\n // const oneOf = value.oneOf[oneOfIdx];\n // if (isRef(oneOf)) continue;\n // if (oneOf.type === 'string') {\n // console.log(refName);\n // // const refName= pascalcase(`${name} ${key} ${oneOfIdx}`);\n // // schema.oneOf[oneOfIdx] = {\n // // $ref: `#/components/schemas/${refName}`,\n // // };\n // }\n // }\n // }\n }\n } else if (schema.type === 'array') {\n if (isRef(schema.items)) continue;\n const refName = name;\n refs.push({ name: refName, value: schema.items ?? {} });\n schema.items = {\n $ref: `#/components/schemas/${refName}`,\n };\n }\n }\n}\nexport async function generate(\n spec: OpenAPIObject,\n settings: {\n output: string;\n name?: string;\n /**\n * full: generate a full project including package.json and tsconfig.json. useful for monorepo/workspaces\n * minimal: generate only the client sdk\n */\n mode?: 'full' | 'minimal';\n formatCode?: (options: { output: string }) => void | Promise<void>;\n },\n) {\n const clientName = settings.name || 'Client';\n const output = join(settings.output, 'lib');\n const groups: Record<\n string,\n {\n use: string;\n methods: string[];\n }\n > = {};\n spec.components ??= {};\n spec.components.schemas ??= {};\n const inputs: Record<string, string> = {};\n const outputs: Record<string, string> = {};\n forEachOperation({ spec }, (entry, operation) => {\n // if (entry.path !== '/v6/prepareUpload') {\n // return;\n // }\n operation.responses ??= {};\n spec.components ??= {};\n spec.components.schemas ??= {};\n for (const status in operation.responses) {\n if (!isSuccessStatusCode(status)) continue;\n const response = isRef(operation.responses[status] as ReferenceObject)\n ? followRef<ResponseObject>(spec, operation.responses[status].$ref)\n : (operation.responses[status] as ResponseObject);\n if (!isEmpty(response.content)) {\n for (const [contentType, mediaType] of Object.entries(\n response.content,\n )) {\n if (parseJsonContentType(contentType)) {\n if (mediaType.schema && !isRef(mediaType.schema)) {\n const outputName = pascalcase(`${operation.operationId} output`);\n spec.components.schemas[outputName] = mediaType.schema;\n operation.responses[status].content[contentType].schema = {\n $ref: `#/components/schemas/${outputName}`,\n };\n }\n }\n // handle chunked response\n }\n }\n }\n console.log(`Processing ${entry.method} ${entry.path}`);\n const group =\n groups[entry.groupName] ??\n (groups[entry.groupName] = {\n methods: [],\n use: `final ${entry.groupName} = new ${pascalcase(entry.groupName)}();`,\n });\n\n const input = toInputs(spec, { entry, operation });\n Object.assign(inputs, input.inputs);\n\n const response = toOutput(spec, operation);\n if (response) {\n Object.assign(outputs, response.outputs);\n }\n group.methods.push(`\n Future<${response ? response.returnType : 'http.StreamedResponse'}> ${camelcase(operation.operationId)}(\n ${isEmpty(operation.requestBody) ? '' : `${input.inputName} input`}\n ) async {\n final stream = await this.dispatcher.${input.contentType}(RequestConfig(\n method: '${entry.method}',\n url: Uri.parse('${entry.path}'),\n headers: {},\n ), ${['json', 'multipart'].includes(input.contentType) ? input.encode : ``});\n ${response ? `${response.decode};` : 'return stream;'}\n }\n `);\n });\n\n const newRefs: { name: string; value: SchemaObject }[] = [];\n tuneSpec(spec, spec.components.schemas, newRefs);\n for (const ref of newRefs) {\n spec.components.schemas[ref.name] = ref.value;\n }\n await writeFile(\n join(process.cwd(), 'openai.json'),\n JSON.stringify(spec, null, 2),\n );\n\n const models = Object.entries(spec.components.schemas).reduce<\n Record<string, string>\n >((acc, [name, schema]) => {\n const serializer = new DartSerializer(spec, (name, content) => {\n acc[`models/${snakecase(name)}.dart`] =\n `import 'dart:io';import 'dart:typed_data'; import './index.dart';\\n\\n${content}`;\n });\n serializer.handle(pascalcase(name), schema);\n return acc;\n }, {});\n\n const clazzez = Object.entries(groups).reduce<Record<string, string>>(\n (acc, [name, { methods }]) => {\n return {\n ...acc,\n [`api/${snakecase(name)}.dart`]: `\nimport 'dart:convert';\n\nimport 'package:http/http.dart' as http;\n\nimport '../interceptors.dart';\nimport '../inputs/index.dart';\nimport '../outputs/index.dart';\nimport '../models/index.dart';\nimport '../http.dart';\n\n class ${pascalcase(name)}Client {\n final Dispatcher dispatcher;\n final Receiver receiver;\n ${pascalcase(name)}Client(this.dispatcher, this.receiver);\n ${methods.join('\\n')}\n }\n `,\n };\n },\n {},\n );\n\n const client = `\n ${Object.keys(groups)\n .map((name) => `import './api/${snakecase(name)}.dart';`)\n .join('\\n')}\nimport './interceptors.dart';\nimport './http.dart';\n\n class ${clientName} {\n final Options options;\n${Object.keys(groups)\n .map((name) => `late final ${pascalcase(name)}Client ${camelcase(name)};`)\n .join('\\n')}\n\n ${clientName}(this.options) {\n final interceptors = [BaseUrlInterceptor(() => this.options.baseUrl)];\n final dispatcher = Dispatcher(interceptors);\n final receiver = Receiver(interceptors);\n ${Object.keys(groups)\n .map(\n (name) =>\n `this.${camelcase(name)} = ${pascalcase(name)}Client(dispatcher, receiver);`,\n )\n .join('\\n')}\n\n }\n\n void setOptions({String? baseUrl}) {\n if (baseUrl != null) {\n options.baseUrl = baseUrl;\n }\n }\n }\n\n\nclass Options {\n String baseUrl;\n Options({required this.baseUrl});\n}\n\n `;\n await writeFiles(output, {\n ...models,\n ...inputs,\n ...outputs,\n });\n\n await writeFiles(output, {\n 'models/index.dart': await getFolderExportsV2(join(output, 'models'), {\n exportSyntax: 'export',\n extensions: 'dart',\n }),\n 'inputs/index.dart': await getFolderExportsV2(join(output, 'inputs'), {\n exportSyntax: 'export',\n extensions: 'dart',\n }),\n 'outputs/index.dart': await getFolderExportsV2(join(output, 'outputs'), {\n exportSyntax: 'export',\n extensions: 'dart',\n }),\n 'interceptors.dart': interceptorsTxt,\n 'http.dart': dispatcherTxt,\n 'responses.dart': responsesTxt,\n ...clazzez,\n });\n await writeFiles(output, {\n 'package.dart': `${await getFolderExportsV2(join(output), {\n exportSyntax: 'export',\n extensions: 'dart',\n ignore(dirent) {\n return dirent.isFile() && dirent.name === 'package.dart';\n },\n })}${client}`,\n });\n\n await writeFiles(settings.output, {\n 'pubspec.yaml': {\n ignoreIfExists: true,\n content: yaml.stringify({\n name: settings.name\n ? `${snakecase(clientName.toLowerCase())}_sdk`\n : 'sdk',\n version: '0.0.1',\n environment: {\n sdk: '^3.7.2',\n },\n dependencies: {\n http: '^1.3.0',\n mime: '^2.0.0',\n },\n }),\n },\n });\n\n await settings.formatCode?.({\n output: output,\n });\n}\n\nfunction toInputs(spec: OpenAPIObject, { entry, operation }: Operation) {\n const inputs: Record<string, unknown> = {};\n const inputName = pascalcase(`${operation.operationId} input`);\n let contentType = 'empty';\n let encode = '';\n if (!isEmpty(operation.requestBody)) {\n const requestBody = isRef(operation.requestBody)\n ? followRef<RequestBodyObject>(spec, operation.requestBody.$ref)\n : operation.requestBody;\n\n for (const type in requestBody.content) {\n const ctSchema = isRef(requestBody.content[type].schema)\n ? followRef(spec, requestBody.content[type].schema.$ref)\n : requestBody.content[type].schema;\n if (!ctSchema) {\n console.warn(\n `Schema not found for ${type} in ${entry.method} ${entry.path}`,\n );\n continue;\n }\n\n const serializer = new DartSerializer(spec, (name, content) => {\n inputs[join(`inputs/${name}.dart`)] =\n `import 'dart:io';import 'dart:typed_data';import '../models/index.dart'; import './index.dart';\\n\\n${content}`;\n });\n const serialized = serializer.handle(inputName, ctSchema, true, {\n alias: isObjectSchema(ctSchema) ? undefined : inputName,\n });\n encode = serialized.encode as string;\n const [mediaType, mediaSubType] = partContentType(type).type.split('/');\n if (mediaType === 'application') {\n contentType = parseJsonContentType(type) as string;\n } else {\n contentType = mediaType;\n }\n\n // const schema = merge({}, objectSchema, {\n // required: additionalProperties\n // .filter((p) => p.required)\n // .map((p) => p.name),\n // properties: additionalProperties.reduce<Record<string, unknown>>(\n // (acc, p) => ({\n // ...acc,\n // [p.name]: p.schema,\n // }),\n // {},\n // ),\n // });\n\n // Object.assign(inputs, bodyInputs(config, objectSchema));\n // schemas[shortContenTypeMap[type]] = zodDeserialzer.handle(schema, true);\n }\n }\n\n return { inputs, inputName, contentType, encode };\n}\n\nfunction toOutput(spec: OpenAPIObject, operation: OperationObject) {\n const outputName = pascalcase(`${operation.operationId} output`);\n operation.responses ??= {};\n const outputs: Record<string, string> = {};\n for (const status in operation.responses) {\n const response = isRef(operation.responses[status] as ReferenceObject)\n ? followRef<ResponseObject>(spec, operation.responses[status].$ref)\n : (operation.responses[status] as ResponseObject);\n for (const type in response.content) {\n const { schema } = response.content[type];\n if (!schema) {\n console.warn(\n `Schema not found for ${type} in ${operation.operationId}`,\n );\n continue;\n }\n const serializer = new DartSerializer(spec, (name, content) => {\n // outputs[join(`outputs/${name}.dart`)] =\n // `import 'dart:typed_data'; import '../models/index.dart'; \\n\\n${content}`;\n });\n if (isStreamingContentType(type)) {\n return {\n type: 'stream',\n outputName,\n outputs,\n decode: `return stream`,\n returnType: `http.StreamedResponse`,\n };\n }\n if (parseJsonContentType(type)) {\n const serialized = serializer.handle(outputName, schema, true, {\n // alias: outputName,\n noEmit: true,\n });\n return {\n type: 'json',\n outputName,\n outputs,\n decode: `final json = await this.receiver.json(stream); return ${serialized.fromJson}`,\n returnType: serialized.use,\n };\n }\n }\n }\n return null;\n}\n", "import {\n pascalcase as _pascalcase,\n snakecase as _snakecase,\n spinalcase as _spinalcase,\n} from 'stringcase';\nimport type ts from 'typescript';\n\nimport type { TypeDeriver } from './lib/deriver.ts';\nimport type { ResponseItem } from './lib/paths.ts';\n\nexport * from './lib/deriver.ts';\nexport * from './lib/file-system.ts';\nexport * from './lib/paths.ts';\nexport * from './lib/program.ts';\nexport * from './lib/ref.ts';\n\nexport function removeDuplicates<T>(\n data: T[],\n accessor: (item: T) => T[keyof T] | T = (item) => item,\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\nexport type NaunceResponseAnalyzerFn = (\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n node: ts.Node,\n) => ResponseItem[];\nexport type NaunceResponseAnalyzer = Record<string, NaunceResponseAnalyzerFn>;\n\nexport type ResponseAnalyzerFn = (\n handler: ts.ArrowFunction,\n deriver: TypeDeriver,\n) => ResponseItem[];\n\nexport function isEmpty(value: unknown): value is null | undefined | '' {\n if (value === null || value === undefined || value === '') {\n return true;\n }\n if (Array.isArray(value) && value.length === 0) {\n return true;\n }\n if (typeof value === 'object' && Object.keys(value).length === 0) {\n return true;\n }\n return false;\n}\n\nexport function pascalcase(value: string) {\n return _pascalcase(value.split('/').join(' '));\n}\nexport function spinalcase(value: string) {\n return _spinalcase(value.split('/').join(' '));\n}\nexport function snakecase(value: string) {\n return _snakecase(value.split('/').join(' '));\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 Readable: 'any',\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 const indexType = type.getStringIndexType();\n if (indexType) {\n return {\n [deriveSymbol]: true,\n kind: 'record',\n optional: false,\n [$types]: [this.serializeType(indexType)],\n };\n }\n if (type.flags & TypeFlags.Any) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.flags & TypeFlags.Unknown) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: [],\n };\n }\n if (type.isStringLiteral()) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: type.value,\n [$types]: ['string'],\n };\n }\n if (type.isNumberLiteral()) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: type.value,\n [$types]: ['number'],\n };\n }\n if (type.flags & TypeFlags.BooleanLiteral) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['boolean'],\n };\n }\n\n if (type.flags & TypeFlags.TemplateLiteral) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['string'],\n };\n }\n if (type.flags & TypeFlags.String) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['string'],\n };\n }\n if (type.flags & TypeFlags.Number) {\n return {\n [deriveSymbol]: true,\n optional: false,\n [$types]: ['number'],\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.flags & TypeFlags.Null) {\n return {\n [deriveSymbol]: true,\n optional: true,\n [$types]: ['null'],\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 // ignore 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.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 const propAssingment = (prop.getDeclarations() ?? []).find((it) =>\n ts.isPropertyAssignment(it),\n );\n // get literal properties values if any\n if (propAssingment) {\n const type = this.checker.getTypeAtLocation(\n propAssingment.initializer,\n );\n serializedProps[prop.name] = this.serializeType(type);\n }\n if (\n (prop.getDeclarations() ?? []).find((it) =>\n ts.isPropertySignature(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 console.warn(`Unhandled type: ${type.flags} ${ts.TypeFlags[type.flags]}`);\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\n // get literal properties values if any\n for (const prop of node.properties) {\n if (ts.isPropertyAssignment(prop)) {\n const type = this.checker.getTypeAtLocation(prop.initializer);\n props[prop.name.getText()] = this.serializeType(type);\n }\n }\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 (node.kind === ts.SyntaxKind.TrueKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: true,\n [$types]: ['boolean'],\n };\n }\n if (node.kind === ts.SyntaxKind.FalseKeyword) {\n return {\n [deriveSymbol]: true,\n optional: false,\n kind: 'literal',\n value: 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 type { Dirent } from 'node:fs';\nimport { mkdir, readFile, readdir, stat, writeFile } from 'node:fs/promises';\nimport { dirname, extname, 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 null | string | { content: string; ignoreIfExists?: boolean }\n >,\n) {\n await Promise.all(\n Object.entries(contents).map(async ([file, content]) => {\n if (content === null) {\n return;\n }\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 } else {\n await writeFile(filePath, content.content, 'utf-8');\n }\n }\n }),\n );\n}\n\nexport async function getFolderExports(\n folder: string,\n includeExtension = true,\n extensions = ['ts'],\n ignore: (dirent: Dirent) => boolean = () => false,\n) {\n const files = await readdir(folder, { withFileTypes: true });\n const exports: string[] = [];\n for (const file of files) {\n if (ignore(file)) {\n continue;\n }\n if (file.isDirectory()) {\n if (await exist(`${file.parentPath}/${file.name}/index.ts`)) {\n exports.push(\n `export * from './${file.name}/index${includeExtension ? '.ts' : ''}';`,\n );\n }\n } else if (\n file.name !== 'index.ts' &&\n extensions.includes(getExt(file.name))\n ) {\n exports.push(\n `export * from './${includeExtension ? file.name : file.name.replace(extname(file.name), '')}';`,\n );\n }\n }\n return exports.join('\\n');\n}\n\nexport async function getFolderExportsV2(\n folder: string,\n options: {\n includeExtension?: boolean;\n extensions: string;\n ignore?: (dirent: Dirent) => boolean;\n exportSyntax: string;\n } = {\n extensions: 'ts',\n ignore: () => false,\n includeExtension: true,\n exportSyntax: 'export * from ',\n },\n) {\n options.includeExtension ??= true;\n if (!(await exist(folder))) {\n return '';\n }\n const files = await readdir(folder, { withFileTypes: true });\n const exports: string[] = [];\n for (const file of files) {\n if (options.ignore?.(file)) {\n continue;\n }\n if (file.isDirectory()) {\n if (\n await exist(\n `${file.parentPath}/${file.name}/index.${options.extensions}`,\n )\n ) {\n exports.push(\n `${options.exportSyntax} './${file.name}/index${options.includeExtension ? `.${options.extensions}` : ''}';`,\n );\n }\n } else if (\n file.name !== `index.${options.extensions}` &&\n options.extensions.includes(getExt(file.name))\n ) {\n exports.push(\n `${options.exportSyntax} './${options.includeExtension ? file.name : file.name.replace(extname(file.name), '')}';`,\n );\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", "import type {\n HeadersObject,\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 | Record<string, 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 contentType?: string;\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 contentType: string | undefined,\n selectors: Selector[],\n responses: ResponseItem[],\n sourceFile: string,\n tags?: string[],\n description?: string,\n ) {\n const responsesObject = this.#responseItemToResponses(responses);\n\n this.#operations.push({\n name,\n path: this.#tunePath(path),\n sourceFile,\n contentType: contentType,\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 !== 'empty'\n ? {\n [ct]:\n ct === 'application/octet-stream'\n ? { schema: { type: 'string', format: 'binary' } }\n : { schema },\n }\n : undefined,\n headers: item.headers.length\n ? item.headers.reduce<HeadersObject>((acc, current) => {\n const headers =\n typeof current === 'string' ? { [current]: [] } : current;\n return Object.entries(headers).reduce<HeadersObject>(\n (subAcc, [key, value]) => {\n const header: HeadersObject = {\n [key]: {\n schema: {\n type: 'string',\n enum: value.length ? value : undefined,\n },\n },\n };\n return { ...subAcc, ...header };\n },\n acc,\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<\n string,\n { required: boolean; schema: SchemaObject }\n > = {};\n for (const selector of selectors) {\n if (selector.source === 'body') {\n bodySchemaProps[selector.name] = {\n required: selector.required,\n schema: await evalZod(selector.against, 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 bodySchema: Record<string, SchemaObject> = {};\n const required: string[] = [];\n for (const [key, value] of Object.entries(bodySchemaProps)) {\n if (value.required) {\n required.push(key);\n }\n bodySchema[key] = value.schema;\n }\n const operationObject: OperationObject = {\n operationId: operation.name,\n parameters,\n tags: operation.tags,\n description: operation.description,\n requestBody: Object.keys(bodySchema).length\n ? {\n required: required.length ? true : false,\n content: {\n [operation.contentType || 'application/json']: {\n schema: {\n required: required.length ? required : undefined,\n type: 'object',\n properties: bodySchema,\n },\n },\n },\n }\n : undefined,\n responses:\n Object.keys(operation.responses).length === 0\n ? undefined\n : operation.responses,\n };\n if (!operations[path]) {\n operations[path] = {};\n }\n operations[path][method] = operationObject;\n if (this.#onOperation) {\n const paths = this.#onOperation?.(\n operation.sourceFile,\n method,\n path,\n operationObject,\n );\n Object.assign(operations, paths ?? {});\n }\n }\n return operations;\n }\n\n /**\n * Converts Express/Node.js style path parameters (/path/:param) to OpenAPI style (/path/{param})\n */\n #tunePath(path: string): string {\n return path.replace(/:([^/]+)/g, '{$1}');\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 ? `const commonZod = require('${commonZodImport}');` : '',\n `const {zodToJsonSchema} = require('zod-to-json-schema');`,\n `const schema = ${schema.replace('.optional()', '').replaceAll('instanceof(File)', 'string().base64()')};`,\n `const jsonSchema = zodToJsonSchema(schema, {\n $refStrategy: 'root',\n basePath: ['#', 'components', 'schemas'],\n target: 'jsonSchema7',\n base64Strategy: 'format:binary',\n });`,\n `export default jsonSchema;`,\n ];\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 value?: string;\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 === 'literal') {\n return { enum: [data.value], type: data[$types][0] };\n } else if (data.kind === 'record') {\n return {\n type: 'object',\n additionalProperties: toSchema(data[$types][0]),\n };\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 { anyOf: 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 const required: string[] = [];\n for (const [key, value] of Object.entries(data)) {\n props[key] = toSchema(value as any);\n if (!(value as any).optional) {\n required.push(key);\n }\n }\n return {\n type: 'object',\n properties: props,\n required,\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 debug from 'debug';\nimport { dirname, join } from 'node:path';\nimport ts from 'typescript';\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}\n", "import { get } from 'lodash-es';\nimport type {\n OpenAPIObject,\n ParameterObject,\n ReferenceObject,\n RequestBodyObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\n\nexport function isRef(obj: any): obj is ReferenceObject {\n return obj && '$ref' in obj;\n}\nexport function notRef(obj: any): obj is SchemaObject {\n return !isRef(obj);\n}\n\nexport function cleanRef(ref: string) {\n return ref.replace(/^#\\//, '');\n}\n\nexport function parseRef(ref: string) {\n const parts = ref.split('/');\n const [model] = parts.splice(-1);\n const [namespace] = parts.splice(-1);\n return {\n model,\n namespace,\n path: cleanRef(parts.join('/')),\n };\n}\nexport function followRef<\n T extends SchemaObject | ParameterObject | RequestBodyObject = SchemaObject,\n>(spec: OpenAPIObject, ref: string): T {\n const pathParts = cleanRef(ref).split('/');\n const entry = get(spec, pathParts) as T | ReferenceObject;\n if (entry && '$ref' in entry) {\n return followRef<T>(spec, entry.$ref);\n }\n return entry;\n}\n", "import { readFile } from 'node:fs/promises';\nimport { extname } from 'node:path';\nimport { parse } from 'yaml';\n\nexport async function loadLocal(location: string) {\n const extName = extname(location);\n const text = await readFile(location, 'utf-8');\n switch (extName) {\n case '.json':\n return JSON.parse(text);\n case '.yaml':\n case '.yml':\n return parse(text);\n default:\n throw new Error(`Unsupported file extension: ${extName}`);\n }\n}\n", "import { extname } from 'node:path';\nimport { parse } from 'yaml';\n\nexport async function loadRemote<T>(location: string): Promise<T> {\n const extName = extname(location);\n const response = await fetch(location);\n switch (extName) {\n case '.json':\n return response.json() as Promise<T>;\n case '.yaml':\n case '.yml': {\n const text = await response.text();\n return parse(text);\n }\n default:\n try {\n // try to parse it as json first\n return response.json() as Promise<T>;\n } catch {\n // parse as yaml\n const text = await response.text();\n return parse(text) as Promise<T>;\n }\n }\n}\n", "import type {\n OpenAPIObject,\n OperationObject,\n ParameterObject,\n ReferenceObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase } from 'stringcase';\n\nexport const defaults: Partial<GenerateSdkConfig> &\n Required<Pick<GenerateSdkConfig, 'operationId' | 'tag'>> = {\n operationId: (operation, path, method) => {\n if (operation.operationId) {\n return camelcase(operation.operationId);\n }\n const metadata = operation['x-oaiMeta'];\n if (metadata && metadata.name) {\n return camelcase(metadata.name);\n }\n return camelcase(\n [method, ...path.replace(/[\\\\/\\\\{\\\\}]/g, ' ').split(' ')]\n .filter(Boolean)\n .join(' ')\n .trim(),\n );\n },\n tag: (operation, path) => {\n return operation.tags?.[0] || determineGenericTag(path, operation);\n },\n};\n\nexport type TunedOperationObject = OperationObject & {\n operationId: string;\n parameters: (ParameterObject | ReferenceObject)[];\n};\n\nexport interface OperationEntry {\n name?: string;\n method: string;\n path: string;\n groupName: string;\n tag: string;\n}\nexport type Operation = {\n entry: OperationEntry;\n operation: TunedOperationObject;\n};\n\nexport function forEachOperation<T>(\n config: GenerateSdkConfig,\n callback: (entry: OperationEntry, operation: TunedOperationObject) => T,\n) {\n const result: T[] = [];\n for (const [path, pathItem] of Object.entries(config.spec.paths ?? {})) {\n const { parameters = [], ...methods } = pathItem;\n\n // Convert Express-style routes (:param) to OpenAPI-style routes ({param})\n const fixedPath = path.replace(/:([^/]+)/g, '{$1}');\n\n for (const [method, operation] of Object.entries(methods) as [\n string,\n OperationObject,\n ][]) {\n const formatOperationId = config.operationId ?? defaults.operationId;\n const formatTag = config.tag ?? defaults.tag;\n const operationName = formatOperationId(operation, fixedPath, method);\n const operationTag = formatTag(operation, fixedPath);\n const metadata = operation['x-oaiMeta'] ?? {};\n result.push(\n callback(\n {\n name: metadata.name,\n method,\n path: fixedPath,\n groupName: operationTag,\n tag: operationTag,\n },\n {\n ...operation,\n parameters: [...parameters, ...(operation.parameters ?? [])],\n operationId: operationName,\n },\n ),\n );\n }\n }\n return result;\n}\n\nexport interface GenerateSdkConfig {\n spec: OpenAPIObject;\n operationId?: (\n operation: OperationObject,\n path: string,\n method: string,\n ) => string;\n tag?: (operation: OperationObject, path: string) => string;\n}\n\n// --- Function Definition (determineGenericTag, sanitizeTag, reservedKeywords, commonVerbs) ---\n/**\n * Set of reserved TypeScript keywords and common verbs potentially used as tags.\n */\nconst reservedKeywords = new Set([\n 'abstract',\n 'arguments',\n 'await',\n 'boolean',\n 'break',\n 'byte',\n 'case',\n 'catch',\n 'char',\n 'class',\n 'const',\n 'continue',\n 'debugger',\n 'default',\n 'delete',\n 'do',\n 'double',\n 'else',\n 'enum',\n 'eval',\n 'export',\n 'extends',\n 'false',\n 'final',\n 'finally',\n 'float',\n 'for',\n 'function',\n 'goto',\n 'if',\n 'implements',\n 'import',\n 'in',\n 'instanceof',\n 'int',\n 'interface',\n 'let',\n 'long',\n 'native',\n 'new',\n 'null',\n 'package',\n 'private',\n 'protected',\n 'public',\n 'return',\n 'short',\n 'static',\n 'super',\n 'switch',\n 'synchronized',\n 'this',\n 'throw',\n 'throws',\n 'transient',\n 'true',\n 'try',\n 'typeof',\n 'var',\n 'void',\n 'volatile',\n 'while',\n 'with',\n 'yield',\n // Potentially problematic identifiers / Common Verbs used as tags\n 'object',\n 'string',\n 'number',\n 'any',\n 'unknown',\n 'never',\n 'get',\n 'list',\n 'create',\n 'update',\n 'delete',\n 'post',\n 'put',\n 'patch',\n 'do',\n 'send',\n 'add',\n 'remove',\n 'set',\n 'find',\n 'search',\n 'check',\n 'make', // Added make, check\n]);\n\n/**\n * Sanitizes a potential tag name (assumed to be already camelCased)\n * to avoid conflicts with reserved keywords or invalid starting characters (numbers).\n * Appends an underscore if the tag matches a reserved keyword.\n * Prepends an underscore if the tag starts with a number.\n * @param camelCasedTag The potential tag name, already camelCased.\n * @returns The sanitized tag name.\n */\nfunction sanitizeTag(camelCasedTag: string): string {\n // Prepend underscore if starts with a number\n if (/^\\d/.test(camelCasedTag)) {\n return `_${camelCasedTag}`;\n }\n // Append underscore if it's a reserved keyword\n return reservedKeywords.has(camelCasedTag)\n ? `${camelCasedTag}_`\n : camelCasedTag;\n}\n\n/**\n * Attempts to determine a generic tag for an OpenAPI operation based on path and operationId.\n * Rules and fallbacks are documented within the code.\n * @param pathString The path string.\n * @param operation The OpenAPI Operation Object.\n * @returns A sanitized, camelCased tag name string.\n */\nexport function determineGenericTag(\n pathString: string,\n operation: OperationObject,\n): string {\n const operationId = operation.operationId || '';\n const VERSION_REGEX = /^[vV]\\d+$/;\n const commonVerbs = new Set([\n // Verbs to potentially strip from operationId prefix\n 'get',\n 'list',\n 'create',\n 'update',\n 'delete',\n 'post',\n 'put',\n 'patch',\n 'do',\n 'send',\n 'add',\n 'remove',\n 'set',\n 'find',\n 'search',\n 'check',\n 'make', // Added make\n ]);\n\n const segments = pathString.split('/').filter(Boolean);\n\n const potentialCandidates = segments.filter(\n (segment) =>\n segment &&\n !segment.startsWith('{') &&\n !segment.endsWith('}') &&\n !VERSION_REGEX.test(segment),\n );\n\n // --- Heuristic 1: Last non-'@' path segment ---\n for (let i = potentialCandidates.length - 1; i >= 0; i--) {\n const segment = potentialCandidates[i];\n if (!segment.startsWith('@')) {\n // Sanitize just before returning\n return sanitizeTag(camelcase(segment));\n }\n }\n\n const canFallbackToPathSegment = potentialCandidates.length > 0;\n\n // --- Heuristic 2: OperationId parsing ---\n if (operationId) {\n const lowerOpId = operationId.toLowerCase();\n const parts = operationId\n .replace(/([a-z])([A-Z])/g, '$1_$2')\n .replace(/([A-Z])([A-Z][a-z])/g, '$1_$2')\n .replace(/([a-zA-Z])(\\d)/g, '$1_$2')\n .replace(/(\\d)([a-zA-Z])/g, '$1_$2')\n .toLowerCase()\n .split(/[_-\\s]+/);\n\n const validParts = parts.filter(Boolean);\n\n // Quick skip: If opId is just a verb and we can use Heuristic 3, prefer that.\n if (\n commonVerbs.has(lowerOpId) &&\n validParts.length === 1 &&\n canFallbackToPathSegment\n ) {\n // Proceed directly to Heuristic 3\n }\n // Only process if there are valid parts and the quick skip didn't happen\n else if (validParts.length > 0) {\n const firstPart = validParts[0];\n const isFirstPartVerb = commonVerbs.has(firstPart);\n\n // Case 2a: Starts with verb, has following parts\n if (isFirstPartVerb && validParts.length > 1) {\n const verbPrefixLength = firstPart.length;\n let nextPartStartIndex = -1;\n if (operationId.length > verbPrefixLength) {\n // Simplified check for next part start\n const charAfterPrefix = operationId[verbPrefixLength];\n if (charAfterPrefix >= 'A' && charAfterPrefix <= 'Z') {\n nextPartStartIndex = verbPrefixLength;\n } else if (charAfterPrefix >= '0' && charAfterPrefix <= '9') {\n nextPartStartIndex = verbPrefixLength;\n } else if (['_', '-'].includes(charAfterPrefix)) {\n nextPartStartIndex = verbPrefixLength + 1;\n } else {\n const match = operationId\n .substring(verbPrefixLength)\n .match(/[A-Z0-9]/);\n if (match && match.index !== undefined) {\n nextPartStartIndex = verbPrefixLength + match.index;\n }\n if (\n nextPartStartIndex === -1 &&\n operationId.length > verbPrefixLength\n ) {\n nextPartStartIndex = verbPrefixLength; // Default guess\n }\n }\n }\n\n if (\n nextPartStartIndex !== -1 &&\n nextPartStartIndex < operationId.length\n ) {\n const remainingOriginalSubstring =\n operationId.substring(nextPartStartIndex);\n const potentialTag = camelcase(remainingOriginalSubstring);\n if (potentialTag) {\n // Sanitize just before returning\n return sanitizeTag(potentialTag);\n }\n }\n\n // Fallback: join remaining lowercased parts\n const potentialTagJoined = camelcase(validParts.slice(1).join('_'));\n if (potentialTagJoined) {\n // Sanitize just before returning\n return sanitizeTag(potentialTagJoined);\n }\n }\n\n // Case 2b: Doesn't start with verb, or only one part (might be verb)\n const potentialTagFull = camelcase(operationId);\n if (potentialTagFull) {\n const isResultSingleVerb = validParts.length === 1 && isFirstPartVerb;\n\n // Avoid returning only a verb if Heuristic 3 is possible\n if (!(isResultSingleVerb && canFallbackToPathSegment)) {\n if (potentialTagFull.length > 0) {\n // Sanitize just before returning\n return sanitizeTag(potentialTagFull);\n }\n }\n }\n\n // Case 2c: Further fallbacks within OpId if above failed/skipped\n const firstPartCamel = camelcase(firstPart);\n if (firstPartCamel) {\n const isFirstPartCamelVerb = commonVerbs.has(firstPartCamel);\n if (\n !isFirstPartCamelVerb ||\n validParts.length === 1 ||\n !canFallbackToPathSegment\n ) {\n // Sanitize just before returning\n return sanitizeTag(firstPartCamel);\n }\n }\n if (\n isFirstPartVerb &&\n validParts.length > 1 &&\n validParts[1] &&\n canFallbackToPathSegment\n ) {\n const secondPartCamel = camelcase(validParts[1]);\n if (secondPartCamel) {\n // Sanitize just before returning\n return sanitizeTag(secondPartCamel);\n }\n }\n } // End if(validParts.length > 0) after quick skip check\n } // End if(operationId)\n\n // --- Heuristic 3: First path segment (stripping '@') ---\n if (potentialCandidates.length > 0) {\n let firstCandidate = potentialCandidates[0];\n if (firstCandidate.startsWith('@')) {\n firstCandidate = firstCandidate.substring(1);\n }\n if (firstCandidate) {\n // Sanitize just before returning\n return sanitizeTag(camelcase(firstCandidate));\n }\n }\n\n // --- Heuristic 4: Default ---\n console.warn(\n `Could not determine a suitable tag for path: ${pathString}, operationId: ${operationId}. Using 'unknown'.`,\n );\n return 'unknown'; // 'unknown' is safe\n}\n\nexport function parseJsonContentType(contentType: string | null | undefined) {\n if (!contentType) {\n return null;\n }\n\n // 1. Trim whitespace\n let mainType = contentType.trim();\n\n // 2. Remove parameters (anything after the first ';')\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n mainType = mainType.substring(0, semicolonIndex).trim(); // Trim potential space before ';'\n }\n\n // 3. Convert to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n if (mainType.endsWith('/json')) {\n return mainType.split('/')[1];\n } else if (mainType.endsWith('+json')) {\n return mainType.split('+')[1];\n }\n return null;\n}\n\n/**\n * Checks if a given content type string represents Server-Sent Events (SSE).\n * Handles case-insensitivity, parameters (like charset), and leading/trailing whitespace.\n *\n * @param contentType The content type string to check (e.g., from a Content-Type header).\n * @returns True if the content type is 'text/event-stream', false otherwise.\n */\nexport function isSseContentType(\n contentType: string | null | undefined,\n): boolean {\n if (!contentType) {\n return false; // Handle null, undefined, or empty string\n }\n\n // 1. Trim whitespace from the input string\n let mainType = contentType.trim();\n\n // 2. Find the position of the first semicolon (if any) to remove parameters\n const semicolonIndex = mainType.indexOf(';');\n if (semicolonIndex !== -1) {\n // Extract the part before the semicolon and trim potential space\n mainType = mainType.substring(0, semicolonIndex).trim();\n }\n\n // 3. Convert the main type part to lowercase for case-insensitive comparison\n mainType = mainType.toLowerCase();\n\n // 4. Compare against the standard SSE MIME type\n return mainType === 'text/event-stream';\n}\n\nexport function isStreamingContentType(\n contentType: string | null | undefined,\n): boolean {\n return contentType === 'application/octet-stream';\n}\n\nexport function isSuccessStatusCode(statusCode: number | string): boolean {\n statusCode = Number(statusCode);\n return statusCode >= 200 && statusCode < 300;\n}\n", "import { merge } from 'lodash-es';\nimport assert from 'node:assert';\nimport type {\n OpenAPIObject,\n ReferenceObject,\n SchemaObject,\n} from 'openapi3-ts/oas31';\nimport { camelcase, snakecase } from 'stringcase';\n\nimport {\n cleanRef,\n followRef,\n isEmpty,\n isRef,\n notRef,\n parseRef,\n pascalcase,\n} from '@sdk-it/core';\n\nconst formatName = (it: any): string => {\n const startsWithDigitPattern = /^-?\\d/;\n // 1. Handle numbers\n if (typeof it === 'number') {\n if (Math.sign(it) === -1) {\n return `$_${Math.abs(it)}`;\n }\n return `$${it}`;\n }\n\n // 2. Handle the specific string 'default'\n if (it === 'default') {\n return '$default';\n }\n\n // 3. Handle other strings\n if (typeof it === 'string') {\n // 3a. Check if the string starts with a digit FIRST\n if (startsWithDigitPattern.test(it)) {\n if (typeof it === 'number') {\n if (Math.sign(it) === -1) {\n return `$_${Math.abs(it)}`;\n }\n return `$${it}`;\n }\n }\n\n // 3b. If not starting with a digit, handle brackets and snake_case\n let nameToFormat = it;\n\n // Remove a single leading '[' if present\n if (nameToFormat.startsWith('[')) {\n nameToFormat = nameToFormat.slice(1);\n }\n\n // Remove a single trailing ']' if present\n if (nameToFormat.endsWith(']')) {\n nameToFormat = nameToFormat.slice(0, -1);\n }\n\n // Apply snakecase to the (potentially modified) string\n return snakecase(nameToFormat);\n }\n\n // 4. Fallback for any other types (e.g., null, undefined, objects)\n // Convert to string first, then apply snakecase\n return snakecase(String(it));\n};\n\ntype Context = Record<string, any>;\ntype Serialized = {\n nullable?: boolean;\n encode?: string;\n use: string;\n toJson: string;\n matches?: string;\n fromJson: string;\n type?: string;\n content: string;\n simple?: boolean;\n};\ntype Emit = (name: string, content: string) => void;\n/**\n * Convert an OpenAPI (JSON Schema style) object into Dart classes\n */\nexport class DartSerializer {\n #spec: OpenAPIObject;\n #emit: Emit;\n\n constructor(spec: OpenAPIObject, emit: Emit) {\n this.#spec = spec;\n this.#emit = emit;\n }\n\n #getRefUsage(schemaName: string, list: string[] = []): string[] {\n this.#spec.components ??= {};\n this.#spec.components.schemas ??= {};\n this.#spec.components.responses ??= {};\n\n const checkSchema = (schema: SchemaObject | ReferenceObject): boolean => {\n if (isRef(schema)) {\n const { model } = parseRef(schema.$ref);\n return model === schemaName;\n }\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return (schema.oneOf as Array<SchemaObject | ReferenceObject>).some(\n (subSchema) => checkSchema(subSchema),\n );\n }\n if (\n schema.type === 'array' &&\n schema.items &&\n notRef(schema.items) &&\n schema.items.oneOf\n ) {\n return checkSchema(schema.items);\n }\n return false;\n };\n\n for (const [key, value] of Object.entries(this.#spec.components.schemas)) {\n if (checkSchema(value)) {\n list.push(key);\n }\n }\n\n return list;\n }\n\n #object(\n className: string,\n schema: SchemaObject,\n context: Context,\n ): Serialized {\n if (schema.additionalProperties) {\n this.#emit(className, `typedef ${className} = Map<String, dynamic>;`);\n return {\n content: '',\n use: 'Map<String, dynamic>',\n encode: 'input',\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${camelcase(context.name)}']`,\n matches: `json['${camelcase(context.name)}'] is Map<String, dynamic>`,\n };\n }\n if (isEmpty(schema.properties)) {\n if (context.noEmit !== true) {\n this.#emit(\n className,\n `class ${className} {\n const ${className}(); // Add const constructor\n\n factory ${className}.fromJson(Map<String, dynamic> json) {\n return const ${className}();\n }\n\n Map<String, dynamic> toJson() => {};\n\n /// Determines if a given map can be parsed into an instance of this class.\n /// Returns true for any map since this class has no properties.\n static bool matches(Map<String, dynamic> json) {\n return true; // Any map is fine for an empty object\n }\n}`,\n );\n }\n return {\n content: '',\n encode: 'input.toJson()',\n use: className,\n toJson: `${this.#safe(context.name as string, context.required)}`,\n fromJson: `${className}.fromJson(json['${context.name}'])`,\n matches: `${className}.matches(json['${context.name}'])`,\n };\n }\n\n const props: string[] = [];\n const toJsonProperties: string[] = [];\n const constructorParams: string[] = [];\n const fromJsonParams: string[] = [];\n const matches: string[] = [];\n\n for (const [key, propSchema] of Object.entries(schema.properties)) {\n const propName = key.replace('[]', '');\n const required = (schema.required ?? []).includes(key);\n const typeStr = this.handle(className, propSchema, required, {\n name: propName,\n required,\n propName: [className, propName].filter(Boolean).join('_'),\n });\n const nullable = typeStr.nullable || !required;\n const nullableSuffix = nullable ? '?' : '';\n props.push(\n `final ${typeStr.use}${nullableSuffix} ${camelcase(propName)};`,\n );\n fromJsonParams.push(`${camelcase(propName)}: ${typeStr.fromJson}`);\n toJsonProperties.push(`'${propName}': ${typeStr.toJson}`);\n constructorParams.push(\n `${required ? 'required ' : ''}this.${camelcase(propName)},`,\n );\n if (required) {\n matches.push(`(\n json.containsKey('${camelcase(propName)}')\n ? ${nullable ? `json['${propName}'] == null` : `json['${propName}'] != null`} ${typeStr.matches ? `&& ${typeStr.matches}` : ''}\n : false)`);\n } else {\n matches.push(`(\n json.containsKey('${camelcase(propName)}')\n ? ${nullable ? `json['${propName}'] == null` : `json['${propName}'] != null`} ${typeStr.matches ? `|| ${typeStr.matches}` : ''}\n : true)`);\n }\n }\n\n const { mixins, withMixins } = this.#mixinise(className, context);\n const content = `class ${className} ${withMixins} {\n ${props.join('\\n')}\n ${!mixins.length ? 'const' : ''} ${className}({\n ${constructorParams.join('\\n')}})${mixins.length > 1 ? '' : `:super()`};\n factory ${className}.fromJson(Map<String, dynamic> json) {\nreturn ${className}(\\n${fromJsonParams.join(',\\n')});\n }\n Map<String, dynamic> toJson() => {\n${toJsonProperties.join(',\\n')}\n };\n static bool matches(Map<String, dynamic> json) {\nreturn ${matches.join(' && ')};\n }\n }`;\n if (context.noEmit !== true) {\n this.#emit(className, content);\n }\n const nullable = !context.required || context.nullable === true;\n return {\n use: className,\n content,\n encode: 'input.toJson()',\n toJson: `${this.#safe(context.name, context.required)}`,\n fromJson: context.name\n ? `${context.forJson || className}.fromJson(json['${context.name}'])`\n : `${context.forJson || className}.fromJson(json)`,\n matches: `${className}.matches(json['${context.name}'])`,\n };\n }\n\n #safe(accces: string, required: boolean) {\n return required\n ? `this.${camelcase(accces)}.toJson()`\n : `this.${camelcase(accces)} != null ? this.${camelcase(accces)}!.toJson() : null`;\n }\n\n #array(\n className: string,\n schema: SchemaObject,\n required = false,\n context: Context,\n ): Serialized {\n if (!schema.items) {\n return {\n content: '',\n use: 'List<dynamic>',\n toJson: '',\n fromJson: `List<dynamic>.from(${context.name ? `json['${context.name}']` : `json`})})`,\n matches: '',\n };\n }\n const itemsType = this.handle(className, schema.items, true, context);\n const fromJson = required\n ? context.name\n ? `(json['${context.name}'] as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()`\n : `(json as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()`\n : context.name\n ? `json['${context.name}'] != null\n ? (json['${context.name}'] as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()\n : null`\n : `json != null\n ? (json as List<${itemsType.simple ? itemsType.use : 'dynamic'}>)\n .map((it) => ${itemsType.simple ? 'it' : `${itemsType.use}.fromJson(it)`})\n .toList()\n : null`;\n\n return {\n encode: `input.map((it) => ${itemsType.simple ? 'it' : `it.toJson()`}).toList()`,\n content: '',\n use: `List<${itemsType.use}>`,\n fromJson,\n toJson: `${context.required ? `this.${camelcase(context.name)}${itemsType.simple ? '' : '.map((it) => it.toJson()).toList()'}` : `this.${camelcase(context.name)}!= null? this.${camelcase(context.name)}${itemsType.simple ? '' : '!.map((it) => it.toJson()).toList()'} : null`}`,\n matches: `json['${camelcase(context.name)}'].every((it) => ${itemsType.matches})`,\n };\n }\n\n /**\n * Convert a basic type to Dart\n */\n #primitive(\n className: string,\n type: string,\n schema: SchemaObject,\n context: Record<string, unknown>,\n required = false,\n ): Serialized {\n switch (type) {\n case 'string':\n return this.#string(schema, context);\n case 'number':\n case 'integer':\n return this.number(schema, context);\n case 'boolean':\n return {\n content: '',\n use: 'bool',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is bool`,\n };\n case 'object':\n return this.#object(className, schema, context);\n case 'array':\n return this.#array(className, schema, required, context);\n case 'null':\n return {\n content: '',\n use: 'Null',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n default:\n // Unknown type -> fallback\n return {\n content: '',\n use: 'dynamic',\n nullable: false,\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n }\n }\n\n #ref(\n className: string,\n $ref: string,\n required: boolean,\n context: Context,\n ): Serialized {\n const schemaName = cleanRef($ref).split('/').pop()!;\n\n const serialized = this.handle(\n schemaName,\n followRef<SchemaObject>(this.#spec, $ref),\n required,\n {\n ...context,\n propName: schemaName,\n noEmit: !!context.alias || !!className || !context.forceEmit,\n },\n );\n return serialized;\n }\n\n // fixme: this method should no longer be needed because the logic in it is being preprocessed before emitting begins\n #allOf(\n className: string,\n schemas: (SchemaObject | ReferenceObject)[],\n context: Context,\n ): Serialized {\n const name = pascalcase(context.propName || className); // className in case is top level\n\n const refs = schemas.filter(isRef);\n const nonRefs = schemas.filter(notRef);\n if (nonRefs.some((it) => it.type && it.type !== 'object')) {\n assert(false, `allOf ${name} must be an object`);\n }\n const objectSchema = merge(\n {},\n ...nonRefs,\n ...refs.map((ref) => followRef(this.#spec, ref.$ref)),\n );\n delete objectSchema.allOf;\n return this.handle(name, objectSchema, true, context);\n }\n\n #anyOf(\n className: string,\n schemas: (SchemaObject | ReferenceObject)[],\n context: Record<string, unknown>,\n ): Serialized {\n // fixme: handle\n if (schemas.length === 0) {\n return {\n content: '',\n nullable: false,\n use: 'dynamic',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n }\n const nullSchemaIndex = schemas.findIndex((schema) => {\n if (isRef(schema)) {\n const refSchema = followRef(this.#spec, schema.$ref);\n return refSchema.type === 'null';\n }\n return schema.type === 'null';\n });\n const anyOfSchemas = schemas.slice(0);\n if (nullSchemaIndex >= 0) {\n anyOfSchemas.splice(nullSchemaIndex, 1); // remove null schema\n }\n\n return this.handle(className, anyOfSchemas[0], true, {\n ...context,\n nullable: nullSchemaIndex >= 0,\n });\n }\n\n #mixinise(name: string, context: Context) {\n const mixins = this.#getRefUsage(name);\n if (context.mixin) {\n mixins.unshift(context.mixin);\n }\n const withMixins =\n mixins.length > 1\n ? ` with ${mixins.join(', ')}`\n : mixins.length === 1\n ? `extends ${mixins[0]}`\n : '';\n return {\n withMixins,\n mixins,\n };\n }\n\n #oneOf(\n className: string,\n schemas: (SchemaObject | ReferenceObject)[],\n context: Context,\n ): Serialized {\n const name = pascalcase(context.propName || className); // className in case is top level\n\n if (schemas.length === 0) {\n return {\n content: '',\n nullable: false,\n use: 'dynamic',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n };\n }\n const content: string[] = [];\n const patterns: { pattern: string; name: string }[] = [];\n // FIXME: if there is just one type then no need to add the discriminator\n const objects = schemas.filter(notRef).filter((it) => it.type === 'object');\n for (const schema of schemas) {\n if (isRef(schema)) {\n const refType = this.#ref(className, schema.$ref, true, context);\n patterns.push({\n pattern: `case ${refType.type || 'Map<String, dynamic>'} map when ${refType.use}.matches(map): return ${refType.use}.fromJson(map);`,\n name: refType.use,\n });\n } else if (schema.type === 'string') {\n // todo: make this into a schema with ref (preproccesing)\n content.push(`class ${name}Text with ${name} {\n final String value;\n ${name}Text(this.value);\n @override\n dynamic toJson() => value;\n static bool matches(dynamic value) {\n return value is String;\n }}\n `);\n patterns.push({\n pattern: `case String(): return ${name}Text(json);`,\n name: `${name}Text`,\n });\n } else if (schema.type === 'array') {\n // todo: make this into a schema with ref (preproccesing) with all varients types (integer, string)\n // todo: this can be abstracted so the varients somehow dynamic without having to replicate the same classes all the time\n const itemsType = this.handle(name, schema.items!, true, {\n ...context,\n noEmit: true,\n });\n content.push(`class ${name}List with ${name} {\n final List<${itemsType.use}> value;\n ${name}List(this.value);\n @override\n dynamic toJson() => value;\n static bool matches(dynamic value) {\n return value is List;\n }}`);\n patterns.push({\n pattern: `case List(): return ${name}List(List<${itemsType.use}>.from(json));`,\n name: `${name}List`,\n });\n }\n }\n if (objects.length) {\n // todo: take a look at CompoundFilterFilters at the end\n const candidates: Record<string, Set<string>> = {};\n for (const schema of objects) {\n if (schema.additionalProperties === true) {\n continue;\n }\n assert(\n schema.properties,\n `Schema ${name} has no properties which are required in oneOf in order to determine the discriminator.`,\n );\n for (const [propName, propSchema] of Object.entries(\n schema.properties,\n )) {\n if (\n notRef(propSchema) &&\n propSchema.enum &&\n // fixme: the enum can have more than one value as long as it is not duplicated else where on the other schemas\n propSchema.enum.length === 1\n ) {\n candidates[propName] ??= new Set();\n candidates[propName].add(String(propSchema.enum[0]));\n }\n }\n }\n\n let discriminatorProp: string | undefined;\n\n for (const [name, values] of Object.entries(candidates)) {\n if (\n // make sure we pick the prop that exists on all objects\n values.size === objects.filter((it) => it.properties?.[name]).length\n ) {\n discriminatorProp = name;\n break;\n }\n }\n\n // if (objects.filter((it) => it.additionalProperties !== true).length) {\n // }\n // assert(discriminatorProp, `No discriminator property found in ${name}`);\n\n if (discriminatorProp) {\n for (const schema of objects) {\n const discriminatorValue: string = (\n (schema as SchemaObject).properties![\n discriminatorProp!\n ] as SchemaObject\n ).enum?.[0];\n\n const varientName = `${name}${pascalcase(discriminatorValue)}`;\n patterns.push({\n pattern: `case Map<String, dynamic> map when ${varientName}.matches(json): return ${varientName}.fromJson(map);`,\n name: varientName,\n });\n\n const objResult = this.#object(varientName, schema, {\n ...context,\n noEmit: true,\n mixin: name,\n });\n content.push(objResult.content);\n }\n }\n }\n\n const { mixins, withMixins } = this.#mixinise(name, context);\n content.unshift(`abstract ${mixins.length ? '' : 'mixin'} class ${name} ${withMixins} {\n dynamic toJson();\n ${\n patterns.length\n ? `static ${name} fromJson(dynamic json) {\n switch (json){\n ${patterns.map((it) => it.pattern).join('\\n')}\n default:\n throw ArgumentError(\"Invalid type for query property: \\${json}\");\n }\n }\n\n\n ${\n patterns.length\n ? ` static bool matches(dynamic value) {\n return ${patterns.map((it) => `value is ${it.name}`).join(' || ')};\n }`\n : ''\n }\n\n `\n : ''\n }\n }`);\n this.#emit(name, content.join('\\n'));\n\n return {\n content: content.join('\\n'),\n use: name,\n toJson: `${this.#safe(context.name as string, context.required)}`,\n fromJson: `${name}.fromJson(json['${context.name}'])`,\n matches: `${name}.matches(json['${context.name}'])`,\n };\n }\n\n #simple(type: string) {\n switch (type) {\n case 'string':\n return 'String';\n case 'number':\n return 'double';\n case 'integer':\n return 'int';\n case 'boolean':\n return 'bool';\n default:\n return 'dynamic';\n }\n }\n\n #enum(className: string, schema: SchemaObject, context: Context): Serialized {\n const name = context.propName || className; // className in case enum is top level\n const values = schema.enum as string[];\n const valType = this.#simple((schema.type as string) || 'string');\n // fixme: if enum have one value and cannot be null then use it as default value\n\n const { mixins, withMixins } = this.#mixinise(className, context);\n\n const content = `\n class _EnumValue implements ${pascalcase(name)} {\n final ${valType} value;\n const _EnumValue(this.value);\n @override\n toJson() {return this.value;}\n}\n abstract ${mixins.length ? '' : 'mixin'} class ${pascalcase(name)} ${withMixins} {\n ${values.map((it) => `static const _EnumValue ${formatName(it)} = _EnumValue(${typeof it === 'number' ? it : `'${it}'`});`).join('\\n')}\n dynamic toJson();\n\n ${valType} get value;\n\n static _EnumValue fromJson(${valType} value) {\n switch (value) {\n${values\n .map(\n (it) =>\n `case ${typeof it === 'number' ? it : `'${it}'`}: return ${formatName(it)};`,\n )\n .join('\\n')}\ndefault:\n throw ArgumentError.value(value, \"value\", \"No enum value with that name\");\n }\n }\n\n static bool matches(${valType} value) {\n try {\nfromJson(value);\nreturn true;\n } catch (error) {\nreturn false;\n }\n }\n\n }`;\n if (context.noEmit !== true) {\n this.#emit(name, content);\n }\n return {\n type: Array.isArray(schema.type)\n ? this.#simple(schema.type[0])\n : schema.type\n ? this.#simple(schema.type)\n : undefined,\n content: content,\n use: pascalcase(name),\n toJson: `${context.required ? `this.${camelcase(context.name)}.toJson()` : `this.${camelcase(context.name)} != null ? this.${camelcase(context.name)}!.toJson() : null`}`,\n fromJson: `${pascalcase(name)}.fromJson(json['${context.name}'])`,\n matches: `${pascalcase(name)}.matches(json['${context.name}'])`,\n };\n }\n\n /**\n * Handle string type with formats\n */\n #string(schema: SchemaObject, context: Context): Serialized {\n switch (schema.format) {\n case 'date-time':\n case 'datetime':\n case 'date':\n return {\n content: '',\n use: 'DateTime',\n simple: true,\n toJson: context.required\n ? `this.${camelcase(context.name)}.toIso8601String()`\n : `this.${camelcase(context.name)} != null ? this.${camelcase(\n context.name,\n )}!.toIso8601String() : null`,\n fromJson: context.name\n ? `json['${context.name}'] != null ? DateTime.parse(json['${context.name}']) : null`\n : 'json',\n matches: `json['${context.name}'] is String`,\n };\n case 'binary':\n case 'byte':\n return {\n content: '',\n use: 'File',\n toJson: `this.${camelcase(context.name)}`,\n simple: true,\n fromJson: context.name ? `json['${context.name}']` : 'json',\n matches: `json['${context.name}'] is Uint8List`,\n };\n default:\n return {\n encode: 'input',\n use: `String`,\n content: '',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: context.name ? `json['${context.name}'] as String` : 'json',\n matches: `json['${context.name}'] is String`,\n };\n }\n }\n\n /**\n * Handle number/integer types with formats\n */\n number(schema: SchemaObject, context: Context): Serialized {\n if (schema.type === 'integer') {\n return {\n content: '',\n use: 'int',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is int`,\n };\n }\n if (['float', 'double'].includes(schema.format as string)) {\n return {\n content: '',\n use: 'double',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is double`,\n };\n }\n return {\n content: '',\n use: 'num',\n simple: true,\n toJson: `this.${camelcase(context.name)}`,\n fromJson: `json['${context.name}']`,\n matches: `json['${context.name}'] is double`,\n };\n }\n\n #serialize(\n className: string,\n schema: SchemaObject | ReferenceObject,\n required = true,\n context: Context = {},\n ): Serialized {\n if (isRef(schema)) {\n return this.#ref(className, schema.$ref, required, context);\n }\n // some schemas have decalres allof, oneof, anyOf at once or combinations of them\n // so we need to process them in order\n if (schema.allOf && Array.isArray(schema.allOf)) {\n return this.#allOf(className, schema.allOf, context);\n }\n if (schema.oneOf && Array.isArray(schema.oneOf)) {\n return this.#oneOf(className, schema.oneOf, context);\n }\n if (schema.anyOf && Array.isArray(schema.anyOf)) {\n return this.#anyOf(className, schema.anyOf, context);\n }\n if (schema.enum && Array.isArray(schema.enum)) {\n return this.#enum(className, schema, context);\n }\n // Handle types\n const types = Array.isArray(schema.type)\n ? schema.type\n : schema.type\n ? [schema.type]\n : [];\n\n let nullable = false;\n if ('nullable' in schema && schema.nullable) {\n nullable = true;\n } else if (schema.default === null) {\n nullable = true;\n } else if (types.includes('null')) {\n nullable = true;\n }\n\n // If no explicit \"type\", fallback to dynamic\n if (!types.length) {\n // unless properties are defined then assume object\n if ('properties' in schema) {\n return this.#object(className, schema, context);\n }\n if ('items' in schema) {\n return this.#array(className, schema, true, context);\n }\n return {\n content: '',\n use: 'dynamic',\n toJson: `${camelcase(context.name as string)}`,\n fromJson: `json['${context.name}']`,\n nullable: false,\n matches: '', // keep it empty as 'type is dynamic' is always true\n };\n }\n return this.#primitive(\n className,\n types[0],\n schema,\n { ...context, nullable },\n required,\n );\n }\n\n handle(\n className: string,\n schema: SchemaObject | ReferenceObject,\n required = true,\n context: Context = {},\n ): Serialized {\n const alias = context.alias;\n context.alias = undefined;\n const serialized = this.#serialize(className, schema, required, {\n ...context,\n forJson: alias,\n });\n\n if (alias) {\n this.#emit(className, `typedef ${alias} = ${serialized.use};`);\n return serialized;\n }\n return serialized;\n }\n}\n\nexport function isObjectSchema(\n schema: SchemaObject | ReferenceObject,\n): schema is SchemaObject {\n return !isRef(schema) && (schema.type === 'object' || !!schema.properties);\n}\n", "import 'dart:convert';\nimport 'dart:io';\n\nimport 'package:http/http.dart' as http;\nimport 'package:http_parser/http_parser.dart';\nimport 'package:mime/mime.dart' as mime;\n\nimport './interceptors.dart';\nimport './responses.dart';\n\nclass Dispatcher {\n final List<Interceptor> interceptors;\n\n Dispatcher(this.interceptors);\n\n Future<http.StreamedResponse> multipart(\n RequestConfig config,\n Map<String, dynamic> body,\n ) async {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.MultipartRequest(\n modifiedConfig.method,\n modifiedConfig.url,\n );\n request.headers.addAll(modifiedConfig.headers);\n for (var entry in body.entries) {\n final key = entry.key;\n final value = entry.value;\n if (value is File) {\n final mimeType = mime.lookupMimeType(value.path);\n request.files.add(\n http.MultipartFile(\n key,\n value.openRead(),\n await value.length(),\n filename: value.uri.pathSegments.last,\n contentType: mimeType != null ? MediaType.parse(mimeType) : null,\n ),\n );\n } else {\n request.fields[key] = value.toString();\n }\n }\n\n return request.send();\n }\n\n Future<http.StreamedResponse> empty(RequestConfig config) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n return request.send();\n }\n\n Future<http.StreamedResponse> json(RequestConfig config, dynamic body) {\n final modifiedConfig = interceptors.fold(\n config,\n (acc, interceptor) => interceptor.before(acc),\n );\n final request = http.Request(modifiedConfig.method, modifiedConfig.url);\n request.headers.addAll(modifiedConfig.headers);\n\n request.headers['Content-Type'] = 'application/json';\n if ((body is Map || body is List)) {\n request.body = jsonEncode(body);\n } else if (body is String) {\n request.body = body;\n } else {\n throw ArgumentError('Unsupported body type: ${body.runtimeType}');\n }\n\n return request.send();\n }\n}\n\nclass Receiver {\n final List<Interceptor> interceptors;\n Receiver(this.interceptors);\n\n dynamic _parse(http.Response response) {\n final contentTypeHeader = response.headers['content-type'];\n final parsed = parseContentType(contentTypeHeader);\n if (parsed.type == 'application/json') {\n return jsonDecode(response.body);\n } else if (parsed.type == 'text/plain') {\n return response.body;\n } else if (parsed.type == 'application/octet-stream') {\n return response.bodyBytes;\n } else {\n throw UnsupportedError('Unsupported content type: ${parsed.type}');\n }\n }\n\n dynamic json(http.StreamedResponse stream) async {\n if (stream.statusCode >= 200 && stream.statusCode < 300) {\n final response = await http.Response.fromStream(stream);\n return _parse(response);\n }\n switch (stream.statusCode) {\n case 400:\n throw BadRequestError('');\n case 401:\n throw UnauthorizedError('');\n case 403:\n throw ForbiddenError('');\n case 404:\n throw NotFoundError('');\n case 500:\n throw InternalServerError('');\n case 402:\n throw PaymentRequiredError('');\n case 405:\n throw MethodNotAllowedError('');\n case 406:\n throw NotAcceptableError('');\n case 409:\n throw ConflictError('');\n case 410:\n throw GoneError('');\n case 422:\n throw UnprocessableEntityError('');\n case 429:\n throw TooManyRequestsError('');\n case 413:\n throw PayloadTooLargeError('');\n case 415:\n throw UnsupportedMediaTypeError('');\n case 501:\n throw NotImplementedError('');\n case 502:\n throw BadGatewayError('');\n case 503:\n throw ServiceUnavailableError('');\n case 504:\n throw GatewayTimeoutError('');\n default:\n throw UnknownApiError('', stream.statusCode);\n }\n }\n}\n\n({String type, Map<String, String> parameters}) parseContentType(\n String? contentTypeHeader,\n) {\n if (contentTypeHeader == null || contentTypeHeader.isEmpty) {\n return (type: '', parameters: {});\n }\n final parts = contentTypeHeader.split(';');\n final type = parts[0].trim();\n final parameters = <String, String>{};\n for (var i = 1; i < parts.length; i++) {\n final param = parts[i].split('=');\n if (param.length == 2) {\n parameters[param[0].trim()] = param[1].trim();\n }\n }\n\n return (type: type, parameters: parameters);\n}\n", "abstract class Interceptor {\n RequestConfig before(RequestConfig config);\n void after();\n}\n\nclass BaseUrlInterceptor extends Interceptor {\n final String Function() getBaseUrl;\n BaseUrlInterceptor(this.getBaseUrl);\n\n @override\n RequestConfig before(RequestConfig config) {\n final baseUrl = getBaseUrl();\n if (config.url.scheme.isEmpty) {\n config.url = Uri.parse(baseUrl + config.url.toString());\n }\n return config;\n }\n\n @override\n void after() {\n //\n }\n}\n\nclass RequestConfig {\n final String method;\n Uri url;\n final Map<String, String> headers;\n RequestConfig({required this.method, required this.url, required this.headers});\n}\n", "sealed class ApiError {\n final String message;\n final int? statusCode;\n final String status;\n const ApiError(this.message, {this.statusCode, this.status = ''});\n\n @override\n String toString() =>\n 'ApiError(status: $status, statusCode: $statusCode, message: $message)';\n}\n\nbase class BadRequestError extends ApiError {\n const BadRequestError(String message)\n : super(message, statusCode: 400, status: 'BadRequest');\n}\n\nbase class UnauthorizedError extends ApiError {\n const UnauthorizedError(String message)\n : super(message, statusCode: 401, status: 'Unauthorized');\n}\n\nbase class ForbiddenError extends ApiError {\n const ForbiddenError(String message)\n : super(message, statusCode: 403, status: 'Forbidden');\n}\n\nbase class NotFoundError extends ApiError {\n const NotFoundError(String message)\n : super(message, statusCode: 404, status: 'NotFound');\n}\n\nbase class InternalServerError extends ApiError {\n const InternalServerError(String message)\n : super(message, statusCode: 500, status: 'InternalServerError');\n}\n\nbase class UnknownApiError extends ApiError {\n const UnknownApiError(String message, int statusCode)\n : super(message, statusCode: statusCode, status: 'UnknownApiError');\n}\n\nbase class PaymentRequiredError extends ApiError {\n const PaymentRequiredError(String message)\n : super(message, statusCode: 402, status: 'PaymentRequired');\n}\n\nbase class MethodNotAllowedError extends ApiError {\n const MethodNotAllowedError(String message)\n : super(message, statusCode: 405, status: 'MethodNotAllowed');\n}\n\nbase class NotAcceptableError extends ApiError {\n const NotAcceptableError(String message)\n : super(message, statusCode: 406, status: 'NotAcceptable');\n}\n\nbase class ConflictError extends ApiError {\n const ConflictError(String message)\n : super(message, statusCode: 409, status: 'Conflict');\n}\n\nbase class GoneError extends ApiError {\n const GoneError(String message)\n : super(message, statusCode: 410, status: 'Gone');\n}\n\nbase class UnprocessableEntityError extends ApiError {\n const UnprocessableEntityError(String message)\n : super(message, statusCode: 422, status: 'UnprocessableEntity');\n}\n\nbase class TooManyRequestsError extends ApiError {\n const TooManyRequestsError(String message)\n : super(message, statusCode: 429, status: 'TooManyRequests');\n}\n\nbase class PayloadTooLargeError extends ApiError {\n const PayloadTooLargeError(String message)\n : super(message, statusCode: 413, status: 'PayloadTooLarge');\n}\n\nbase class UnsupportedMediaTypeError extends ApiError {\n const UnsupportedMediaTypeError(String message)\n : super(message, statusCode: 415, status: 'UnsupportedMediaType');\n}\n\nbase class NotImplementedError extends ApiError {\n const NotImplementedError(String message)\n : super(message, statusCode: 501, status: 'NotImplemented');\n}\n\nbase class BadGatewayError extends ApiError {\n const BadGatewayError(String message)\n : super(message, statusCode: 502, status: 'BadGateway');\n}\n\nbase class ServiceUnavailableError extends ApiError {\n const ServiceUnavailableError(String message)\n : super(message, statusCode: 503, status: 'ServiceUnavailable');\n}\n\nbase class GatewayTimeoutError extends ApiError {\n const GatewayTimeoutError(String message)\n : super(message, statusCode: 504, status: 'GatewayTimeout');\n}\n"],
|
|
5
|
+
"mappings": "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;AACH,YAAM,oBAAoB,OAAO,eAAe,SAAS;AACzD,YAAM,YAAY,OAAO,OAAO,SAAS;AACzC,YAAM,gBAAgB,kBAAkB,WAAW,WAAW,MAAM;AACpE,YAAM,eAAe,UAAU,WAAW,SAAS;AACnD,YAAM,WAAW,UAAU,WAAW,KAAK,CAAC;AAC5C,aAAO;QACL;UACE;YACE,MAAM,SAAS;YACf;YACA,MAAM;YACN,WAAW;YACX,KAAK;UACP;UACA;YACE,GAAG;YACH,YAAY,CAAC,GAAG,YAAY,GAAI,UAAU,cAAc,CAAC,CAAE;YAC3D,aAAa;UACf;QACF;MACF;IACF;EACF;AACA,SAAO;AACT;AAgBA,IAAM,mBAAmB,oBAAI,IAAI;EAC/B;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACF,CAAC;AAUD,SAAS,YAAY,eAA+B;AAElD,MAAI,MAAM,KAAK,aAAa,GAAG;AAC7B,WAAO,IAAI,aAAa;EAC1B;AAEA,SAAO,iBAAiB,IAAI,aAAa,IACrC,GAAG,aAAa,MAChB;AACN;AASO,SAAS,oBACd,YACA,WACQ;AACR,QAAM,cAAc,UAAU,eAAe;AAC7C,QAAM,gBAAgB;AACtB,QAAM,cAAc,oBAAI,IAAI;;IAE1B;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EACF,CAAC;AAED,QAAM,WAAW,WAAW,MAAM,GAAG,EAAE,OAAO,OAAO;AAErD,QAAM,sBAAsB,SAAS;IACnC,CAAC,YACC,WACA,CAAC,QAAQ,WAAW,GAAG,KACvB,CAAC,QAAQ,SAAS,GAAG,KACrB,CAAC,cAAc,KAAK,OAAO;EAC/B;AAGA,WAAS,IAAI,oBAAoB,SAAS,GAAG,KAAK,GAAG,KAAK;AACxD,UAAM,UAAU,oBAAoB,CAAC;AACrC,QAAI,CAAC,QAAQ,WAAW,GAAG,GAAG;AAE5B,aAAO,YAAY,UAAU,OAAO,CAAC;IACvC;EACF;AAEA,QAAM,2BAA2B,oBAAoB,SAAS;AAG9D,MAAI,aAAa;AACf,UAAM,YAAY,YAAY,YAAY;AAC1C,UAAM,QAAQ,YACX,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,wBAAwB,OAAO,EACvC,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,mBAAmB,OAAO,EAClC,YAAY,EACZ,MAAM,SAAS;AAElB,UAAM,aAAa,MAAM,OAAO,OAAO;AAGvC,QACE,YAAY,IAAI,SAAS,KACzB,WAAW,WAAW,KACtB,0BACA;IAEF,WAES,WAAW,SAAS,GAAG;AAC9B,YAAM,YAAY,WAAW,CAAC;AAC9B,YAAM,kBAAkB,YAAY,IAAI,SAAS;AAGjD,UAAI,mBAAmB,WAAW,SAAS,GAAG;AAC5C,cAAM,mBAAmB,UAAU;AACnC,YAAI,qBAAqB;AACzB,YAAI,YAAY,SAAS,kBAAkB;AAEzC,gBAAM,kBAAkB,YAAY,gBAAgB;AACpD,cAAI,mBAAmB,OAAO,mBAAmB,KAAK;AACpD,iCAAqB;UACvB,WAAW,mBAAmB,OAAO,mBAAmB,KAAK;AAC3D,iCAAqB;UACvB,WAAW,CAAC,KAAK,GAAG,EAAE,SAAS,eAAe,GAAG;AAC/C,iCAAqB,mBAAmB;UAC1C,OAAO;AACL,kBAAM,QAAQ,YACX,UAAU,gBAAgB,EAC1B,MAAM,UAAU;AACnB,gBAAI,SAAS,MAAM,UAAU,QAAW;AACtC,mCAAqB,mBAAmB,MAAM;YAChD;AACA,gBACE,uBAAuB,MACvB,YAAY,SAAS,kBACrB;AACA,mCAAqB;YACvB;UACF;QACF;AAEA,YACE,uBAAuB,MACvB,qBAAqB,YAAY,QACjC;AACA,gBAAM,6BACJ,YAAY,UAAU,kBAAkB;AAC1C,gBAAM,eAAe,UAAU,0BAA0B;AACzD,cAAI,cAAc;AAEhB,mBAAO,YAAY,YAAY;UACjC;QACF;AAGA,cAAM,qBAAqB,UAAU,WAAW,MAAM,CAAC,EAAE,KAAK,GAAG,CAAC;AAClE,YAAI,oBAAoB;AAEtB,iBAAO,YAAY,kBAAkB;QACvC;MACF;AAGA,YAAM,mBAAmB,UAAU,WAAW;AAC9C,UAAI,kBAAkB;AACpB,cAAM,qBAAqB,WAAW,WAAW,KAAK;AAGtD,YAAI,EAAE,sBAAsB,2BAA2B;AACrD,cAAI,iBAAiB,SAAS,GAAG;AAE/B,mBAAO,YAAY,gBAAgB;UACrC;QACF;MACF;AAGA,YAAM,iBAAiB,UAAU,SAAS;AAC1C,UAAI,gBAAgB;AAClB,cAAM,uBAAuB,YAAY,IAAI,cAAc;AAC3D,YACE,CAAC,wBACD,WAAW,WAAW,KACtB,CAAC,0BACD;AAEA,iBAAO,YAAY,cAAc;QACnC;MACF;AACA,UACE,mBACA,WAAW,SAAS,KACpB,WAAW,CAAC,KACZ,0BACA;AACA,cAAM,kBAAkB,UAAU,WAAW,CAAC,CAAC;AAC/C,YAAI,iBAAiB;AAEnB,iBAAO,YAAY,eAAe;QACpC;MACF;IACF;EACF;AAGA,MAAI,oBAAoB,SAAS,GAAG;AAClC,QAAI,iBAAiB,oBAAoB,CAAC;AAC1C,QAAI,eAAe,WAAW,GAAG,GAAG;AAClC,uBAAiB,eAAe,UAAU,CAAC;IAC7C;AACA,QAAI,gBAAgB;AAElB,aAAO,YAAY,UAAU,cAAc,CAAC;IAC9C;EACF;AAGA,UAAQ;IACN,gDAAgD,UAAU,kBAAkB,WAAW;EACzF;AACA,SAAO;AACT;AAEO,SAAS,qBAAqB,aAAwC;AAC3E,MAAI,CAAC,aAAa;AAChB,WAAO;EACT;AAGA,MAAI,WAAW,YAAY,KAAK;AAGhC,QAAM,iBAAiB,SAAS,QAAQ,GAAG;AAC3C,MAAI,mBAAmB,IAAI;AACzB,eAAW,SAAS,UAAU,GAAG,cAAc,EAAE,KAAK;EACxD;AAGA,aAAW,SAAS,YAAY;AAEhC,MAAI,SAAS,SAAS,OAAO,GAAG;AAC9B,WAAO,SAAS,MAAM,GAAG,EAAE,CAAC;EAC9B,WAAW,SAAS,SAAS,OAAO,GAAG;AACrC,WAAO,SAAS,MAAM,GAAG,EAAE,CAAC;EAC9B;AACA,SAAO;AACT;AAiCO,SAAS,uBACd,aACS;AACT,SAAO,gBAAgB;AACzB;AAEO,SAAS,oBAAoB,YAAsC;AACxE,eAAa,OAAO,UAAU;AAC9B,SAAO,cAAc,OAAO,aAAa;AAC3C;;;ACrdA,SAAS,aAAa;AACtB,OAAO,YAAY;AAMnB,SAAS,aAAAC,YAAW,aAAAC,kBAAiB;AAYrC,IAAM,aAAa,CAAC,OAAoB;AACtC,QAAM,yBAAyB;AAE/B,MAAI,OAAO,OAAO,UAAU;AAC1B,QAAI,KAAK,KAAK,EAAE,MAAM,IAAI;AACxB,aAAO,KAAK,KAAK,IAAI,EAAE,CAAC;AAAA,IAC1B;AACA,WAAO,IAAI,EAAE;AAAA,EACf;AAGA,MAAI,OAAO,WAAW;AACpB,WAAO;AAAA,EACT;AAGA,MAAI,OAAO,OAAO,UAAU;AAE1B,QAAI,uBAAuB,KAAK,EAAE,GAAG;AACnC,UAAI,OAAO,OAAO,UAAU;AAC1B,YAAI,KAAK,KAAK,EAAE,MAAM,IAAI;AACxB,iBAAO,KAAK,KAAK,IAAI,EAAE,CAAC;AAAA,QAC1B;AACA,eAAO,IAAI,EAAE;AAAA,MACf;AAAA,IACF;AAGA,QAAI,eAAe;AAGnB,QAAI,aAAa,WAAW,GAAG,GAAG;AAChC,qBAAe,aAAa,MAAM,CAAC;AAAA,IACrC;AAGA,QAAI,aAAa,SAAS,GAAG,GAAG;AAC9B,qBAAe,aAAa,MAAM,GAAG,EAAE;AAAA,IACzC;AAGA,WAAOC,WAAU,YAAY;AAAA,EAC/B;AAIA,SAAOA,WAAU,OAAO,EAAE,CAAC;AAC7B;AAkBO,IAAM,iBAAN,MAAqB;AAAA,EAC1B;AAAA,EACA;AAAA,EAEA,YAAY,MAAqB,MAAY;AAC3C,SAAK,QAAQ;AACb,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,aAAa,YAAoB,OAAiB,CAAC,GAAa;AAC9D,SAAK,MAAM,eAAe,CAAC;AAC3B,SAAK,MAAM,WAAW,YAAY,CAAC;AACnC,SAAK,MAAM,WAAW,cAAc,CAAC;AAErC,UAAM,cAAc,CAAC,WAAoD;AACvE,UAAI,MAAM,MAAM,GAAG;AACjB,cAAM,EAAE,MAAM,IAAI,SAAS,OAAO,IAAI;AACtC,eAAO,UAAU;AAAA,MACnB;AACA,UAAI,OAAO,SAAS,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/C,eAAQ,OAAO,MAAgD;AAAA,UAC7D,CAAC,cAAc,YAAY,SAAS;AAAA,QACtC;AAAA,MACF;AACA,UACE,OAAO,SAAS,WAChB,OAAO,SACP,OAAO,OAAO,KAAK,KACnB,OAAO,MAAM,OACb;AACA,eAAO,YAAY,OAAO,KAAK;AAAA,MACjC;AACA,aAAO;AAAA,IACT;AAEA,eAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,MAAM,WAAW,OAAO,GAAG;AACxE,UAAI,YAAY,KAAK,GAAG;AACtB,aAAK,KAAK,GAAG;AAAA,MACf;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEA,QACE,WACA,QACA,SACY;AACZ,QAAI,OAAO,sBAAsB;AAC/B,WAAK,MAAM,WAAW,WAAW,SAAS,0BAA0B;AACpE,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,QAAQC,WAAU,QAAQ,IAAI,CAAC;AAAA,QACvC,UAAU,SAASA,WAAU,QAAQ,IAAI,CAAC;AAAA,QAC1C,SAAS,SAASA,WAAU,QAAQ,IAAI,CAAC;AAAA,MAC3C;AAAA,IACF;AACA,QAAI,QAAQ,OAAO,UAAU,GAAG;AAC9B,UAAI,QAAQ,WAAW,MAAM;AAC3B,aAAK;AAAA,UACH;AAAA,UACA,SAAS,SAAS;AAAA,UAClB,SAAS;AAAA;AAAA,YAEP,SAAS;AAAA,mBACF,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAWpB;AAAA,MACF;AACA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,KAAK;AAAA,QACL,QAAQ,GAAG,KAAK,MAAM,QAAQ,MAAgB,QAAQ,QAAQ,CAAC;AAAA,QAC/D,UAAU,GAAG,SAAS,mBAAmB,QAAQ,IAAI;AAAA,QACrD,SAAS,GAAG,SAAS,kBAAkB,QAAQ,IAAI;AAAA,MACrD;AAAA,IACF;AAEA,UAAM,QAAkB,CAAC;AACzB,UAAM,mBAA6B,CAAC;AACpC,UAAM,oBAA8B,CAAC;AACrC,UAAM,iBAA2B,CAAC;AAClC,UAAM,UAAoB,CAAC;AAE3B,eAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,OAAO,UAAU,GAAG;AACjE,YAAM,WAAW,IAAI,QAAQ,MAAM,EAAE;AACrC,YAAM,YAAY,OAAO,YAAY,CAAC,GAAG,SAAS,GAAG;AACrD,YAAM,UAAU,KAAK,OAAO,WAAW,YAAY,UAAU;AAAA,QAC3D,MAAM;AAAA,QACN;AAAA,QACA,UAAU,CAAC,WAAW,QAAQ,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,MAC1D,CAAC;AACD,YAAMC,YAAW,QAAQ,YAAY,CAAC;AACtC,YAAM,iBAAiBA,YAAW,MAAM;AACxC,YAAM;AAAA,QACJ,SAAS,QAAQ,GAAG,GAAG,cAAc,IAAID,WAAU,QAAQ,CAAC;AAAA,MAC9D;AACA,qBAAe,KAAK,GAAGA,WAAU,QAAQ,CAAC,KAAK,QAAQ,QAAQ,EAAE;AACjE,uBAAiB,KAAK,IAAI,QAAQ,MAAM,QAAQ,MAAM,EAAE;AACxD,wBAAkB;AAAA,QAChB,GAAG,WAAW,cAAc,EAAE,QAAQA,WAAU,QAAQ,CAAC;AAAA,MAC3D;AACA,UAAI,UAAU;AACZ,gBAAQ,KAAK;AAAA,sBACCA,WAAU,QAAQ,CAAC;AAAA,MACnCC,YAAW,SAAS,QAAQ,eAAe,SAAS,QAAQ,YAAY,IAAI,QAAQ,UAAU,MAAM,QAAQ,OAAO,KAAK,EAAE;AAAA,WACrH;AAAA,MACL,OAAO;AACL,gBAAQ,KAAK;AAAA,sBACCD,WAAU,QAAQ,CAAC;AAAA,MACnCC,YAAW,SAAS,QAAQ,eAAe,SAAS,QAAQ,YAAY,IAAI,QAAQ,UAAU,MAAM,QAAQ,OAAO,KAAK,EAAE;AAAA,UACtH;AAAA,MACJ;AAAA,IACF;AAEA,UAAM,EAAE,QAAQ,WAAW,IAAI,KAAK,UAAU,WAAW,OAAO;AAChE,UAAM,UAAU,SAAS,SAAS,IAAI,UAAU;AAAA,QAC5C,MAAM,KAAK,IAAI,CAAC;AAAA,QAChB,CAAC,OAAO,SAAS,UAAU,EAAE,IAAI,SAAS;AAAA,QAC1C,kBAAkB,KAAK,IAAI,CAAC,KAAK,OAAO,SAAS,IAAI,KAAK,UAAU;AAAA,iBAC3D,SAAS;AAAA,SACjB,SAAS;AAAA,EAAM,eAAe,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,EAGhD,iBAAiB,KAAK,KAAK,CAAC;AAAA;AAAA;AAAA,SAGrB,QAAQ,KAAK,MAAM,CAAC;AAAA;AAAA;AAGzB,QAAI,QAAQ,WAAW,MAAM;AAC3B,WAAK,MAAM,WAAW,OAAO;AAAA,IAC/B;AACA,UAAM,WAAW,CAAC,QAAQ,YAAY,QAAQ,aAAa;AAC3D,WAAO;AAAA,MACL,KAAK;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ,GAAG,KAAK,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,MACrD,UAAU,QAAQ,OACd,GAAG,QAAQ,WAAW,SAAS,mBAAmB,QAAQ,IAAI,QAC9D,GAAG,QAAQ,WAAW,SAAS;AAAA,MACnC,SAAS,GAAG,SAAS,kBAAkB,QAAQ,IAAI;AAAA,IACrD;AAAA,EACF;AAAA,EAEA,MAAM,QAAgB,UAAmB;AACvC,WAAO,WACH,QAAQD,WAAU,MAAM,CAAC,cACzB,QAAQA,WAAU,MAAM,CAAC,mBAAmBA,WAAU,MAAM,CAAC;AAAA,EACnE;AAAA,EAEA,OACE,WACA,QACA,WAAW,OACX,SACY;AACZ,QAAI,CAAC,OAAO,OAAO;AACjB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,UAAU,sBAAsB,QAAQ,OAAO,SAAS,QAAQ,IAAI,OAAO,MAAM;AAAA,QACjF,SAAS;AAAA,MACX;AAAA,IACF;AACA,UAAM,YAAY,KAAK,OAAO,WAAW,OAAO,OAAO,MAAM,OAAO;AACpE,UAAM,WAAW,WACb,QAAQ,OACN,UAAU,QAAQ,IAAI,cAAc,UAAU,SAAS,UAAU,MAAM,SAAS;AAAA,2BAC/D,UAAU,SAAS,OAAO,GAAG,UAAU,GAAG,eAAe;AAAA,yBAE1E,iBAAiB,UAAU,SAAS,UAAU,MAAM,SAAS;AAAA,2BAC5C,UAAU,SAAS,OAAO,GAAG,UAAU,GAAG,eAAe;AAAA,yBAE5E,QAAQ,OACN,SAAS,QAAQ,IAAI;AAAA,uBACR,QAAQ,IAAI,cAAc,UAAU,SAAS,UAAU,MAAM,SAAS;AAAA,+BAC9D,UAAU,SAAS,OAAO,GAAG,UAAU,GAAG,eAAe;AAAA;AAAA,sBAG9E;AAAA,8BACoB,UAAU,SAAS,UAAU,MAAM,SAAS;AAAA,+BAC3C,UAAU,SAAS,OAAO,GAAG,UAAU,GAAG,eAAe;AAAA;AAAA;AAIpF,WAAO;AAAA,MACL,QAAQ,qBAAqB,UAAU,SAAS,OAAO,aAAa;AAAA,MACpE,SAAS;AAAA,MACT,KAAK,QAAQ,UAAU,GAAG;AAAA,MAC1B;AAAA,MACA,QAAQ,GAAG,QAAQ,WAAW,QAAQA,WAAU,QAAQ,IAAI,CAAC,GAAG,UAAU,SAAS,KAAK,oCAAoC,KAAK,QAAQA,WAAU,QAAQ,IAAI,CAAC,iBAAiBA,WAAU,QAAQ,IAAI,CAAC,GAAG,UAAU,SAAS,KAAK,qCAAqC,SAAS;AAAA,MACjR,SAAS,SAASA,WAAU,QAAQ,IAAI,CAAC,oBAAoB,UAAU,OAAO;AAAA,IAChF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WACE,WACA,MACA,QACA,SACA,WAAW,OACC;AACZ,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO,KAAK,QAAQ,QAAQ,OAAO;AAAA,MACrC,KAAK;AAAA,MACL,KAAK;AACH,eAAO,KAAK,OAAO,QAAQ,OAAO;AAAA,MACpC,KAAK;AACH,eAAO;AAAA,UACL,SAAS;AAAA,UACT,KAAK;AAAA,UACL,QAAQ,GAAGA,WAAU,QAAQ,IAAc,CAAC;AAAA,UAC5C,UAAU,SAAS,QAAQ,IAAI;AAAA,UAC/B,SAAS,SAAS,QAAQ,IAAI;AAAA,QAChC;AAAA,MACF,KAAK;AACH,eAAO,KAAK,QAAQ,WAAW,QAAQ,OAAO;AAAA,MAChD,KAAK;AACH,eAAO,KAAK,OAAO,WAAW,QAAQ,UAAU,OAAO;AAAA,MACzD,KAAK;AACH,eAAO;AAAA,UACL,SAAS;AAAA,UACT,KAAK;AAAA,UACL,QAAQ,GAAGA,WAAU,QAAQ,IAAc,CAAC;AAAA,UAC5C,UAAU,SAAS,QAAQ,IAAI;AAAA,QACjC;AAAA,MACF;AAEE,eAAO;AAAA,UACL,SAAS;AAAA,UACT,KAAK;AAAA,UACL,UAAU;AAAA,UACV,QAAQ,GAAGA,WAAU,QAAQ,IAAc,CAAC;AAAA,UAC5C,UAAU,SAAS,QAAQ,IAAI;AAAA,QACjC;AAAA,IACJ;AAAA,EACF;AAAA,EAEA,KACE,WACA,MACA,UACA,SACY;AACZ,UAAM,aAAa,SAAS,IAAI,EAAE,MAAM,GAAG,EAAE,IAAI;AAEjD,UAAM,aAAa,KAAK;AAAA,MACtB;AAAA,MACA,UAAwB,KAAK,OAAO,IAAI;AAAA,MACxC;AAAA,MACA;AAAA,QACE,GAAG;AAAA,QACH,UAAU;AAAA,QACV,QAAQ,CAAC,CAAC,QAAQ,SAAS,CAAC,CAAC,aAAa,CAAC,QAAQ;AAAA,MACrD;AAAA,IACF;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,OACE,WACA,SACA,SACY;AACZ,UAAM,OAAO,WAAW,QAAQ,YAAY,SAAS;AAErD,UAAM,OAAO,QAAQ,OAAO,KAAK;AACjC,UAAM,UAAU,QAAQ,OAAO,MAAM;AACrC,QAAI,QAAQ,KAAK,CAAC,OAAO,GAAG,QAAQ,GAAG,SAAS,QAAQ,GAAG;AACzD,aAAO,OAAO,SAAS,IAAI,oBAAoB;AAAA,IACjD;AACA,UAAM,eAAe;AAAA,MACnB,CAAC;AAAA,MACD,GAAG;AAAA,MACH,GAAG,KAAK,IAAI,CAAC,QAAQ,UAAU,KAAK,OAAO,IAAI,IAAI,CAAC;AAAA,IACtD;AACA,WAAO,aAAa;AACpB,WAAO,KAAK,OAAO,MAAM,cAAc,MAAM,OAAO;AAAA,EACtD;AAAA,EAEA,OACE,WACA,SACA,SACY;AAEZ,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,KAAK;AAAA,QACL,QAAQ,GAAGA,WAAU,QAAQ,IAAc,CAAC;AAAA,QAC5C,UAAU,SAAS,QAAQ,IAAI;AAAA,MACjC;AAAA,IACF;AACA,UAAM,kBAAkB,QAAQ,UAAU,CAAC,WAAW;AACpD,UAAI,MAAM,MAAM,GAAG;AACjB,cAAM,YAAY,UAAU,KAAK,OAAO,OAAO,IAAI;AACnD,eAAO,UAAU,SAAS;AAAA,MAC5B;AACA,aAAO,OAAO,SAAS;AAAA,IACzB,CAAC;AACD,UAAM,eAAe,QAAQ,MAAM,CAAC;AACpC,QAAI,mBAAmB,GAAG;AACxB,mBAAa,OAAO,iBAAiB,CAAC;AAAA,IACxC;AAEA,WAAO,KAAK,OAAO,WAAW,aAAa,CAAC,GAAG,MAAM;AAAA,MACnD,GAAG;AAAA,MACH,UAAU,mBAAmB;AAAA,IAC/B,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,MAAc,SAAkB;AACxC,UAAM,SAAS,KAAK,aAAa,IAAI;AACrC,QAAI,QAAQ,OAAO;AACjB,aAAO,QAAQ,QAAQ,KAAK;AAAA,IAC9B;AACA,UAAM,aACJ,OAAO,SAAS,IACZ,SAAS,OAAO,KAAK,IAAI,CAAC,KAC1B,OAAO,WAAW,IAChB,WAAW,OAAO,CAAC,CAAC,KACpB;AACR,WAAO;AAAA,MACL;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OACE,WACA,SACA,SACY;AACZ,UAAM,OAAO,WAAW,QAAQ,YAAY,SAAS;AAErD,QAAI,QAAQ,WAAW,GAAG;AACxB,aAAO;AAAA,QACL,SAAS;AAAA,QACT,UAAU;AAAA,QACV,KAAK;AAAA,QACL,QAAQ,GAAGA,WAAU,QAAQ,IAAc,CAAC;AAAA,QAC5C,UAAU,SAAS,QAAQ,IAAI;AAAA,MACjC;AAAA,IACF;AACA,UAAM,UAAoB,CAAC;AAC3B,UAAM,WAAgD,CAAC;AAEvD,UAAM,UAAU,QAAQ,OAAO,MAAM,EAAE,OAAO,CAAC,OAAO,GAAG,SAAS,QAAQ;AAC1E,eAAW,UAAU,SAAS;AAC5B,UAAI,MAAM,MAAM,GAAG;AACjB,cAAM,UAAU,KAAK,KAAK,WAAW,OAAO,MAAM,MAAM,OAAO;AAC/D,iBAAS,KAAK;AAAA,UACZ,SAAS,QAAQ,QAAQ,QAAQ,sBAAsB,aAAa,QAAQ,GAAG,yBAAyB,QAAQ,GAAG;AAAA,UACnH,MAAM,QAAQ;AAAA,QAChB,CAAC;AAAA,MACH,WAAW,OAAO,SAAS,UAAU;AAEnC,gBAAQ,KAAK,SAAS,IAAI,aAAa,IAAI;AAAA;AAAA,YAEvC,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,WAML;AACH,iBAAS,KAAK;AAAA,UACZ,SAAS,yBAAyB,IAAI;AAAA,UACtC,MAAM,GAAG,IAAI;AAAA,QACf,CAAC;AAAA,MACH,WAAW,OAAO,SAAS,SAAS;AAGlC,cAAM,YAAY,KAAK,OAAO,MAAM,OAAO,OAAQ,MAAM;AAAA,UACvD,GAAG;AAAA,UACH,QAAQ;AAAA,QACV,CAAC;AACD,gBAAQ,KAAK,SAAS,IAAI,aAAa,IAAI;AAAA,yBAC1B,UAAU,GAAG;AAAA,cACxB,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,WAKP;AACH,iBAAS,KAAK;AAAA,UACZ,SAAS,uBAAuB,IAAI,aAAa,UAAU,GAAG;AAAA,UAC9D,MAAM,GAAG,IAAI;AAAA,QACf,CAAC;AAAA,MACH;AAAA,IACF;AACA,QAAI,QAAQ,QAAQ;AAElB,YAAM,aAA0C,CAAC;AACjD,iBAAW,UAAU,SAAS;AAC5B,YAAI,OAAO,yBAAyB,MAAM;AACxC;AAAA,QACF;AACA;AAAA,UACE,OAAO;AAAA,UACP,UAAU,IAAI;AAAA,QAChB;AACA,mBAAW,CAAC,UAAU,UAAU,KAAK,OAAO;AAAA,UAC1C,OAAO;AAAA,QACT,GAAG;AACD,cACE,OAAO,UAAU,KACjB,WAAW;AAAA,UAEX,WAAW,KAAK,WAAW,GAC3B;AACA,uBAAW,QAAQ,MAAM,oBAAI,IAAI;AACjC,uBAAW,QAAQ,EAAE,IAAI,OAAO,WAAW,KAAK,CAAC,CAAC,CAAC;AAAA,UACrD;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AAEJ,iBAAW,CAACE,OAAM,MAAM,KAAK,OAAO,QAAQ,UAAU,GAAG;AACvD;AAAA;AAAA,UAEE,OAAO,SAAS,QAAQ,OAAO,CAAC,OAAO,GAAG,aAAaA,KAAI,CAAC,EAAE;AAAA,UAC9D;AACA,8BAAoBA;AACpB;AAAA,QACF;AAAA,MACF;AAMA,UAAI,mBAAmB;AACrB,mBAAW,UAAU,SAAS;AAC5B,gBAAM,qBACH,OAAwB,WACvB,iBACF,EACA,OAAO,CAAC;AAEV,gBAAM,cAAc,GAAG,IAAI,GAAG,WAAW,kBAAkB,CAAC;AAC5D,mBAAS,KAAK;AAAA,YACZ,SAAS,sCAAsC,WAAW,0BAA0B,WAAW;AAAA,YAC/F,MAAM;AAAA,UACR,CAAC;AAED,gBAAM,YAAY,KAAK,QAAQ,aAAa,QAAQ;AAAA,YAClD,GAAG;AAAA,YACH,QAAQ;AAAA,YACR,OAAO;AAAA,UACT,CAAC;AACD,kBAAQ,KAAK,UAAU,OAAO;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAEA,UAAM,EAAE,QAAQ,WAAW,IAAI,KAAK,UAAU,MAAM,OAAO;AAC3D,YAAQ,QAAQ,YAAY,OAAO,SAAS,KAAK,OAAO,UAAU,IAAI,IAAI,UAAU;AAAA;AAAA,QAGhF,SAAS,SACL,UAAU,IAAI;AAAA;AAAA,UAEhB,SAAS,IAAI,CAAC,OAAO,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAQ9C,SAAS,SACL;AAAA,iBACM,SAAS,IAAI,CAAC,OAAO,YAAY,GAAG,IAAI,EAAE,EAAE,KAAK,MAAM,CAAC;AAAA,WAE9D,EACN;AAAA;AAAA,UAGO,EACN;AAAA,MACA;AACF,SAAK,MAAM,MAAM,QAAQ,KAAK,IAAI,CAAC;AAEnC,WAAO;AAAA,MACL,SAAS,QAAQ,KAAK,IAAI;AAAA,MAC1B,KAAK;AAAA,MACL,QAAQ,GAAG,KAAK,MAAM,QAAQ,MAAgB,QAAQ,QAAQ,CAAC;AAAA,MAC/D,UAAU,GAAG,IAAI,mBAAmB,QAAQ,IAAI;AAAA,MAChD,SAAS,GAAG,IAAI,kBAAkB,QAAQ,IAAI;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,QAAQ,MAAc;AACpB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT,KAAK;AACH,eAAO;AAAA,MACT;AACE,eAAO;AAAA,IACX;AAAA,EACF;AAAA,EAEA,MAAM,WAAmB,QAAsB,SAA8B;AAC3E,UAAM,OAAO,QAAQ,YAAY;AACjC,UAAM,SAAS,OAAO;AACtB,UAAM,UAAU,KAAK,QAAS,OAAO,QAAmB,QAAQ;AAGhE,UAAM,EAAE,QAAQ,WAAW,IAAI,KAAK,UAAU,WAAW,OAAO;AAEhE,UAAM,UAAU;AAAA,gCACY,WAAW,IAAI,CAAC;AAAA,UACtC,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,eAKF,OAAO,SAAS,KAAK,OAAO,UAAU,WAAW,IAAI,CAAC,IAAI,UAAU;AAAA,QAC3E,OAAO,IAAI,CAAC,OAAO,2BAA2B,WAAW,EAAE,CAAC,iBAAiB,OAAO,OAAO,WAAW,KAAK,IAAI,EAAE,GAAG,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,QAGpI,OAAO;AAAA;AAAA,mCAEoB,OAAO;AAAA;AAAA,EAExC,OACC;AAAA,MACC,CAAC,OACC,QAAQ,OAAO,OAAO,WAAW,KAAK,IAAI,EAAE,GAAG,YAAY,WAAW,EAAE,CAAC;AAAA,IAC7E,EACC,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAMa,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAU7B,QAAI,QAAQ,WAAW,MAAM;AAC3B,WAAK,MAAM,MAAM,OAAO;AAAA,IAC1B;AACA,WAAO;AAAA,MACL,MAAM,MAAM,QAAQ,OAAO,IAAI,IAC3B,KAAK,QAAQ,OAAO,KAAK,CAAC,CAAC,IAC3B,OAAO,OACL,KAAK,QAAQ,OAAO,IAAI,IACxB;AAAA,MACN;AAAA,MACA,KAAK,WAAW,IAAI;AAAA,MACpB,QAAQ,GAAG,QAAQ,WAAW,QAAQF,WAAU,QAAQ,IAAI,CAAC,cAAc,QAAQA,WAAU,QAAQ,IAAI,CAAC,mBAAmBA,WAAU,QAAQ,IAAI,CAAC,mBAAmB;AAAA,MACvK,UAAU,GAAG,WAAW,IAAI,CAAC,mBAAmB,QAAQ,IAAI;AAAA,MAC5D,SAAS,GAAG,WAAW,IAAI,CAAC,kBAAkB,QAAQ,IAAI;AAAA,IAC5D;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,QAAsB,SAA8B;AAC1D,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,UACL,SAAS;AAAA,UACT,KAAK;AAAA,UACL,QAAQ;AAAA,UACR,QAAQ,QAAQ,WACZ,QAAQA,WAAU,QAAQ,IAAI,CAAC,uBAC/B,QAAQA,WAAU,QAAQ,IAAI,CAAC,mBAAmBA;AAAA,YAChD,QAAQ;AAAA,UACV,CAAC;AAAA,UACL,UAAU,QAAQ,OACd,SAAS,QAAQ,IAAI,qCAAqC,QAAQ,IAAI,eACtE;AAAA,UACJ,SAAS,SAAS,QAAQ,IAAI;AAAA,QAChC;AAAA,MACF,KAAK;AAAA,MACL,KAAK;AACH,eAAO;AAAA,UACL,SAAS;AAAA,UACT,KAAK;AAAA,UACL,QAAQ,QAAQA,WAAU,QAAQ,IAAI,CAAC;AAAA,UACvC,QAAQ;AAAA,UACR,UAAU,QAAQ,OAAO,SAAS,QAAQ,IAAI,OAAO;AAAA,UACrD,SAAS,SAAS,QAAQ,IAAI;AAAA,QAChC;AAAA,MACF;AACE,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,KAAK;AAAA,UACL,SAAS;AAAA,UACT,QAAQ;AAAA,UACR,QAAQ,QAAQA,WAAU,QAAQ,IAAI,CAAC;AAAA,UACvC,UAAU,QAAQ,OAAO,SAAS,QAAQ,IAAI,iBAAiB;AAAA,UAC/D,SAAS,SAAS,QAAQ,IAAI;AAAA,QAChC;AAAA,IACJ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,QAAsB,SAA8B;AACzD,QAAI,OAAO,SAAS,WAAW;AAC7B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,QAAQA,WAAU,QAAQ,IAAI,CAAC;AAAA,QACvC,UAAU,SAAS,QAAQ,IAAI;AAAA,QAC/B,SAAS,SAAS,QAAQ,IAAI;AAAA,MAChC;AAAA,IACF;AACA,QAAI,CAAC,SAAS,QAAQ,EAAE,SAAS,OAAO,MAAgB,GAAG;AACzD,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK;AAAA,QACL,QAAQ;AAAA,QACR,QAAQ,QAAQA,WAAU,QAAQ,IAAI,CAAC;AAAA,QACvC,UAAU,SAAS,QAAQ,IAAI;AAAA,QAC/B,SAAS,SAAS,QAAQ,IAAI;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,MACL,SAAS;AAAA,MACT,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,QAAQA,WAAU,QAAQ,IAAI,CAAC;AAAA,MACvC,UAAU,SAAS,QAAQ,IAAI;AAAA,MAC/B,SAAS,SAAS,QAAQ,IAAI;AAAA,IAChC;AAAA,EACF;AAAA,EAEA,WACE,WACA,QACA,WAAW,MACX,UAAmB,CAAC,GACR;AACZ,QAAI,MAAM,MAAM,GAAG;AACjB,aAAO,KAAK,KAAK,WAAW,OAAO,MAAM,UAAU,OAAO;AAAA,IAC5D;AAGA,QAAI,OAAO,SAAS,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/C,aAAO,KAAK,OAAO,WAAW,OAAO,OAAO,OAAO;AAAA,IACrD;AACA,QAAI,OAAO,SAAS,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/C,aAAO,KAAK,OAAO,WAAW,OAAO,OAAO,OAAO;AAAA,IACrD;AACA,QAAI,OAAO,SAAS,MAAM,QAAQ,OAAO,KAAK,GAAG;AAC/C,aAAO,KAAK,OAAO,WAAW,OAAO,OAAO,OAAO;AAAA,IACrD;AACA,QAAI,OAAO,QAAQ,MAAM,QAAQ,OAAO,IAAI,GAAG;AAC7C,aAAO,KAAK,MAAM,WAAW,QAAQ,OAAO;AAAA,IAC9C;AAEA,UAAM,QAAQ,MAAM,QAAQ,OAAO,IAAI,IACnC,OAAO,OACP,OAAO,OACL,CAAC,OAAO,IAAI,IACZ,CAAC;AAEP,QAAI,WAAW;AACf,QAAI,cAAc,UAAU,OAAO,UAAU;AAC3C,iBAAW;AAAA,IACb,WAAW,OAAO,YAAY,MAAM;AAClC,iBAAW;AAAA,IACb,WAAW,MAAM,SAAS,MAAM,GAAG;AACjC,iBAAW;AAAA,IACb;AAGA,QAAI,CAAC,MAAM,QAAQ;AAEjB,UAAI,gBAAgB,QAAQ;AAC1B,eAAO,KAAK,QAAQ,WAAW,QAAQ,OAAO;AAAA,MAChD;AACA,UAAI,WAAW,QAAQ;AACrB,eAAO,KAAK,OAAO,WAAW,QAAQ,MAAM,OAAO;AAAA,MACrD;AACA,aAAO;AAAA,QACL,SAAS;AAAA,QACT,KAAK;AAAA,QACL,QAAQ,GAAGA,WAAU,QAAQ,IAAc,CAAC;AAAA,QAC5C,UAAU,SAAS,QAAQ,IAAI;AAAA,QAC/B,UAAU;AAAA,QACV,SAAS;AAAA;AAAA,MACX;AAAA,IACF;AACA,WAAO,KAAK;AAAA,MACV;AAAA,MACA,MAAM,CAAC;AAAA,MACP;AAAA,MACA,EAAE,GAAG,SAAS,SAAS;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAAA,EAEA,OACE,WACA,QACA,WAAW,MACX,UAAmB,CAAC,GACR;AACZ,UAAM,QAAQ,QAAQ;AACtB,YAAQ,QAAQ;AAChB,UAAM,aAAa,KAAK,WAAW,WAAW,QAAQ,UAAU;AAAA,MAC9D,GAAG;AAAA,MACH,SAAS;AAAA,IACX,CAAC;AAED,QAAI,OAAO;AACT,WAAK,MAAM,WAAW,WAAW,KAAK,MAAM,WAAW,GAAG,GAAG;AAC7D,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AACF;AAEO,SAAS,eACd,QACwB;AACxB,SAAO,CAAC,MAAM,MAAM,MAAM,OAAO,SAAS,YAAY,CAAC,CAAC,OAAO;AACjE;;;AC/0BA;;;ACAA;;;ACAA;;;AbuCA,SAAS,SACP,MACA,SACA,MACA;AACA,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG;AACpD,QAAI,MAAM,MAAM;AAAG;AAEnB,QAAI,CAAC,QAAQ,OAAO,KAAK,KAAK,CAAC,QAAQ,OAAO,KAAK,GAAG;AACpD,aAAO,OAAO;AAAA,IAChB;AACA,QAAI,CAAC,QAAQ,OAAO,KAAK,GAAG;AAC1B,YAAMG,WAAU,OAAO;AACvB,YAAMC,QAAOD,SAAQ,OAAO,KAAK;AACjC,YAAM,UAAUA,SAAQ,OAAO,MAAM;AACrC,UAAI,QAAQ,KAAK,CAAC,OAAO,GAAG,QAAQ,GAAG,SAAS,QAAQ,GAAG;AACzD,QAAAE,QAAO,OAAO,SAAS,IAAI,oBAAoB;AAAA,MACjD;AACA,YAAM,eAAeC;AAAA,QACnB,CAAC;AAAA,QACD,GAAG;AAAA,QACH,GAAGF,MAAK,IAAI,CAAC,QAAQ,UAAU,MAAM,IAAI,IAAI,CAAC;AAAA,MAChD;AACA,aAAO,aAAa;AACpB,aAAO,OAAO;AACd,aAAO,OAAO,QAAQ,YAAY;AAAA,IACpC;AAEA,QAAI,OAAO,SAAS,UAAU;AAC5B,UAAI,CAAC,QAAQ,OAAO,KAAK,GAAG;AAC1B,mBAAW,YAAY,OAAO,OAAO;AACnC,gBAAM,QAAQ,OAAO,MAAM,QAAQ;AACnC,cAAI,MAAM,KAAK;AAAG;AAClB,cAAI,CAAC,QAAQ,MAAM,QAAQ,KAAK,OAAO,YAAY;AACjD,mBAAO,MAAM,QAAQ,IAAI,OAAO,WAAW,MAAM,SAAS,CAAC,CAAC;AAAA,UAC9D;AAAA,QACF;AAEA,eAAO,OAAO;AACd,iBAAS,MAAM,SAAS,IAAI;AAC5B;AAAA,MACF;AAEA,aAAO,eAAe,CAAC;AAEvB,iBAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,OAAO,UAAU,GAAG;AACjE,YAAI,MAAM,KAAK;AAAG;AAClB,cAAM,UAAU,WAAW,GAAG,IAAI,IAAI,SAAS,QAAQ,MAAM,EAAE,CAAC,EAAE;AAClE,aAAK,KAAK,EAAE,MAAM,SAAS,MAAM,CAAC;AAClC,eAAO,WAAW,QAAQ,IAAI;AAAA,UAC5B,MAAM,wBAAwB,OAAO;AAAA,QACvC;AACA,cAAM,QAAQ,OAAO;AAAA,UACnB,OAAO,QAAQ,MAAM,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,KAAKG,MAAK,MAAM;AAC3D,mBAAO,CAAC,WAAW,GAAG,OAAO,IAAI,GAAG,EAAE,GAAGA,MAAK;AAAA,UAChD,CAAC;AAAA,QACH;AACA,iBAAS,MAAM,OAAO,IAAI;AAAA,MAc5B;AAAA,IACF,WAAW,OAAO,SAAS,SAAS;AAClC,UAAI,MAAM,OAAO,KAAK;AAAG;AACzB,YAAM,UAAU;AAChB,WAAK,KAAK,EAAE,MAAM,SAAS,OAAO,OAAO,SAAS,CAAC,EAAE,CAAC;AACtD,aAAO,QAAQ;AAAA,QACb,MAAM,wBAAwB,OAAO;AAAA,MACvC;AAAA,IACF;AAAA,EACF;AACF;AACA,eAAsB,SACpB,MACA,UAUA;AACA,QAAM,aAAa,SAAS,QAAQ;AACpC,QAAM,SAASC,MAAK,SAAS,QAAQ,KAAK;AAC1C,QAAM,SAMF,CAAC;AACL,OAAK,eAAe,CAAC;AACrB,OAAK,WAAW,YAAY,CAAC;AAC7B,QAAM,SAAiC,CAAC;AACxC,QAAM,UAAkC,CAAC;AACzC,mBAAiB,EAAE,KAAK,GAAG,CAAC,OAAO,cAAc;AAI/C,cAAU,cAAc,CAAC;AACzB,SAAK,eAAe,CAAC;AACrB,SAAK,WAAW,YAAY,CAAC;AAC7B,eAAW,UAAU,UAAU,WAAW;AACxC,UAAI,CAAC,oBAAoB,MAAM;AAAG;AAClC,YAAMC,YAAW,MAAM,UAAU,UAAU,MAAM,CAAoB,IACjE,UAA0B,MAAM,UAAU,UAAU,MAAM,EAAE,IAAI,IAC/D,UAAU,UAAU,MAAM;AAC/B,UAAI,CAAC,QAAQA,UAAS,OAAO,GAAG;AAC9B,mBAAW,CAAC,aAAa,SAAS,KAAK,OAAO;AAAA,UAC5CA,UAAS;AAAA,QACX,GAAG;AACD,cAAI,qBAAqB,WAAW,GAAG;AACrC,gBAAI,UAAU,UAAU,CAAC,MAAM,UAAU,MAAM,GAAG;AAChD,oBAAM,aAAa,WAAW,GAAG,UAAU,WAAW,SAAS;AAC/D,mBAAK,WAAW,QAAQ,UAAU,IAAI,UAAU;AAChD,wBAAU,UAAU,MAAM,EAAE,QAAQ,WAAW,EAAE,SAAS;AAAA,gBACxD,MAAM,wBAAwB,UAAU;AAAA,cAC1C;AAAA,YACF;AAAA,UACF;AAAA,QAEF;AAAA,MACF;AAAA,IACF;AACA,YAAQ,IAAI,cAAc,MAAM,MAAM,IAAI,MAAM,IAAI,EAAE;AACtD,UAAM,QACJ,OAAO,MAAM,SAAS,MACrB,OAAO,MAAM,SAAS,IAAI;AAAA,MACzB,SAAS,CAAC;AAAA,MACV,KAAK,SAAS,MAAM,SAAS,UAAU,WAAW,MAAM,SAAS,CAAC;AAAA,IACpE;AAEF,UAAM,QAAQ,SAAS,MAAM,EAAE,OAAO,UAAU,CAAC;AACjD,WAAO,OAAO,QAAQ,MAAM,MAAM;AAElC,UAAM,WAAW,SAAS,MAAM,SAAS;AACzC,QAAI,UAAU;AACZ,aAAO,OAAO,SAAS,SAAS,OAAO;AAAA,IACzC;AACA,UAAM,QAAQ,KAAK;AAAA,iBACN,WAAW,SAAS,aAAa,uBAAuB,KAAKC,WAAU,UAAU,WAAW,CAAC;AAAA,SACrG,QAAQ,UAAU,WAAW,IAAI,KAAK,GAAG,MAAM,SAAS,QAAQ;AAAA;AAAA,iDAExB,MAAM,WAAW;AAAA,uBAC3C,MAAM,MAAM;AAAA,8BACL,MAAM,IAAI;AAAA;AAAA,eAEzB,CAAC,QAAQ,WAAW,EAAE,SAAS,MAAM,WAAW,IAAI,MAAM,SAAS,EAAE;AAAA,YACxE,WAAW,GAAG,SAAS,MAAM,MAAM,gBAAgB;AAAA;AAAA,KAE1D;AAAA,EACH,CAAC;AAED,QAAM,UAAmD,CAAC;AAC1D,WAAS,MAAM,KAAK,WAAW,SAAS,OAAO;AAC/C,aAAW,OAAO,SAAS;AACzB,SAAK,WAAW,QAAQ,IAAI,IAAI,IAAI,IAAI;AAAA,EAC1C;AACA,QAAMC;AAAA,IACJH,MAAK,QAAQ,IAAI,GAAG,aAAa;AAAA,IACjC,KAAK,UAAU,MAAM,MAAM,CAAC;AAAA,EAC9B;AAEA,QAAM,SAAS,OAAO,QAAQ,KAAK,WAAW,OAAO,EAAE,OAErD,CAAC,KAAK,CAAC,MAAM,MAAM,MAAM;AACzB,UAAM,aAAa,IAAI,eAAe,MAAM,CAACI,OAAM,YAAY;AAC7D,UAAI,UAAU,UAAUA,KAAI,CAAC,OAAO,IAClC;AAAA;AAAA,EAAwE,OAAO;AAAA,IACnF,CAAC;AACD,eAAW,OAAO,WAAW,IAAI,GAAG,MAAM;AAC1C,WAAO;AAAA,EACT,GAAG,CAAC,CAAC;AAEL,QAAM,UAAU,OAAO,QAAQ,MAAM,EAAE;AAAA,IACrC,CAAC,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM;AAC5B,aAAO;AAAA,QACL,GAAG;AAAA,QACH,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAW7B,WAAW,IAAI,CAAC;AAAA;AAAA;AAAA,QAGpB,WAAW,IAAI,CAAC;AAAA,QAChB,QAAQ,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,MAGpB;AAAA,IACF;AAAA,IACA,CAAC;AAAA,EACH;AAEA,QAAM,SAAS;AAAA,IACb,OAAO,KAAK,MAAM,EACjB,IAAI,CAAC,SAAS,iBAAiB,UAAU,IAAI,CAAC,SAAS,EACvD,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,UAIL,UAAU;AAAA;AAAA,EAElB,OAAO,KAAK,MAAM,EACjB,IAAI,CAAC,SAAS,cAAc,WAAW,IAAI,CAAC,UAAUF,WAAU,IAAI,CAAC,GAAG,EACxE,KAAK,IAAI,CAAC;AAAA;AAAA,IAET,UAAU;AAAA;AAAA;AAAA;AAAA,MAIR,OAAO,KAAK,MAAM,EACjB;AAAA,IACC,CAAC,SACC,QAAQA,WAAU,IAAI,CAAC,MAAM,WAAW,IAAI,CAAC;AAAA,EACjD,EACC,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBf,QAAM,WAAW,QAAQ;AAAA,IACvB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL,CAAC;AAED,QAAM,WAAW,QAAQ;AAAA,IACvB,qBAAqB,MAAM,mBAAmBF,MAAK,QAAQ,QAAQ,GAAG;AAAA,MACpE,cAAc;AAAA,MACd,YAAY;AAAA,IACd,CAAC;AAAA,IACD,qBAAqB,MAAM,mBAAmBA,MAAK,QAAQ,QAAQ,GAAG;AAAA,MACpE,cAAc;AAAA,MACd,YAAY;AAAA,IACd,CAAC;AAAA,IACD,sBAAsB,MAAM,mBAAmBA,MAAK,QAAQ,SAAS,GAAG;AAAA,MACtE,cAAc;AAAA,MACd,YAAY;AAAA,IACd,CAAC;AAAA,IACD,qBAAqB;AAAA,IACrB,aAAa;AAAA,IACb,kBAAkB;AAAA,IAClB,GAAG;AAAA,EACL,CAAC;AACD,QAAM,WAAW,QAAQ;AAAA,IACvB,gBAAgB,GAAG,MAAM,mBAAmBA,MAAK,MAAM,GAAG;AAAA,MACxD,cAAc;AAAA,MACd,YAAY;AAAA,MACZ,OAAO,QAAQ;AACb,eAAO,OAAO,OAAO,KAAK,OAAO,SAAS;AAAA,MAC5C;AAAA,IACF,CAAC,CAAC,GAAG,MAAM;AAAA,EACb,CAAC;AAED,QAAM,WAAW,SAAS,QAAQ;AAAA,IAChC,gBAAgB;AAAA,MACd,gBAAgB;AAAA,MAChB,SAAS,KAAK,UAAU;AAAA,QACtB,MAAM,SAAS,OACX,GAAG,UAAU,WAAW,YAAY,CAAC,CAAC,SACtC;AAAA,QACJ,SAAS;AAAA,QACT,aAAa;AAAA,UACX,KAAK;AAAA,QACP;AAAA,QACA,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,MAAM;AAAA,QACR;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,QAAM,SAAS,aAAa;AAAA,IAC1B;AAAA,EACF,CAAC;AACH;AAEA,SAAS,SAAS,MAAqB,EAAE,OAAO,UAAU,GAAc;AACtE,QAAM,SAAkC,CAAC;AACzC,QAAM,YAAY,WAAW,GAAG,UAAU,WAAW,QAAQ;AAC7D,MAAI,cAAc;AAClB,MAAI,SAAS;AACb,MAAI,CAAC,QAAQ,UAAU,WAAW,GAAG;AACnC,UAAM,cAAc,MAAM,UAAU,WAAW,IAC3C,UAA6B,MAAM,UAAU,YAAY,IAAI,IAC7D,UAAU;AAEd,eAAW,QAAQ,YAAY,SAAS;AACtC,YAAM,WAAW,MAAM,YAAY,QAAQ,IAAI,EAAE,MAAM,IACnD,UAAU,MAAM,YAAY,QAAQ,IAAI,EAAE,OAAO,IAAI,IACrD,YAAY,QAAQ,IAAI,EAAE;AAC9B,UAAI,CAAC,UAAU;AACb,gBAAQ;AAAA,UACN,wBAAwB,IAAI,OAAO,MAAM,MAAM,IAAI,MAAM,IAAI;AAAA,QAC/D;AACA;AAAA,MACF;AAEA,YAAM,aAAa,IAAI,eAAe,MAAM,CAAC,MAAM,YAAY;AAC7D,eAAOA,MAAK,UAAU,IAAI,OAAO,CAAC,IAChC;AAAA;AAAA,EAAsG,OAAO;AAAA,MACjH,CAAC;AACD,YAAM,aAAa,WAAW,OAAO,WAAW,UAAU,MAAM;AAAA,QAC9D,OAAO,eAAe,QAAQ,IAAI,SAAY;AAAA,MAChD,CAAC;AACD,eAAS,WAAW;AACpB,YAAM,CAAC,WAAW,YAAY,IAAI,gBAAgB,IAAI,EAAE,KAAK,MAAM,GAAG;AACtE,UAAI,cAAc,eAAe;AAC/B,sBAAc,qBAAqB,IAAI;AAAA,MACzC,OAAO;AACL,sBAAc;AAAA,MAChB;AAAA,IAiBF;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,WAAW,aAAa,OAAO;AAClD;AAEA,SAAS,SAAS,MAAqB,WAA4B;AACjE,QAAM,aAAa,WAAW,GAAG,UAAU,WAAW,SAAS;AAC/D,YAAU,cAAc,CAAC;AACzB,QAAM,UAAkC,CAAC;AACzC,aAAW,UAAU,UAAU,WAAW;AACxC,UAAM,WAAW,MAAM,UAAU,UAAU,MAAM,CAAoB,IACjE,UAA0B,MAAM,UAAU,UAAU,MAAM,EAAE,IAAI,IAC/D,UAAU,UAAU,MAAM;AAC/B,eAAW,QAAQ,SAAS,SAAS;AACnC,YAAM,EAAE,OAAO,IAAI,SAAS,QAAQ,IAAI;AACxC,UAAI,CAAC,QAAQ;AACX,gBAAQ;AAAA,UACN,wBAAwB,IAAI,OAAO,UAAU,WAAW;AAAA,QAC1D;AACA;AAAA,MACF;AACA,YAAM,aAAa,IAAI,eAAe,MAAM,CAAC,MAAM,YAAY;AAAA,MAG/D,CAAC;AACD,UAAI,uBAAuB,IAAI,GAAG;AAChC,eAAO;AAAA,UACL,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,YAAY;AAAA,QACd;AAAA,MACF;AACA,UAAI,qBAAqB,IAAI,GAAG;AAC9B,cAAM,aAAa,WAAW,OAAO,YAAY,QAAQ,MAAM;AAAA;AAAA,UAE7D,QAAQ;AAAA,QACV,CAAC;AACD,eAAO;AAAA,UACL,MAAM;AAAA,UACN;AAAA,UACA;AAAA,UACA,QAAQ,yDAAyD,WAAW,QAAQ;AAAA,UACpF,YAAY,WAAW;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;",
|
|
6
|
+
"names": ["merge", "assert", "writeFile", "join", "camelcase", "ts", "parse", "camelcase", "snakecase", "snakecase", "camelcase", "nullable", "name", "schemas", "refs", "assert", "merge", "value", "join", "response", "camelcase", "writeFile", "name"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dart-emitter.d.ts","sourceRoot":"","sources":["../../src/lib/dart-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACb,MAAM,mBAAmB,CAAC;AA8D3B,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACnC,KAAK,UAAU,GAAG;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AACF,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AACpD;;GAEG;AACH,qBAAa,cAAc;;gBAIb,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"dart-emitter.d.ts","sourceRoot":"","sources":["../../src/lib/dart-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,aAAa,EACb,eAAe,EACf,YAAY,EACb,MAAM,mBAAmB,CAAC;AA8D3B,KAAK,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AACnC,KAAK,UAAU,GAAG;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AACF,KAAK,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AACpD;;GAEG;AACH,qBAAa,cAAc;;gBAIb,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,IAAI;IA0nB3C;;OAEG;IACH,MAAM,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,GAAG,UAAU;IAiG1D,MAAM,CACJ,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,YAAY,GAAG,eAAe,EACtC,QAAQ,UAAO,EACf,OAAO,GAAE,OAAY,GACpB,UAAU;CAcd;AAED,wBAAgB,cAAc,CAC5B,MAAM,EAAE,YAAY,GAAG,eAAe,GACrC,MAAM,IAAI,YAAY,CAExB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/lib/generate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,aAAa,EAMd,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/lib/generate.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,aAAa,EAMd,MAAM,mBAAmB,CAAC;AA6G3B,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE;IACR,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE,iBAyNF"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sdk-it/dart",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"openapi3-ts": "4.4.0",
|
|
25
|
-
"@sdk-it/core": "0.
|
|
25
|
+
"@sdk-it/core": "0.19.0",
|
|
26
26
|
"lodash-es": "^4.17.21",
|
|
27
27
|
"stringcase": "^4.3.1",
|
|
28
|
-
"@sdk-it/spec": "0.
|
|
28
|
+
"@sdk-it/spec": "0.19.0",
|
|
29
29
|
"fast-content-type-parse": "^3.0.0",
|
|
30
30
|
"yaml": "^2.7.0"
|
|
31
31
|
}
|