@arrirpc/codegen-dart 0.45.0

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.cjs ADDED
@@ -0,0 +1,1031 @@
1
+ 'use strict';
2
+
3
+ const child_process = require('child_process');
4
+ const fs = require('fs');
5
+ const codegenUtils = require('@arrirpc/codegen-utils');
6
+ const schema = require('@arrirpc/schema');
7
+
8
+ var __defProp = Object.defineProperty;
9
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
10
+ var __publicField = (obj, key, value) => {
11
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
12
+ return value;
13
+ };
14
+ function camelCaseWrapper(input) {
15
+ if (input.toUpperCase() === input) {
16
+ return codegenUtils.camelCase(input, { normalize: true });
17
+ }
18
+ return codegenUtils.camelCase(input);
19
+ }
20
+ const dartClientGenerator = codegenUtils.defineClientGeneratorPlugin(
21
+ (options) => {
22
+ return {
23
+ generator: async (def) => {
24
+ if (!options.clientName) {
25
+ throw new Error(
26
+ 'Missing "clientName" cannot generate dart client'
27
+ );
28
+ }
29
+ if (!options.outputFile) {
30
+ throw new Error(
31
+ 'Missing "outputFile" cannot generate dart client'
32
+ );
33
+ }
34
+ const numProcedures = Object.keys(def.procedures).length;
35
+ if (numProcedures <= 0) {
36
+ console.warn(
37
+ "No procedures found in definition file. Dart client will not be generated"
38
+ );
39
+ }
40
+ const result = createDartClient(def, options);
41
+ fs.writeFileSync(options.outputFile, result);
42
+ try {
43
+ child_process.execSync(`dart format ${options.outputFile}`);
44
+ } catch (err) {
45
+ console.error("Error formatting dart client", err);
46
+ }
47
+ },
48
+ options
49
+ };
50
+ }
51
+ );
52
+ class DartClientGenerator {
53
+ constructor() {
54
+ __publicField(this, "generatedModels", []);
55
+ }
56
+ }
57
+ function getAnnotations(metadata) {
58
+ const commentParts = [];
59
+ if (metadata?.description?.length) {
60
+ const parts = metadata.description.split("\n");
61
+ for (const part of parts) {
62
+ commentParts.push(`/// ${part}`);
63
+ }
64
+ }
65
+ if (metadata?.isDeprecated) {
66
+ commentParts.push("@deprecated");
67
+ }
68
+ if (commentParts.length === 0) {
69
+ return "";
70
+ }
71
+ return `${commentParts.join("\n")}
72
+ `;
73
+ }
74
+ function createDartClient(def, opts) {
75
+ const existingClassNames = [];
76
+ const clientVersion = def.info?.version ?? "";
77
+ const services = codegenUtils.unflattenProcedures(def.procedures);
78
+ const rpcParts = [];
79
+ const serviceGetterParts = [];
80
+ const serviceParts = [];
81
+ const modelParts = [];
82
+ for (const key of Object.keys(services)) {
83
+ const item = services[key];
84
+ if (codegenUtils.isRpcDefinition(item)) {
85
+ const rpc = dartRpcFromDefinition(key, item);
86
+ if (rpc) {
87
+ rpcParts.push(rpc);
88
+ }
89
+ continue;
90
+ }
91
+ if (codegenUtils.isServiceDefinition(item)) {
92
+ const serviceName = codegenUtils.pascalCase(`${opts.clientName}_${key}`);
93
+ const service = dartServiceFromDefinition(serviceName, item, {
94
+ versionNumber: clientVersion,
95
+ ...opts
96
+ });
97
+ serviceParts.push(service);
98
+ serviceGetterParts.push(`${serviceName}Service get ${key} {
99
+ return ${serviceName}Service(
100
+ httpClient: _httpClient,
101
+ baseUrl: _baseUrl,
102
+ headers: _headers,
103
+ );
104
+ }`);
105
+ }
106
+ }
107
+ for (const key of Object.keys(def.definitions)) {
108
+ const item = def.definitions[key];
109
+ if (codegenUtils.isSchemaFormProperties(item) || codegenUtils.isSchemaFormDiscriminator(item) || codegenUtils.isSchemaFormValues(item)) {
110
+ const result = dartTypeFromJtdSchema(key, item, {
111
+ isOptional: false,
112
+ existingClassNames
113
+ });
114
+ modelParts.push(result.content);
115
+ }
116
+ }
117
+ if (rpcParts.length === 0 && serviceGetterParts.length === 0) {
118
+ return `// this file was autogenerated by arri
119
+ // ignore_for_file: type=lint
120
+ import "package:arri_client/arri_client.dart";
121
+
122
+ ${modelParts.join("\n")}`;
123
+ }
124
+ return `// this file was autogenerated by arri
125
+ // ignore_for_file: type=lint, unused_field
126
+ import "dart:convert";
127
+ import "package:arri_client/arri_client.dart";
128
+ import "package:http/http.dart" as http;
129
+
130
+ class ${opts.clientName} {
131
+ final http.Client? _httpClient;
132
+ final String _baseUrl;
133
+ final String _clientVersion = "${def.info?.version ?? ""}";
134
+ late final Map<String, String> Function()? _headers;
135
+ ${opts.clientName}({
136
+ http.Client? httpClient,
137
+ String baseUrl = "",
138
+ Map<String, String> Function()? headers,
139
+ }) : _httpClient = httpClient,
140
+ _baseUrl = baseUrl,
141
+ _headers = headers;
142
+ ${rpcParts.join("\n ")}
143
+ ${serviceGetterParts.join("\n ")}
144
+ }
145
+
146
+ ${serviceParts.join("\n")}
147
+
148
+ ${modelParts.join("\n")}
149
+ `;
150
+ }
151
+ function dartServiceFromDefinition(name, def, opts) {
152
+ const rpcParts = [];
153
+ const subServiceParts = [];
154
+ const serviceName = `${name}`;
155
+ Object.keys(def).forEach((key) => {
156
+ const item = def[key];
157
+ if (codegenUtils.isRpcDefinition(item)) {
158
+ const rpc = dartRpcFromDefinition(key, item);
159
+ if (rpc) {
160
+ rpcParts.push(rpc);
161
+ }
162
+ return;
163
+ }
164
+ if (codegenUtils.isServiceDefinition(item)) {
165
+ const subServiceName = codegenUtils.pascalCase(`${serviceName}_${key}`);
166
+ const subService = dartServiceFromDefinition(
167
+ subServiceName,
168
+ item,
169
+ opts
170
+ );
171
+ subServiceParts.push({
172
+ name: subServiceName,
173
+ key,
174
+ content: subService
175
+ });
176
+ }
177
+ });
178
+ return `class ${serviceName}Service {
179
+ final http.Client? _httpClient;
180
+ final String _baseUrl;
181
+ final String _clientVersion = "${opts.versionNumber}";
182
+ late final Map<String, String> Function()? _headers;
183
+ ${serviceName}Service({
184
+ http.Client? httpClient,
185
+ String baseUrl = "",
186
+ Map<String, String> Function()? headers,
187
+ }) : _httpClient = httpClient,
188
+ _baseUrl = baseUrl,
189
+ _headers = headers;
190
+ ${subServiceParts.map(
191
+ (sub) => `${sub.name}Service get ${sub.key} {
192
+ return ${sub.name}Service(
193
+ httpClient: _httpClient,
194
+ baseUrl: _baseUrl,
195
+ headers: _headers,
196
+ );
197
+ }`
198
+ ).join("\n")}
199
+ ${rpcParts.join("\n ")}
200
+ }
201
+ ${subServiceParts.map((sub) => sub.content).join("\n")}
202
+ `;
203
+ }
204
+ function dartRpcFromDefinition(key, def, opts) {
205
+ if (def.transport === "http") {
206
+ return dartHttpRpcFromSchema(key, def);
207
+ }
208
+ if (def.transport === "ws") {
209
+ return dartWsRpcFromSchema(key, def);
210
+ }
211
+ console.warn(
212
+ `[codegen-dart] WARNING: unsupported transport "${def.transport}". Skipping "${def.path}".`
213
+ );
214
+ return "";
215
+ }
216
+ function dartHttpRpcFromSchema(key, def, opts) {
217
+ let returnType = `Future<String>`;
218
+ let returnTypeName = "String";
219
+ if (def.response) {
220
+ returnTypeName = codegenUtils.pascalCase(def.response);
221
+ if (def.isEventStream) {
222
+ returnType = `EventSource<${returnTypeName}>`;
223
+ } else {
224
+ returnType = `Future<${returnTypeName}>`;
225
+ }
226
+ } else {
227
+ returnType = "Future<void>";
228
+ }
229
+ let paramsInput = "";
230
+ if (def.params) {
231
+ paramsInput = `${codegenUtils.pascalCase(def.params)} params`;
232
+ }
233
+ let responseParser = "(body) => body;";
234
+ switch (returnType) {
235
+ case "Future<String>":
236
+ break;
237
+ case "Future<int>":
238
+ responseParser = `(body) => Int.parse(body)`;
239
+ break;
240
+ case "Future<double>":
241
+ responseParser = `(body) => Double.parse(body)`;
242
+ break;
243
+ case "Future<void>":
244
+ responseParser = `(body) {}`;
245
+ break;
246
+ case "Future<bool>":
247
+ responseParser = `(body) {
248
+ switch(body) {
249
+ case "true":
250
+ case "1":
251
+ return true;
252
+ case "false":
253
+ case "0":
254
+ default:
255
+ return false;
256
+ }
257
+ }`;
258
+ break;
259
+ default:
260
+ responseParser = `(body) => ${returnTypeName}.fromJson(
261
+ json.decode(body),
262
+ )`;
263
+ break;
264
+ }
265
+ if (def.isEventStream) {
266
+ const hookParts = [
267
+ `SseHookOnData<${returnTypeName}>? onData`,
268
+ `SseHookOnError<${returnTypeName}>? onError`,
269
+ `SseHookOnConnectionError<${returnTypeName}>? onConnectionError`,
270
+ `SseHookOnOpen<${returnTypeName}>? onOpen`,
271
+ `SseHookOnClose<${returnTypeName}>? onClose`,
272
+ `String? lastEventId`
273
+ ];
274
+ return `${getAnnotations({ description: def.description, isDeprecated: def.isDeprecated })}${returnType} ${key}(${paramsInput.length ? `${paramsInput}, ` : ""}{${hookParts.join(", ")},}) {
275
+ return parsedArriSseRequest<${returnTypeName}>(
276
+ "$_baseUrl${def.path}",
277
+ httpClient: _httpClient,
278
+ method: HttpMethod.${def.method},
279
+ headers: _headers,
280
+ params: ${paramsInput.length ? `params.toJson()` : "null"},
281
+ parser: ${responseParser},
282
+ onData: onData,
283
+ onError: onError,
284
+ onConnectionError: onConnectionError,
285
+ onOpen: onOpen,
286
+ onClose: onClose,
287
+ lastEventId: lastEventId,
288
+ clientVersion: _clientVersion,
289
+ );
290
+ }`;
291
+ }
292
+ return `${getAnnotations({ description: def.description, isDeprecated: def.isDeprecated })}${returnType} ${key}(${paramsInput}) {
293
+ return parsedArriRequest(
294
+ "$_baseUrl${def.path}",
295
+ httpClient: _httpClient,
296
+ method: HttpMethod.${def.method},
297
+ headers: _headers,
298
+ params: ${paramsInput.length ? `params.toJson()` : "null"},
299
+ parser: ${responseParser},
300
+ clientVersion: _clientVersion,
301
+ );
302
+ }`;
303
+ }
304
+ function dartWsRpcFromSchema(key, def, opts) {
305
+ const serverMsg = def.response ? codegenUtils.pascalCase(def.response, { normalize: true }) : "Null";
306
+ const clientMsg = def.params ? codegenUtils.pascalCase(def.params, { normalize: true }) : "Null";
307
+ const returnType = `Future<ArriWebsocketController<${serverMsg}, ${clientMsg}>>`;
308
+ const parser = def.response ? `(body) => ${serverMsg}.fromJson(json.decode(body))` : `(_) => null`;
309
+ const serializer = def.params ? `(body) => json.encode(body.toJson())` : `(_) => ""`;
310
+ return `${getAnnotations({ description: def.description, isDeprecated: def.isDeprecated })}${returnType} ${key}() {
311
+ return arriWebsocketRequest<${serverMsg}, ${clientMsg}>(
312
+ "$_baseUrl${def.path}",
313
+ headers: _headers,
314
+ parser: ${parser},
315
+ serializer: ${serializer},
316
+ clientVersion: _clientVersion,
317
+ );
318
+ }`;
319
+ }
320
+ function dartTypeFromJtdSchema(nodePath, def, additionalOptions) {
321
+ if (codegenUtils.isSchemaFormType(def)) {
322
+ return dartScalarFromJtdScalar(nodePath, def, additionalOptions);
323
+ }
324
+ if (codegenUtils.isSchemaFormProperties(def)) {
325
+ return dartClassFromJtdSchema(nodePath, def, additionalOptions);
326
+ }
327
+ if (codegenUtils.isSchemaFormElements(def)) {
328
+ return dartArrayFromJtdSchema(nodePath, def, additionalOptions);
329
+ }
330
+ if (codegenUtils.isSchemaFormEnum(def)) {
331
+ return dartEnumFromJtdSchema(nodePath, def, additionalOptions);
332
+ }
333
+ if (codegenUtils.isSchemaFormValues(def)) {
334
+ return dartMapFromJtdSchema(nodePath, def, additionalOptions);
335
+ }
336
+ if (codegenUtils.isSchemaFormDiscriminator(def)) {
337
+ return dartSealedClassFromJtdSchema(nodePath, def, additionalOptions);
338
+ }
339
+ if (codegenUtils.isSchemaFormRef(def)) {
340
+ return dartRefFromJtdSchema(nodePath, def, additionalOptions);
341
+ }
342
+ return dartDynamicFromAny(nodePath, schema.a.any(), additionalOptions);
343
+ }
344
+ function dartClassFromJtdSchema(nodePath, def, additionalOptions) {
345
+ const isException = additionalOptions?.isException ?? false;
346
+ const discOptions = additionalOptions?.discriminatorOptions;
347
+ const isDiscriminatorChild = (discOptions?.discriminatorKey.length ?? 0) > 0;
348
+ const jsonKey = nodePath.split(".").pop() ?? "";
349
+ const key = camelCaseWrapper(jsonKey);
350
+ let className = def.metadata?.id ? codegenUtils.pascalCase(def.metadata.id) : void 0;
351
+ if (!className) {
352
+ const relativePath = nodePath.split(".").pop();
353
+ if (additionalOptions.parentId && relativePath) {
354
+ className = codegenUtils.pascalCase(
355
+ `${additionalOptions.parentId}_${relativePath}`
356
+ );
357
+ } else {
358
+ className = codegenUtils.pascalCase(nodePath.split(".").join("_"));
359
+ }
360
+ }
361
+ const properties = [];
362
+ const optionalProperties = [];
363
+ const subContentParts = [];
364
+ if (!def.properties) {
365
+ return {
366
+ typeName: "",
367
+ fieldTemplate: "",
368
+ constructorTemplate: "",
369
+ fromJsonTemplate: () => "",
370
+ toJsonTemplate: () => "",
371
+ content: ""
372
+ };
373
+ }
374
+ for (const key2 of Object.keys(def.properties ?? {})) {
375
+ const keyPath = `${nodePath}.${key2}`;
376
+ const prop = def.properties[key2];
377
+ const mappedProp = dartTypeFromJtdSchema(keyPath, prop, {
378
+ parentId: className,
379
+ isOptional: false,
380
+ existingClassNames: additionalOptions.existingClassNames
381
+ });
382
+ properties.push({
383
+ key: key2,
384
+ templates: mappedProp
385
+ });
386
+ if (mappedProp?.content) {
387
+ subContentParts.push(mappedProp.content);
388
+ }
389
+ }
390
+ if (def.optionalProperties) {
391
+ for (const key2 of Object.keys(def.optionalProperties ?? {})) {
392
+ const keyPath = `${nodePath}.${key2}`;
393
+ const prop = def.optionalProperties[key2];
394
+ const mappedProp = dartTypeFromJtdSchema(keyPath, prop, {
395
+ parentId: className,
396
+ isOptional: true,
397
+ existingClassNames: additionalOptions.existingClassNames
398
+ });
399
+ optionalProperties.push({ key: key2, templates: mappedProp });
400
+ if (mappedProp?.content) {
401
+ subContentParts.push(mappedProp.content);
402
+ }
403
+ }
404
+ }
405
+ const fieldParts = [];
406
+ const constructorParts = [];
407
+ const fromJsonParts = [];
408
+ const copyWithParamParts = [];
409
+ const copyWithInitParts = [];
410
+ if (discOptions) {
411
+ fieldParts.push(`@override
412
+ final String ${camelCaseWrapper(discOptions.discriminatorKey)} = "${discOptions.discriminatorValue}"`);
413
+ }
414
+ for (const prop of properties) {
415
+ fieldParts.push(prop.templates.fieldTemplate);
416
+ constructorParts.push(prop.templates.constructorTemplate);
417
+ const subJsonKey = prop.key;
418
+ const subKey = camelCaseWrapper(prop.key);
419
+ fromJsonParts.push(
420
+ `${subKey}: ${prop.templates.fromJsonTemplate(
421
+ `json["${subJsonKey}"]`
422
+ )}`
423
+ );
424
+ if (prop.templates.typeName === "dynamic") {
425
+ copyWithParamParts.push(`dynamic ${subKey}`);
426
+ copyWithInitParts.push(`${subKey}: ${subKey} ?? this.${subKey}`);
427
+ } else {
428
+ if (prop.templates.typeName.endsWith("?")) {
429
+ copyWithParamParts.push(
430
+ `ArriBox<${prop.templates.typeName}>? ${subKey}`
431
+ );
432
+ copyWithInitParts.push(
433
+ `${subKey}: ${subKey} != null ? ${subKey}.value : this.${subKey}`
434
+ );
435
+ } else {
436
+ copyWithParamParts.push(
437
+ `${prop.templates.typeName}? ${subKey}`
438
+ );
439
+ copyWithInitParts.push(
440
+ `${subKey}: ${subKey} ?? this.${subKey}`
441
+ );
442
+ }
443
+ }
444
+ }
445
+ for (const prop of optionalProperties) {
446
+ fieldParts.push(prop.templates.fieldTemplate);
447
+ constructorParts.push(prop.templates.constructorTemplate);
448
+ const subKey = camelCaseWrapper(prop.key);
449
+ const subJsonKey = prop.key;
450
+ fromJsonParts.push(
451
+ `${subKey}: ${prop.templates.fromJsonTemplate(
452
+ `json["${subJsonKey}"]`
453
+ )}`
454
+ );
455
+ if (prop.templates.typeName === "dynamic") {
456
+ copyWithParamParts.push(`dynamic ${subKey}`);
457
+ copyWithInitParts.push(`${subKey}: ${subKey} ?? this.${subKey}`);
458
+ } else {
459
+ if (prop.templates.typeName.endsWith("?")) {
460
+ copyWithParamParts.push(
461
+ `ArriBox<${prop.templates.typeName}>? ${subKey}`
462
+ );
463
+ copyWithInitParts.push(
464
+ `${subKey}: ${subKey} != null ? ${subKey}.value : this.${subKey}`
465
+ );
466
+ } else {
467
+ copyWithParamParts.push(
468
+ `${prop.templates.typeName}? ${subKey}`
469
+ );
470
+ copyWithInitParts.push(
471
+ `${subKey}: ${subKey} ?? this.${subKey}`
472
+ );
473
+ }
474
+ }
475
+ }
476
+ let classNamePart = `class ${className}`;
477
+ if (isDiscriminatorChild) {
478
+ classNamePart += ` implements ${discOptions?.discriminatorParentClassName}`;
479
+ } else if (isException) {
480
+ classNamePart += ` implements Exception`;
481
+ }
482
+ let content = `${getAnnotations(def.metadata)}${classNamePart} {
483
+ ${fieldParts.join(";\n ")};
484
+ const ${className}({
485
+ ${constructorParts.join(",\n ")},
486
+ });
487
+ factory ${className}.fromJson(Map<String, dynamic> json) {
488
+ return ${className}(
489
+ ${fromJsonParts.join(",\n ")},
490
+ );
491
+ }
492
+ ${isDiscriminatorChild ? `@override` : ""}
493
+ Map<String, dynamic> toJson() {
494
+ final __result = <String, dynamic>{${isDiscriminatorChild ? `
495
+ "${discOptions?.discriminatorKey}": ${camelCaseWrapper(
496
+ discOptions?.discriminatorKey ?? ""
497
+ )},` : ""}
498
+ ${properties.map(
499
+ (prop) => `"${prop.key}": ${prop.templates.toJsonTemplate(
500
+ camelCaseWrapper(prop.key)
501
+ )}`
502
+ ).join(",\n ")}${properties.length ? "," : ""}
503
+ };
504
+ ${optionalProperties.map(
505
+ (prop) => `if (${camelCaseWrapper(prop.key)} != null) {
506
+ __result["${prop.key}"] = ${prop.templates.toJsonTemplate(
507
+ camelCaseWrapper(prop.key)
508
+ )};
509
+ }`
510
+ ).join("\n")}
511
+ return __result;
512
+ }
513
+ ${className} copyWith({
514
+ ${copyWithParamParts.join(",\n ")},
515
+ }) {
516
+ return ${className}(
517
+ ${copyWithInitParts.join(",\n ")},
518
+ );
519
+ }
520
+ }
521
+ ${subContentParts.join("\n")}
522
+
523
+ `;
524
+ if (additionalOptions.existingClassNames.includes(className)) {
525
+ content = "";
526
+ } else {
527
+ additionalOptions.existingClassNames.push(className);
528
+ }
529
+ const isNullable = def.nullable ?? additionalOptions?.isOptional;
530
+ const typeName = isNullable ? `${className}?` : className;
531
+ return {
532
+ typeName,
533
+ fieldTemplate: fieldTemplateString(
534
+ typeName,
535
+ key,
536
+ def.metadata?.description,
537
+ def.metadata?.isDeprecated
538
+ ),
539
+ constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
540
+ fromJsonTemplate: (input) => isNullable ? `${input} is Map<String, dynamic> ? ${className}.fromJson(${input}) : null` : `${className}.fromJson(${input})`,
541
+ toJsonTemplate: (input) => `${input}${isNullable ? "?" : ""}.toJson()`,
542
+ content
543
+ };
544
+ }
545
+ function dartDynamicFromAny(nodePath, def, additionalOptions) {
546
+ const jsonKey = nodePath.split(".").pop() ?? "";
547
+ const key = camelCaseWrapper(jsonKey);
548
+ return {
549
+ typeName: "dynamic",
550
+ fieldTemplate: fieldTemplateString(
551
+ "dynamic",
552
+ key,
553
+ def.metadata?.description,
554
+ def.metadata?.isDeprecated
555
+ ),
556
+ constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
557
+ fromJsonTemplate: (input) => `${input}`,
558
+ toJsonTemplate: (input) => input,
559
+ content: ""
560
+ };
561
+ }
562
+ function fieldTemplateString(typeName, key, description, deprecated) {
563
+ let result = "";
564
+ if (deprecated) {
565
+ result += `@deprecated
566
+ `;
567
+ }
568
+ if (description) {
569
+ const parts = description.split("\n");
570
+ for (const part of parts) {
571
+ result += `/// ${part}
572
+ `;
573
+ }
574
+ }
575
+ result += `final ${typeName} ${key}`;
576
+ return result;
577
+ }
578
+ function dartArrayFromJtdSchema(nodePath, def, additionalOptions) {
579
+ const isNullable = additionalOptions.isOptional || (def.nullable ?? false);
580
+ const jsonKey = nodePath.split(".").pop() ?? "";
581
+ const key = camelCaseWrapper(jsonKey);
582
+ const subtype = dartTypeFromJtdSchema(`${nodePath}.Item`, def.elements, {
583
+ existingClassNames: additionalOptions.existingClassNames,
584
+ isOptional: false
585
+ });
586
+ const typeName = isNullable ? `List<${subtype.typeName}>?` : `List<${subtype.typeName}>`;
587
+ return {
588
+ typeName,
589
+ fieldTemplate: fieldTemplateString(
590
+ typeName,
591
+ key,
592
+ def.metadata?.description,
593
+ def.metadata?.isDeprecated
594
+ ),
595
+ constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
596
+ fromJsonTemplate: (input) => {
597
+ if (isNullable) {
598
+ return `${input} is List ?
599
+ // ignore: unnecessary_cast
600
+ (${input} as List).map((item) => ${subtype.fromJsonTemplate(
601
+ "item"
602
+ )}).toList() as ${typeName} : null`;
603
+ }
604
+ return `${input} is List ?
605
+ // ignore: unnecessary_cast
606
+ (${input} as List).map((item) => ${subtype.fromJsonTemplate(
607
+ "item"
608
+ )}).toList() as ${typeName} : <${subtype.typeName}>[]`;
609
+ },
610
+ toJsonTemplate: (input) => {
611
+ return `${input}${isNullable ? "?" : ""}.map((item) => ${subtype.toJsonTemplate("item")}).toList()`;
612
+ },
613
+ content: subtype.content
614
+ };
615
+ }
616
+ function dartScalarFromJtdScalar(nodePath, def, additionalOptions) {
617
+ const isNullable = additionalOptions.isOptional || (def.nullable ?? false);
618
+ const jsonKey = nodePath.split(".").pop() ?? "";
619
+ const key = camelCaseWrapper(jsonKey);
620
+ const defaultInitializationTemplate = additionalOptions.isOptional ? `this.${key}` : `required this.${key}`;
621
+ const { description } = def.metadata ?? {};
622
+ const defaultToJsonTemplate = (input) => input;
623
+ switch (def.type) {
624
+ case "boolean":
625
+ if (isNullable) {
626
+ return {
627
+ typeName: "bool?",
628
+ fieldTemplate: fieldTemplateString(
629
+ "bool?",
630
+ key,
631
+ description,
632
+ def.metadata?.isDeprecated
633
+ ),
634
+ constructorTemplate: defaultInitializationTemplate,
635
+ fromJsonTemplate: (input) => `nullableTypeFromDynamic<bool>(${input})`,
636
+ toJsonTemplate: defaultToJsonTemplate,
637
+ content: ""
638
+ };
639
+ }
640
+ return {
641
+ typeName: "bool",
642
+ fieldTemplate: fieldTemplateString(
643
+ "bool",
644
+ key,
645
+ description,
646
+ def.metadata?.isDeprecated
647
+ ),
648
+ constructorTemplate: defaultInitializationTemplate,
649
+ fromJsonTemplate: (input) => `typeFromDynamic<bool>(${input}, false)`,
650
+ toJsonTemplate: defaultToJsonTemplate,
651
+ content: ""
652
+ };
653
+ case "float32":
654
+ case "float64":
655
+ if (isNullable) {
656
+ return {
657
+ typeName: "double?",
658
+ fieldTemplate: fieldTemplateString(
659
+ "double?",
660
+ key,
661
+ description,
662
+ def.metadata?.isDeprecated
663
+ ),
664
+ constructorTemplate: defaultInitializationTemplate,
665
+ fromJsonTemplate: (input) => `nullableDoubleFromDynamic(${input})`,
666
+ toJsonTemplate: defaultToJsonTemplate,
667
+ content: ""
668
+ };
669
+ }
670
+ return {
671
+ typeName: "double",
672
+ fieldTemplate: fieldTemplateString(
673
+ "double",
674
+ key,
675
+ description,
676
+ def.metadata?.isDeprecated
677
+ ),
678
+ constructorTemplate: defaultInitializationTemplate,
679
+ fromJsonTemplate: (input) => `doubleFromDynamic(${input}, 0)`,
680
+ toJsonTemplate: defaultToJsonTemplate,
681
+ content: ""
682
+ };
683
+ case "int16":
684
+ case "int32":
685
+ case "int8":
686
+ case "uint16":
687
+ case "uint32":
688
+ case "uint8":
689
+ if (isNullable) {
690
+ return {
691
+ typeName: "int?",
692
+ fieldTemplate: fieldTemplateString(
693
+ "int?",
694
+ key,
695
+ description,
696
+ def.metadata?.isDeprecated
697
+ ),
698
+ constructorTemplate: defaultInitializationTemplate,
699
+ fromJsonTemplate: (input) => `nullableIntFromDynamic(${input})`,
700
+ toJsonTemplate: defaultToJsonTemplate,
701
+ content: ""
702
+ };
703
+ }
704
+ return {
705
+ typeName: "int",
706
+ fieldTemplate: fieldTemplateString(
707
+ `int`,
708
+ key,
709
+ description,
710
+ def.metadata?.isDeprecated
711
+ ),
712
+ constructorTemplate: defaultInitializationTemplate,
713
+ fromJsonTemplate: (input) => `intFromDynamic(${input}, 0)`,
714
+ toJsonTemplate: defaultToJsonTemplate,
715
+ content: ""
716
+ };
717
+ case "int64":
718
+ case "uint64":
719
+ if (isNullable) {
720
+ return {
721
+ typeName: "BigInt?",
722
+ fieldTemplate: fieldTemplateString(
723
+ `BigInt?`,
724
+ key,
725
+ description,
726
+ def.metadata?.isDeprecated
727
+ ),
728
+ constructorTemplate: defaultInitializationTemplate,
729
+ fromJsonTemplate: (input) => `nullableBigIntFromDynamic(${input})`,
730
+ toJsonTemplate: (input) => `${input}?.toString()`,
731
+ content: ""
732
+ };
733
+ }
734
+ return {
735
+ typeName: "BigInt",
736
+ fieldTemplate: fieldTemplateString(
737
+ `BigInt`,
738
+ key,
739
+ description,
740
+ def.metadata?.isDeprecated
741
+ ),
742
+ constructorTemplate: defaultInitializationTemplate,
743
+ fromJsonTemplate: (input) => `bigIntFromDynamic(${input}, BigInt.zero)`,
744
+ toJsonTemplate: (input) => `${input}.toString()`,
745
+ content: ""
746
+ };
747
+ case "timestamp":
748
+ if (isNullable) {
749
+ return {
750
+ typeName: "DateTime?",
751
+ fieldTemplate: fieldTemplateString(
752
+ "DateTime?",
753
+ key,
754
+ description,
755
+ def.metadata?.isDeprecated
756
+ ),
757
+ constructorTemplate: defaultInitializationTemplate,
758
+ fromJsonTemplate: (input) => `nullableDateTimeFromDynamic(${input})`,
759
+ toJsonTemplate: (input) => `${input}?.toUtc().toIso8601String()`,
760
+ content: ""
761
+ };
762
+ }
763
+ return {
764
+ typeName: "DateTime",
765
+ fieldTemplate: fieldTemplateString(
766
+ "DateTime",
767
+ key,
768
+ description,
769
+ def.metadata?.isDeprecated
770
+ ),
771
+ constructorTemplate: defaultInitializationTemplate,
772
+ fromJsonTemplate: (input) => `dateTimeFromDynamic(
773
+ ${input},
774
+ DateTime.fromMillisecondsSinceEpoch(0),
775
+ )`,
776
+ toJsonTemplate: (input) => `${input}.toUtc().toIso8601String()`,
777
+ content: ""
778
+ };
779
+ case "string":
780
+ if (isNullable) {
781
+ return {
782
+ typeName: "String?",
783
+ fieldTemplate: fieldTemplateString(
784
+ "String?",
785
+ key,
786
+ description,
787
+ def.metadata?.isDeprecated
788
+ ),
789
+ constructorTemplate: defaultInitializationTemplate,
790
+ fromJsonTemplate: (input) => `nullableTypeFromDynamic<String>(${input})`,
791
+ toJsonTemplate: defaultToJsonTemplate,
792
+ content: ""
793
+ };
794
+ }
795
+ return {
796
+ typeName: "String",
797
+ fieldTemplate: fieldTemplateString(
798
+ "String",
799
+ key,
800
+ description,
801
+ def.metadata?.isDeprecated
802
+ ),
803
+ constructorTemplate: defaultInitializationTemplate,
804
+ fromJsonTemplate: (input) => `typeFromDynamic<String>(${input}, "")`,
805
+ toJsonTemplate: defaultToJsonTemplate,
806
+ content: ""
807
+ };
808
+ default:
809
+ return {
810
+ typeName: "dynamic",
811
+ fieldTemplate: fieldTemplateString(
812
+ "dynamic",
813
+ key,
814
+ description,
815
+ def.metadata?.isDeprecated
816
+ ),
817
+ constructorTemplate: defaultInitializationTemplate,
818
+ fromJsonTemplate: (input) => input,
819
+ toJsonTemplate: defaultToJsonTemplate,
820
+ content: ""
821
+ };
822
+ }
823
+ }
824
+ function dartEnumFromJtdSchema(nodePath, def, additionalOptions) {
825
+ const isNullable = additionalOptions.isOptional || (def.nullable ?? false);
826
+ const jsonKey = nodePath.split(".").pop() ?? "";
827
+ const key = camelCaseWrapper(jsonKey);
828
+ let className = def.metadata?.id ? codegenUtils.pascalCase(def.metadata.id) : void 0;
829
+ if (!className) {
830
+ className = codegenUtils.pascalCase(nodePath.split(".").join("_"));
831
+ }
832
+ const valNames = [];
833
+ const fieldParts = [];
834
+ for (const val of def.enum) {
835
+ valNames.push(`${camelCaseWrapper(val)}`);
836
+ fieldParts.push(`${camelCaseWrapper(val)}("${val}")`);
837
+ }
838
+ let content = `${getAnnotations(def.metadata)}enum ${className} implements Comparable<${className}> {
839
+ ${fieldParts.join(",\n ")};
840
+ const ${className}(this.value);
841
+ final String value;
842
+
843
+ factory ${className}.fromJson(dynamic json) {
844
+ for(final v in values) {
845
+ if(v.value == json) {
846
+ return v;
847
+ }
848
+ }
849
+ return ${valNames[0]};
850
+ }
851
+
852
+ @override
853
+ compareTo(${className} other) => name.compareTo(other.name);
854
+ }`;
855
+ if (additionalOptions.existingClassNames.includes(className)) {
856
+ content = "";
857
+ } else {
858
+ additionalOptions.existingClassNames.push(className);
859
+ }
860
+ return {
861
+ typeName: className,
862
+ fieldTemplate: fieldTemplateString(
863
+ isNullable ? `${className}?` : className,
864
+ key,
865
+ def.metadata?.description,
866
+ def.metadata?.isDeprecated
867
+ ),
868
+ constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
869
+ fromJsonTemplate: (input) => {
870
+ if (isNullable) {
871
+ return `${input} is String ? ${className}.fromJson(${input}) : null`;
872
+ }
873
+ return `${className}.fromJson(${input})`;
874
+ },
875
+ toJsonTemplate: (input) => `${input}${isNullable ? "?" : ""}.value`,
876
+ content
877
+ };
878
+ }
879
+ function dartMapFromJtdSchema(nodePath, def, additionalOptions) {
880
+ const isNullable = additionalOptions.isOptional || (def.nullable ?? false);
881
+ const jsonKey = nodePath.split(".").pop() ?? "";
882
+ const key = camelCaseWrapper(jsonKey);
883
+ const innerType = dartTypeFromJtdSchema(`${nodePath}.Value`, def.values, {
884
+ existingClassNames: additionalOptions.existingClassNames,
885
+ isOptional: false
886
+ });
887
+ const typeName = `Map<String, ${innerType.typeName}>${isNullable ? "?" : ""}`;
888
+ return {
889
+ typeName: isNullable ? `Map<String, ${innerType.typeName}>?` : `Map<String, ${innerType.typeName}>`,
890
+ fieldTemplate: fieldTemplateString(
891
+ typeName,
892
+ key,
893
+ def.metadata?.description,
894
+ def.metadata?.isDeprecated
895
+ ),
896
+ constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
897
+ fromJsonTemplate: (input) => `${input} is Map<String, dynamic>
898
+ ? (${input} as Map<String, dynamic>).map(
899
+ (key, value) => MapEntry(key, ${innerType.fromJsonTemplate(
900
+ "value"
901
+ )}))
902
+ : <String, ${innerType.typeName}>{}`,
903
+ toJsonTemplate: (input) => `${input}${isNullable ? "?" : ""}.map((key, value) => MapEntry(key, ${innerType.toJsonTemplate(
904
+ "value"
905
+ )}))`,
906
+ content: innerType.content
907
+ };
908
+ }
909
+ function dartSealedClassFromJtdSchema(nodePath, def, additionalOptions) {
910
+ const className = def.metadata?.id ? codegenUtils.pascalCase(def.metadata?.id) : codegenUtils.pascalCase(nodePath.split(".").join("_"));
911
+ const isNullable = additionalOptions.isOptional || (def.nullable ?? false);
912
+ const jsonKey = nodePath.split(".").pop() ?? "";
913
+ const key = camelCaseWrapper(jsonKey);
914
+ const discriminatorJsonKey = def.discriminator;
915
+ const discriminatorKey = camelCaseWrapper(def.discriminator);
916
+ const fromJsonCaseParts = [];
917
+ const childContentParts = [];
918
+ Object.keys(def.mapping).forEach((discKeyValue) => {
919
+ const childDef = def.mapping[discKeyValue];
920
+ if (!codegenUtils.isSchemaFormProperties(childDef)) {
921
+ return;
922
+ }
923
+ const child = dartClassFromJtdSchema(
924
+ `${nodePath}.${camelCaseWrapper(discKeyValue.toLowerCase())}`,
925
+ childDef,
926
+ {
927
+ parentId: className,
928
+ isOptional: false,
929
+ existingClassNames: additionalOptions.existingClassNames,
930
+ discriminatorOptions: {
931
+ discriminatorKey,
932
+ discriminatorValue: discKeyValue,
933
+ discriminatorParentClassName: className
934
+ }
935
+ }
936
+ );
937
+ fromJsonCaseParts.push(`case "${discKeyValue}":
938
+ return ${child.typeName}.fromJson(json);`);
939
+ childContentParts.push(child.content);
940
+ });
941
+ let content = "";
942
+ if (!additionalOptions.existingClassNames.includes(className)) {
943
+ content = `${getAnnotations(def.metadata)}sealed class ${className} {
944
+ final String ${discriminatorKey};
945
+ const ${className}({
946
+ required this.${discriminatorKey},
947
+ });
948
+ factory ${className}.fromJson(Map<String, dynamic> json) {
949
+ if(json["${discriminatorJsonKey}"] is! String) {
950
+ throw Exception(
951
+ "Unable to decode ${className}. Expected String from \\"${discriminatorJsonKey}\\". Received \${json["${discriminatorJsonKey}"]}}",
952
+ );
953
+ }
954
+ switch (json["${discriminatorJsonKey}"]) {
955
+ ${fromJsonCaseParts.join("\n ")}
956
+ }
957
+ throw Exception(
958
+ "Unable to decode ${className}. \\"\${json["${discriminatorJsonKey}"]}\\" doesn't match any of the accepted discriminator values.",
959
+ );
960
+ }
961
+ Map<String, dynamic> toJson();
962
+ }
963
+ ${childContentParts.join("\n")}`;
964
+ additionalOptions.existingClassNames.push(className);
965
+ }
966
+ const typeName = `${className}${isNullable ? "?" : ""}`;
967
+ return {
968
+ typeName,
969
+ fieldTemplate: fieldTemplateString(
970
+ typeName,
971
+ key,
972
+ def.metadata?.description,
973
+ def.metadata?.isDeprecated
974
+ ),
975
+ constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
976
+ fromJsonTemplate: (input) => {
977
+ if (isNullable) {
978
+ return `${input} is Map<String, dynamic> ? ${className}.fromJson(${input}) : null`;
979
+ }
980
+ return `${className}.fromJson(${input})`;
981
+ },
982
+ toJsonTemplate: (input) => {
983
+ if (isNullable) {
984
+ return `${input}?.toJson()`;
985
+ }
986
+ return `${input}.toJson()`;
987
+ },
988
+ content
989
+ };
990
+ }
991
+ function dartRefFromJtdSchema(nodePath, def, additionalOptions) {
992
+ const jsonKey = nodePath.split(".").pop() ?? "";
993
+ const key = camelCaseWrapper(jsonKey);
994
+ const className = codegenUtils.pascalCase(def.ref, { normalize: true });
995
+ const isNullable = additionalOptions.isOptional || (def.nullable ?? false);
996
+ const typeName = `${className}${isNullable ? "?" : ""}`;
997
+ return {
998
+ typeName,
999
+ fieldTemplate: fieldTemplateString(
1000
+ typeName,
1001
+ key,
1002
+ def.metadata?.description,
1003
+ def.metadata?.isDeprecated
1004
+ ),
1005
+ constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
1006
+ fromJsonTemplate(input) {
1007
+ if (isNullable) {
1008
+ return `${input} is Map<String, dynamic> ? ${className}.fromJson(${input}) : null`;
1009
+ }
1010
+ return `${className}.fromJson(${input})`;
1011
+ },
1012
+ toJsonTemplate(input) {
1013
+ if (isNullable) {
1014
+ return `${input}?.toJson()`;
1015
+ }
1016
+ return `${input}.toJson()`;
1017
+ },
1018
+ content: ""
1019
+ };
1020
+ }
1021
+
1022
+ exports.DartClientGenerator = DartClientGenerator;
1023
+ exports.createDartClient = createDartClient;
1024
+ exports.dartClassFromJtdSchema = dartClassFromJtdSchema;
1025
+ exports.dartClientGenerator = dartClientGenerator;
1026
+ exports.dartHttpRpcFromSchema = dartHttpRpcFromSchema;
1027
+ exports.dartRpcFromDefinition = dartRpcFromDefinition;
1028
+ exports.dartServiceFromDefinition = dartServiceFromDefinition;
1029
+ exports.dartTypeFromJtdSchema = dartTypeFromJtdSchema;
1030
+ exports.dartWsRpcFromSchema = dartWsRpcFromSchema;
1031
+ exports.getAnnotations = getAnnotations;