@arrirpc/codegen-dart 0.49.1 → 0.51.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -5
- package/dist/index.cjs +1114 -914
- package/dist/index.d.cts +26 -38
- package/dist/index.d.mts +26 -38
- package/dist/index.d.ts +26 -38
- package/dist/index.mjs +1121 -919
- package/package.json +4 -3
package/dist/index.cjs
CHANGED
@@ -1,1032 +1,1232 @@
|
|
1
1
|
'use strict';
|
2
2
|
|
3
|
+
const node_child_process = require('node:child_process');
|
4
|
+
const fs = require('node:fs/promises');
|
3
5
|
const codegenUtils = require('@arrirpc/codegen-utils');
|
4
|
-
const
|
5
|
-
const child_process = require('child_process');
|
6
|
-
const fs = require('fs');
|
6
|
+
const path = require('pathe');
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
8
|
+
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
9
|
+
|
10
|
+
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
11
|
+
const path__default = /*#__PURE__*/_interopDefaultCompat(path);
|
12
|
+
|
13
|
+
function outputIsNullable(schema, context) {
|
14
|
+
if (schema.nullable) {
|
15
|
+
return true;
|
16
|
+
}
|
17
|
+
if (context.isOptional) {
|
18
|
+
return true;
|
17
19
|
}
|
18
|
-
return
|
20
|
+
return false;
|
19
21
|
}
|
20
|
-
const
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
22
|
+
const reservedIdentifierKeywords = {
|
23
|
+
abstract: 2,
|
24
|
+
as: 2,
|
25
|
+
assert: 0,
|
26
|
+
async: 3,
|
27
|
+
await: 1,
|
28
|
+
base: 3,
|
29
|
+
break: 0,
|
30
|
+
case: 0,
|
31
|
+
catch: 0,
|
32
|
+
class: 0,
|
33
|
+
const: 0,
|
34
|
+
continue: 0,
|
35
|
+
covariant: 2,
|
36
|
+
default: 0,
|
37
|
+
deferred: 2,
|
38
|
+
do: 0,
|
39
|
+
dynamic: 2,
|
40
|
+
else: 0,
|
41
|
+
enum: 0,
|
42
|
+
export: 2,
|
43
|
+
extends: 0,
|
44
|
+
extension: 2,
|
45
|
+
external: 2,
|
46
|
+
factory: 2,
|
47
|
+
false: 0,
|
48
|
+
final: 0,
|
49
|
+
finally: 0,
|
50
|
+
for: 0,
|
51
|
+
Function: 2,
|
52
|
+
get: 2,
|
53
|
+
hide: 3,
|
54
|
+
if: 0,
|
55
|
+
implements: 2,
|
56
|
+
import: 2,
|
57
|
+
in: 0,
|
58
|
+
interface: 2,
|
59
|
+
is: 0,
|
60
|
+
late: 2,
|
61
|
+
library: 2,
|
62
|
+
mixin: 2,
|
63
|
+
new: 0,
|
64
|
+
null: 0,
|
65
|
+
of: 3,
|
66
|
+
on: 3,
|
67
|
+
operator: 2,
|
68
|
+
part: 2,
|
69
|
+
required: 2,
|
70
|
+
rethrow: 0,
|
71
|
+
return: 0,
|
72
|
+
sealed: 3,
|
73
|
+
set: 2,
|
74
|
+
show: 3,
|
75
|
+
static: 2,
|
76
|
+
super: 0,
|
77
|
+
switch: 0,
|
78
|
+
sync: 3,
|
79
|
+
this: 0,
|
80
|
+
throw: 0,
|
81
|
+
true: 0,
|
82
|
+
try: 0,
|
83
|
+
type: 2,
|
84
|
+
typedef: 2,
|
85
|
+
var: 0,
|
86
|
+
void: 0,
|
87
|
+
when: 3,
|
88
|
+
with: 0,
|
89
|
+
while: 0,
|
90
|
+
yield: 1
|
91
|
+
};
|
92
|
+
function canUseIdentifier(input) {
|
93
|
+
const reservedId = reservedIdentifierKeywords[input];
|
94
|
+
if (typeof reservedId === "undefined") {
|
95
|
+
return true;
|
50
96
|
}
|
51
|
-
)
|
52
|
-
|
53
|
-
|
54
|
-
|
97
|
+
switch (reservedId) {
|
98
|
+
case 0:
|
99
|
+
return false;
|
100
|
+
case 1:
|
101
|
+
return true;
|
102
|
+
case 2:
|
103
|
+
return true;
|
104
|
+
case 3:
|
105
|
+
return true;
|
106
|
+
default:
|
107
|
+
throw new Error("Unhandled case");
|
55
108
|
}
|
56
109
|
}
|
57
|
-
function
|
58
|
-
const
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
}
|
110
|
+
function sanitizeIdentifier(input) {
|
111
|
+
const bannedCharacters = "!@#$%^&*()-=+[{}]\\|/?.><,;`~";
|
112
|
+
const result = codegenUtils.removeDisallowedChars(input, bannedCharacters);
|
113
|
+
const numbers = "0123456789";
|
114
|
+
if (numbers.includes(result.charAt(0))) {
|
115
|
+
return `k_${result}`;
|
64
116
|
}
|
65
|
-
|
66
|
-
|
117
|
+
return result;
|
118
|
+
}
|
119
|
+
function canUseClassName(input) {
|
120
|
+
const reservedId = reservedIdentifierKeywords[input];
|
121
|
+
if (typeof reservedId === "undefined") {
|
122
|
+
return true;
|
67
123
|
}
|
68
|
-
|
69
|
-
|
124
|
+
switch (reservedId) {
|
125
|
+
case 0:
|
126
|
+
return false;
|
127
|
+
case 1:
|
128
|
+
return false;
|
129
|
+
case 2:
|
130
|
+
return false;
|
131
|
+
case 3:
|
132
|
+
return true;
|
133
|
+
default:
|
134
|
+
throw new Error("Unhandled case");
|
70
135
|
}
|
71
|
-
return `${commentParts.join("\n")}
|
72
|
-
`;
|
73
136
|
}
|
74
|
-
function
|
75
|
-
const
|
76
|
-
|
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,
|
137
|
+
function validDartIdentifier(input) {
|
138
|
+
const finalIdentifier = sanitizeIdentifier(
|
139
|
+
codegenUtils.camelCase(input, { normalize: true })
|
103
140
|
);
|
104
|
-
|
105
|
-
}
|
141
|
+
if (!canUseIdentifier(finalIdentifier)) {
|
142
|
+
return `k_${finalIdentifier}`;
|
106
143
|
}
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
}
|
144
|
+
return finalIdentifier;
|
145
|
+
}
|
146
|
+
function validDartClassName(input, modelPrefix) {
|
147
|
+
const className = sanitizeIdentifier(
|
148
|
+
codegenUtils.pascalCase(input, { normalize: true })
|
149
|
+
);
|
150
|
+
if (canUseClassName(className) || modelPrefix.length) {
|
151
|
+
return className;
|
116
152
|
}
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
${modelParts.join("\n")}`;
|
153
|
+
return `Class${className}`;
|
154
|
+
}
|
155
|
+
function getDartClassName(schema, context) {
|
156
|
+
if (schema.metadata?.id) {
|
157
|
+
return validDartClassName(schema.metadata.id, context.modelPrefix);
|
123
158
|
}
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
final String _clientVersion = "${def.info?.version ?? ""}";
|
135
|
-
late final FutureOr<Map<String, String>> Function()? _headers;
|
136
|
-
${opts.clientName}({
|
137
|
-
http.Client? httpClient,
|
138
|
-
String baseUrl = "",
|
139
|
-
FutureOr<Map<String, String>> Function()? headers,
|
140
|
-
}) : _httpClient = httpClient,
|
141
|
-
_baseUrl = baseUrl,
|
142
|
-
_headers = headers;
|
143
|
-
${rpcParts.join("\n ")}
|
144
|
-
${serviceGetterParts.join("\n ")}
|
159
|
+
if (context.discriminatorParentId) {
|
160
|
+
return validDartClassName(
|
161
|
+
`${context.discriminatorParentId}_${context.discriminatorValue}`,
|
162
|
+
context.modelPrefix
|
163
|
+
);
|
164
|
+
}
|
165
|
+
return validDartClassName(
|
166
|
+
context.instancePath.split("/").join("_"),
|
167
|
+
context.modelPrefix
|
168
|
+
);
|
145
169
|
}
|
146
170
|
|
147
|
-
|
171
|
+
function dartAnyFromSchema(schema, context) {
|
172
|
+
const typeName = `dynamic`;
|
173
|
+
const isNullable = outputIsNullable(schema, context);
|
174
|
+
const defaultValue = `null`;
|
175
|
+
return {
|
176
|
+
typeName,
|
177
|
+
isNullable,
|
178
|
+
defaultValue,
|
179
|
+
fromJson(input) {
|
180
|
+
return `${input}`;
|
181
|
+
},
|
182
|
+
toJson(input) {
|
183
|
+
return input;
|
184
|
+
},
|
185
|
+
toQueryString() {
|
186
|
+
return `print("[WARNING] any's cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
|
187
|
+
},
|
188
|
+
content: ""
|
189
|
+
};
|
190
|
+
}
|
148
191
|
|
149
|
-
|
150
|
-
|
192
|
+
function dartListFromSchema(schema, context) {
|
193
|
+
const isNullable = outputIsNullable(schema, context);
|
194
|
+
const innerType = dartTypeFromSchema(schema.elements, {
|
195
|
+
clientName: context.clientName,
|
196
|
+
modelPrefix: context.modelPrefix,
|
197
|
+
generatedTypes: context.generatedTypes,
|
198
|
+
instancePath: `${context.instancePath}/[Element]`,
|
199
|
+
schemaPath: `${context.schemaPath}/elements`
|
200
|
+
});
|
201
|
+
const typeName = isNullable ? `List<${innerType.typeName}>?` : `List<${innerType.typeName}>`;
|
202
|
+
const defaultValue = isNullable ? "null" : "[]";
|
203
|
+
return {
|
204
|
+
typeName,
|
205
|
+
isNullable,
|
206
|
+
defaultValue,
|
207
|
+
fromJson(input) {
|
208
|
+
if (isNullable) {
|
209
|
+
return `${input} is List
|
210
|
+
? (${input} as List)
|
211
|
+
.map((_el_) => ${innerType.fromJson(`_el_`)})
|
212
|
+
.toList()
|
213
|
+
: null`;
|
214
|
+
}
|
215
|
+
return `${input} is List
|
216
|
+
? (${input} as List)
|
217
|
+
.map((_el_) => ${innerType.fromJson(`_el_`)})
|
218
|
+
.toList()
|
219
|
+
: <${innerType.typeName}>[]`;
|
220
|
+
},
|
221
|
+
toJson(input) {
|
222
|
+
if (context.isOptional) {
|
223
|
+
return `${input}!.map((_el_) => ${innerType.toJson("_el_", "", "")}).toList()`;
|
224
|
+
}
|
225
|
+
if (schema.nullable) {
|
226
|
+
return `${input}?.map((_el_) => ${innerType.toJson("_el_", "", "")}).toList()`;
|
227
|
+
}
|
228
|
+
return `${input}.map((_el_) => ${innerType.toJson("_el_", "", "")}).toList()`;
|
229
|
+
},
|
230
|
+
toQueryString() {
|
231
|
+
return `print(
|
232
|
+
"[WARNING] arrays cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
|
233
|
+
},
|
234
|
+
content: innerType.content
|
235
|
+
};
|
151
236
|
}
|
152
|
-
|
153
|
-
|
154
|
-
const
|
155
|
-
const
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
237
|
+
|
238
|
+
function dartClassFromSchema(schema, context) {
|
239
|
+
const isNullable = outputIsNullable(schema, context);
|
240
|
+
const className = getDartClassName(schema, context);
|
241
|
+
const finalClassName = `${context.modelPrefix}${className}`;
|
242
|
+
const typeName = isNullable ? `${finalClassName}?` : finalClassName;
|
243
|
+
const defaultValue = isNullable ? "null" : `${finalClassName}.empty()`;
|
244
|
+
const result = {
|
245
|
+
typeName,
|
246
|
+
isNullable,
|
247
|
+
defaultValue,
|
248
|
+
fromJson(input) {
|
249
|
+
if (isNullable) {
|
250
|
+
return `${input} is Map<String, dynamic>
|
251
|
+
? ${finalClassName}.fromJson(${input})
|
252
|
+
: null`;
|
162
253
|
}
|
163
|
-
return
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
)
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
(
|
193
|
-
|
194
|
-
httpClient: _httpClient,
|
195
|
-
baseUrl: _baseUrl,
|
196
|
-
headers: _headers,
|
254
|
+
return `${input} is Map<String, dynamic>
|
255
|
+
? ${finalClassName}.fromJson(${input})
|
256
|
+
: ${finalClassName}.empty()`;
|
257
|
+
},
|
258
|
+
toJson(input) {
|
259
|
+
if (context.isOptional) {
|
260
|
+
return `${input}!.toJson()`;
|
261
|
+
}
|
262
|
+
if (schema.nullable) {
|
263
|
+
return `${input}?.toJson()`;
|
264
|
+
}
|
265
|
+
return `${input}.toJson()`;
|
266
|
+
},
|
267
|
+
toQueryString() {
|
268
|
+
return `print(
|
269
|
+
"[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
|
270
|
+
},
|
271
|
+
content: ""
|
272
|
+
};
|
273
|
+
if (context.generatedTypes.includes(className)) {
|
274
|
+
return result;
|
275
|
+
}
|
276
|
+
const propNames = [];
|
277
|
+
const fieldParts = [];
|
278
|
+
const constructorParts = [];
|
279
|
+
const defaultParts = [];
|
280
|
+
const fromJsonParts = [];
|
281
|
+
const toJsonRequiredParts = [];
|
282
|
+
if (context.discriminatorKey && context.discriminatorValue) {
|
283
|
+
toJsonRequiredParts.push(
|
284
|
+
` "${context.discriminatorKey}": ${validDartIdentifier(context.discriminatorKey)},`
|
197
285
|
);
|
198
|
-
}`
|
199
|
-
).join("\n")}
|
200
|
-
${rpcParts.join("\n ")}
|
201
|
-
}
|
202
|
-
${subServiceParts.map((sub) => sub.content).join("\n")}
|
203
|
-
`;
|
204
|
-
}
|
205
|
-
function dartRpcFromDefinition(key, def, opts) {
|
206
|
-
if (def.transport === "http") {
|
207
|
-
return dartHttpRpcFromSchema(key, def);
|
208
286
|
}
|
209
|
-
|
210
|
-
|
287
|
+
const toJsonOptionalParts = [];
|
288
|
+
const toUrlQueryParts = [];
|
289
|
+
if (context.discriminatorKey && context.discriminatorValue) {
|
290
|
+
toUrlQueryParts.push(
|
291
|
+
`_queryParts_.add("${context.discriminatorKey}=$${validDartIdentifier(context.discriminatorKey)}");`
|
292
|
+
);
|
211
293
|
}
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
294
|
+
const copyWithParamParts = [];
|
295
|
+
const copyWithReturnParts = [];
|
296
|
+
const subContentParts = [];
|
297
|
+
for (const key of Object.keys(schema.properties)) {
|
298
|
+
const innerSchema = schema.properties[key];
|
299
|
+
const typeResult = dartTypeFromSchema(innerSchema, {
|
300
|
+
clientName: context.clientName,
|
301
|
+
modelPrefix: context.modelPrefix,
|
302
|
+
generatedTypes: context.generatedTypes,
|
303
|
+
instancePath: `/${className}/${key}`,
|
304
|
+
schemaPath: `${context.schemaPath}/properties/${key}`
|
305
|
+
});
|
306
|
+
const propName = validDartIdentifier(key);
|
307
|
+
propNames.push(propName);
|
308
|
+
fieldParts.push(` final ${typeResult.typeName} ${propName};`);
|
309
|
+
constructorParts.push(` required this.${propName},`);
|
310
|
+
defaultParts.push(` ${propName}: ${typeResult.defaultValue},`);
|
311
|
+
fromJsonParts.push(
|
312
|
+
` final ${propName} = ${typeResult.fromJson(`_input_["${key}"]`, key)};`
|
313
|
+
);
|
314
|
+
toJsonRequiredParts.push(
|
315
|
+
` "${key}": ${typeResult.toJson(propName, "", key)},`
|
316
|
+
);
|
317
|
+
toUrlQueryParts.push(
|
318
|
+
` ${typeResult.toQueryString(propName, "_queryParts_", key)};`
|
319
|
+
);
|
320
|
+
if (typeResult.isNullable) {
|
321
|
+
copyWithParamParts.push(
|
322
|
+
` ${typeResult.typeName} Function()? ${propName},`
|
323
|
+
);
|
324
|
+
copyWithReturnParts.push(
|
325
|
+
` ${propName}: ${propName} != null ? ${propName}() : this.${propName},`
|
326
|
+
);
|
224
327
|
} else {
|
225
|
-
|
328
|
+
copyWithParamParts.push(
|
329
|
+
` ${typeResult.typeName}${typeResult.typeName !== "dynamic" ? "?" : ""} ${propName},`
|
330
|
+
);
|
331
|
+
copyWithReturnParts.push(
|
332
|
+
` ${propName}: ${propName} ?? this.${propName},`
|
333
|
+
);
|
334
|
+
}
|
335
|
+
if (typeResult.content) {
|
336
|
+
subContentParts.push(typeResult.content);
|
226
337
|
}
|
227
|
-
} else {
|
228
|
-
returnType = "Future<void>";
|
229
338
|
}
|
230
|
-
|
231
|
-
|
232
|
-
|
339
|
+
for (const key of Object.keys(schema.optionalProperties ?? {})) {
|
340
|
+
const innerSchema = schema.optionalProperties[key];
|
341
|
+
const typeResult = dartTypeFromSchema(innerSchema, {
|
342
|
+
clientName: context.clientName,
|
343
|
+
modelPrefix: context.modelPrefix,
|
344
|
+
generatedTypes: context.generatedTypes,
|
345
|
+
instancePath: `/${className}/${key}`,
|
346
|
+
schemaPath: `${context.schemaPath}/optionalProperties/${key}`,
|
347
|
+
isOptional: true
|
348
|
+
});
|
349
|
+
const propName = validDartIdentifier(key);
|
350
|
+
propNames.push(propName);
|
351
|
+
fieldParts.push(` final ${typeResult.typeName} ${propName};`);
|
352
|
+
constructorParts.push(` this.${propName},`);
|
353
|
+
fromJsonParts.push(
|
354
|
+
` final ${propName} = ${typeResult.fromJson(`_input_["${key}"]`, key)};`
|
355
|
+
);
|
356
|
+
toJsonOptionalParts.push(
|
357
|
+
` if (${propName} != null) _output_["${key}"] = ${typeResult.toJson(propName, "_output_", key)};`
|
358
|
+
);
|
359
|
+
toUrlQueryParts.push(
|
360
|
+
` ${typeResult.toQueryString(propName, "_queryParts_", key)};`
|
361
|
+
);
|
362
|
+
copyWithParamParts.push(
|
363
|
+
` ${typeResult.typeName} Function()? ${propName},`
|
364
|
+
);
|
365
|
+
copyWithReturnParts.push(
|
366
|
+
` ${propName}: ${propName} != null ? ${propName}() : this.${propName},`
|
367
|
+
);
|
368
|
+
if (typeResult.content) {
|
369
|
+
subContentParts.push(typeResult.content);
|
370
|
+
}
|
233
371
|
}
|
234
|
-
let
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
break;
|
241
|
-
case "Future<double>":
|
242
|
-
responseParser = `(body) => Double.parse(body)`;
|
243
|
-
break;
|
244
|
-
case "Future<void>":
|
245
|
-
responseParser = `(body) {}`;
|
246
|
-
break;
|
247
|
-
case "Future<bool>":
|
248
|
-
responseParser = `(body) {
|
249
|
-
switch(body) {
|
250
|
-
case "true":
|
251
|
-
case "1":
|
252
|
-
return true;
|
253
|
-
case "false":
|
254
|
-
case "0":
|
255
|
-
default:
|
256
|
-
return false;
|
257
|
-
}
|
258
|
-
}`;
|
259
|
-
break;
|
260
|
-
default:
|
261
|
-
responseParser = `(body) => ${returnTypeName}.fromJson(
|
262
|
-
json.decode(body),
|
263
|
-
)`;
|
264
|
-
break;
|
372
|
+
let discriminatorPart = "";
|
373
|
+
if (context.discriminatorKey && context.discriminatorValue) {
|
374
|
+
discriminatorPart = `
|
375
|
+
@override
|
376
|
+
String get ${validDartIdentifier(context.discriminatorKey)} => "${context.discriminatorValue}";
|
377
|
+
`;
|
265
378
|
}
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
return parsedArriSseRequest<${returnTypeName}>(
|
277
|
-
"$_baseUrl${def.path}",
|
278
|
-
httpClient: _httpClient,
|
279
|
-
method: HttpMethod.${def.method},
|
280
|
-
headers: _headers,
|
281
|
-
params: ${paramsInput.length ? `params.toJson()` : "null"},
|
282
|
-
parser: ${responseParser},
|
283
|
-
onData: onData,
|
284
|
-
onError: onError,
|
285
|
-
onConnectionError: onConnectionError,
|
286
|
-
onOpen: onOpen,
|
287
|
-
onClose: onClose,
|
288
|
-
lastEventId: lastEventId,
|
289
|
-
clientVersion: _clientVersion,
|
290
|
-
);
|
291
|
-
}`;
|
379
|
+
result.content = `class ${finalClassName} implements ${context.discriminatorParentId ?? "ArriModel"} {
|
380
|
+
${fieldParts.join("\n")}
|
381
|
+
const ${finalClassName}({
|
382
|
+
${constructorParts.join("\n")}
|
383
|
+
});
|
384
|
+
${discriminatorPart}
|
385
|
+
factory ${finalClassName}.empty() {
|
386
|
+
return ${finalClassName}(
|
387
|
+
${defaultParts.join("\n")}
|
388
|
+
);
|
292
389
|
}
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
headers: _headers,
|
299
|
-
params: ${paramsInput.length ? `params.toJson()` : "null"},
|
300
|
-
parser: ${responseParser},
|
301
|
-
clientVersion: _clientVersion,
|
390
|
+
|
391
|
+
factory ${finalClassName}.fromJson(Map<String, dynamic> _input_) {
|
392
|
+
${fromJsonParts.join("\n")}
|
393
|
+
return ${finalClassName}(
|
394
|
+
${propNames.map((prop) => ` ${prop}: ${prop},`).join("\n")}
|
302
395
|
);
|
303
|
-
}`;
|
304
|
-
}
|
305
|
-
function dartWsRpcFromSchema(key, def, _opts) {
|
306
|
-
const serverMsg = def.response ? codegenUtils.pascalCase(def.response, { normalize: true }) : "Null";
|
307
|
-
const clientMsg = def.params ? codegenUtils.pascalCase(def.params, { normalize: true }) : "Null";
|
308
|
-
const returnType = `Future<ArriWebsocketController<${serverMsg}, ${clientMsg}>>`;
|
309
|
-
const parser = def.response ? `(body) => ${serverMsg}.fromJson(json.decode(body))` : `(_) => null`;
|
310
|
-
const serializer = def.params ? `(body) => json.encode(body.toJson())` : `(_) => ""`;
|
311
|
-
return `${getAnnotations({ description: def.description, isDeprecated: def.isDeprecated })}${returnType} ${key}() {
|
312
|
-
return arriWebsocketRequest<${serverMsg}, ${clientMsg}>(
|
313
|
-
"$_baseUrl${def.path}",
|
314
|
-
headers: _headers,
|
315
|
-
parser: ${parser},
|
316
|
-
serializer: ${serializer},
|
317
|
-
clientVersion: _clientVersion,
|
318
|
-
);
|
319
|
-
}`;
|
320
|
-
}
|
321
|
-
function dartTypeFromJtdSchema(nodePath, def, additionalOptions) {
|
322
|
-
if (codegenUtils.isSchemaFormType(def)) {
|
323
|
-
return dartScalarFromJtdScalar(nodePath, def, additionalOptions);
|
324
396
|
}
|
325
|
-
|
326
|
-
|
397
|
+
|
398
|
+
factory ${finalClassName}.fromJsonString(String input) {
|
399
|
+
return ${finalClassName}.fromJson(json.decode(input));
|
400
|
+
}
|
401
|
+
|
402
|
+
@override
|
403
|
+
Map<String, dynamic> toJson() {
|
404
|
+
final _output_ = <String, dynamic>{
|
405
|
+
${toJsonRequiredParts.join("\n")}
|
406
|
+
};
|
407
|
+
${toJsonOptionalParts.join("\n")}
|
408
|
+
return _output_;
|
327
409
|
}
|
328
|
-
|
329
|
-
|
410
|
+
|
411
|
+
@override
|
412
|
+
String toJsonString() {
|
413
|
+
return json.encode(toJson());
|
330
414
|
}
|
331
|
-
|
332
|
-
|
415
|
+
|
416
|
+
@override
|
417
|
+
String toUrlQueryParams() {
|
418
|
+
final _queryParts_ = <String>[];
|
419
|
+
${toUrlQueryParts.join("\n")}
|
420
|
+
return _queryParts_.join("&");
|
333
421
|
}
|
334
|
-
|
335
|
-
|
422
|
+
|
423
|
+
@override
|
424
|
+
${finalClassName} copyWith({
|
425
|
+
${copyWithParamParts.join("\n")}
|
426
|
+
}) {
|
427
|
+
return ${finalClassName}(
|
428
|
+
${copyWithReturnParts.join("\n")}
|
429
|
+
);
|
336
430
|
}
|
337
|
-
|
338
|
-
|
431
|
+
|
432
|
+
@override
|
433
|
+
List<Object?> get props => [
|
434
|
+
${propNames.map((prop) => ` ${prop},`).join("\n")}
|
435
|
+
];
|
436
|
+
|
437
|
+
@override
|
438
|
+
bool operator ==(Object other) {
|
439
|
+
return other is ${finalClassName} &&
|
440
|
+
listsAreEqual(props, other.props);
|
339
441
|
}
|
340
|
-
|
341
|
-
|
442
|
+
|
443
|
+
@override
|
444
|
+
int get hashCode => listToHashCode(props);
|
445
|
+
|
446
|
+
@override
|
447
|
+
String toString() {
|
448
|
+
return "${finalClassName} \${toJsonString()}";
|
342
449
|
}
|
343
|
-
return dartDynamicFromAny(nodePath, schema.a.any(), additionalOptions);
|
344
450
|
}
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
className = codegenUtils.pascalCase(nodePath.split(".").join("_"));
|
360
|
-
}
|
361
|
-
}
|
362
|
-
const properties = [];
|
363
|
-
const optionalProperties = [];
|
451
|
+
|
452
|
+
${subContentParts.join("\n\n")}`;
|
453
|
+
context.generatedTypes.push(className);
|
454
|
+
return result;
|
455
|
+
}
|
456
|
+
|
457
|
+
function dartSealedClassFromSchema(schema, context) {
|
458
|
+
const isNullable = outputIsNullable(schema, context);
|
459
|
+
const className = getDartClassName(schema, context);
|
460
|
+
const finalClassName = `${context.modelPrefix}${className}`;
|
461
|
+
const typeName = isNullable ? `${finalClassName}?` : finalClassName;
|
462
|
+
const defaultValue = isNullable ? `null` : `${finalClassName}.empty()`;
|
463
|
+
const discriminatorKey = schema.discriminator;
|
464
|
+
const subTypeParts = [];
|
364
465
|
const subContentParts = [];
|
365
|
-
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
const prop = def.properties[key2];
|
378
|
-
const mappedProp = dartTypeFromJtdSchema(keyPath, prop, {
|
379
|
-
parentId: className,
|
380
|
-
isOptional: false,
|
381
|
-
existingClassNames: additionalOptions.existingClassNames
|
466
|
+
for (const key of Object.keys(schema.mapping)) {
|
467
|
+
const subSchema = schema.mapping[key];
|
468
|
+
const discriminatorValue = key;
|
469
|
+
const subTypeResult = dartClassFromSchema(subSchema, {
|
470
|
+
clientName: context.clientName,
|
471
|
+
modelPrefix: context.modelPrefix,
|
472
|
+
generatedTypes: context.generatedTypes,
|
473
|
+
instancePath: context.instancePath,
|
474
|
+
schemaPath: `${context.schemaPath}/mapping/${key}`,
|
475
|
+
discriminatorKey,
|
476
|
+
discriminatorValue,
|
477
|
+
discriminatorParentId: className
|
382
478
|
});
|
383
|
-
|
384
|
-
|
385
|
-
|
479
|
+
subTypeParts.push({
|
480
|
+
name: subTypeResult.typeName,
|
481
|
+
value: discriminatorValue
|
386
482
|
});
|
387
|
-
if (
|
388
|
-
subContentParts.push(
|
483
|
+
if (subTypeResult.content) {
|
484
|
+
subContentParts.push(subTypeResult.content);
|
389
485
|
}
|
390
486
|
}
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
optionalProperties.push({ key: key2, templates: mappedProp });
|
401
|
-
if (mappedProp?.content) {
|
402
|
-
subContentParts.push(mappedProp.content);
|
487
|
+
const result = {
|
488
|
+
typeName,
|
489
|
+
isNullable,
|
490
|
+
defaultValue,
|
491
|
+
fromJson(input) {
|
492
|
+
if (isNullable) {
|
493
|
+
return `${input} is Map<String, dynamic>
|
494
|
+
? ${finalClassName}.fromJson(${input})
|
495
|
+
: null`;
|
403
496
|
}
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
if (discOptions) {
|
412
|
-
fieldParts.push(`@override
|
413
|
-
final String ${camelCaseWrapper(discOptions.discriminatorKey)} = "${discOptions.discriminatorValue}"`);
|
414
|
-
}
|
415
|
-
for (const prop of properties) {
|
416
|
-
fieldParts.push(prop.templates.fieldTemplate);
|
417
|
-
constructorParts.push(prop.templates.constructorTemplate);
|
418
|
-
const subJsonKey = prop.key;
|
419
|
-
const subKey = camelCaseWrapper(prop.key);
|
420
|
-
fromJsonParts.push(
|
421
|
-
`${subKey}: ${prop.templates.fromJsonTemplate(
|
422
|
-
`json["${subJsonKey}"]`
|
423
|
-
)}`
|
424
|
-
);
|
425
|
-
if (prop.templates.typeName === "dynamic") {
|
426
|
-
copyWithParamParts.push(`dynamic ${subKey}`);
|
427
|
-
copyWithInitParts.push(`${subKey}: ${subKey} ?? this.${subKey}`);
|
428
|
-
} else {
|
429
|
-
if (prop.templates.typeName.endsWith("?")) {
|
430
|
-
copyWithParamParts.push(
|
431
|
-
`ArriBox<${prop.templates.typeName}>? ${subKey}`
|
432
|
-
);
|
433
|
-
copyWithInitParts.push(
|
434
|
-
`${subKey}: ${subKey} != null ? ${subKey}.value : this.${subKey}`
|
435
|
-
);
|
436
|
-
} else {
|
437
|
-
copyWithParamParts.push(
|
438
|
-
`${prop.templates.typeName}? ${subKey}`
|
439
|
-
);
|
440
|
-
copyWithInitParts.push(
|
441
|
-
`${subKey}: ${subKey} ?? this.${subKey}`
|
442
|
-
);
|
497
|
+
return `${input} is Map<String, dynamic>
|
498
|
+
? ${finalClassName}.fromJson(${input})
|
499
|
+
: ${finalClassName}.empty()`;
|
500
|
+
},
|
501
|
+
toJson(input) {
|
502
|
+
if (context.isOptional) {
|
503
|
+
return `${input}!.toJson()`;
|
443
504
|
}
|
444
|
-
|
445
|
-
|
446
|
-
for (const prop of optionalProperties) {
|
447
|
-
fieldParts.push(prop.templates.fieldTemplate);
|
448
|
-
constructorParts.push(prop.templates.constructorTemplate);
|
449
|
-
const subKey = camelCaseWrapper(prop.key);
|
450
|
-
const subJsonKey = prop.key;
|
451
|
-
fromJsonParts.push(
|
452
|
-
`${subKey}: ${prop.templates.fromJsonTemplate(
|
453
|
-
`json["${subJsonKey}"]`
|
454
|
-
)}`
|
455
|
-
);
|
456
|
-
if (prop.templates.typeName === "dynamic") {
|
457
|
-
copyWithParamParts.push(`dynamic ${subKey}`);
|
458
|
-
copyWithInitParts.push(`${subKey}: ${subKey} ?? this.${subKey}`);
|
459
|
-
} else {
|
460
|
-
if (prop.templates.typeName.endsWith("?")) {
|
461
|
-
copyWithParamParts.push(
|
462
|
-
`ArriBox<${prop.templates.typeName}>? ${subKey}`
|
463
|
-
);
|
464
|
-
copyWithInitParts.push(
|
465
|
-
`${subKey}: ${subKey} != null ? ${subKey}.value : this.${subKey}`
|
466
|
-
);
|
467
|
-
} else {
|
468
|
-
copyWithParamParts.push(
|
469
|
-
`${prop.templates.typeName}? ${subKey}`
|
470
|
-
);
|
471
|
-
copyWithInitParts.push(
|
472
|
-
`${subKey}: ${subKey} ?? this.${subKey}`
|
473
|
-
);
|
505
|
+
if (schema.nullable) {
|
506
|
+
return `${input}?.toJson()`;
|
474
507
|
}
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
508
|
+
return `${input}.toJson()`;
|
509
|
+
},
|
510
|
+
toQueryString() {
|
511
|
+
return `print(
|
512
|
+
"[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
|
513
|
+
},
|
514
|
+
content: ""
|
515
|
+
};
|
516
|
+
if (context.generatedTypes.includes(className)) {
|
517
|
+
return result;
|
482
518
|
}
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
${
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
519
|
+
const discriminatorProp = validDartIdentifier(schema.discriminator);
|
520
|
+
result.content = `sealed class ${finalClassName} implements ArriModel {
|
521
|
+
String get ${discriminatorProp};
|
522
|
+
const ${finalClassName}();
|
523
|
+
|
524
|
+
factory ${finalClassName}.empty() {
|
525
|
+
return ${subTypeParts[0]?.name}.empty();
|
526
|
+
}
|
527
|
+
|
528
|
+
factory ${finalClassName}.fromJson(Map<String, dynamic> _input_) {
|
529
|
+
final ${discriminatorProp} = typeFromDynamic<String>(_input_["${schema.discriminator}"], "");
|
530
|
+
switch (${discriminatorProp}) {
|
531
|
+
${subTypeParts.map(
|
532
|
+
(type) => ` case "${type.value}":
|
533
|
+
return ${type.name}.fromJson(_input_);`
|
534
|
+
).join("\n")}
|
535
|
+
default:
|
536
|
+
return ${finalClassName}.empty();
|
537
|
+
}
|
538
|
+
}
|
539
|
+
|
540
|
+
factory ${finalClassName}.fromJsonString(String input) {
|
541
|
+
return ${finalClassName}.fromJson(json.decode(input));
|
542
|
+
}
|
543
|
+
}
|
544
|
+
|
545
|
+
${subContentParts.join("\n\n")}`;
|
546
|
+
context.generatedTypes.push(className);
|
547
|
+
return result;
|
548
|
+
}
|
549
|
+
|
550
|
+
function dartEnumFromSchema(schema, context) {
|
551
|
+
const isNullable = outputIsNullable(schema, context);
|
552
|
+
const enumName = getDartClassName(schema, context);
|
553
|
+
const typeName = isNullable ? `${enumName}?` : enumName;
|
554
|
+
const enumValues = schema.enum.map((val) => ({
|
555
|
+
name: codegenUtils.camelCase(val, { normalize: true }),
|
556
|
+
serialValue: val
|
557
|
+
}));
|
558
|
+
if (!enumValues.length) {
|
559
|
+
throw new Error(
|
560
|
+
`Enum schemas must have at least one enum value. At ${context.instancePath}.`
|
491
561
|
);
|
492
562
|
}
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
|
563
|
+
const defaultValue = isNullable ? "null" : `${context.modelPrefix}${enumName}.${enumValues[0]?.name}`;
|
564
|
+
const output = {
|
565
|
+
typeName,
|
566
|
+
isNullable,
|
567
|
+
defaultValue,
|
568
|
+
fromJson(input, _key) {
|
569
|
+
if (isNullable) {
|
570
|
+
return `${input} is String ? ${context.modelPrefix}${enumName}.fromString(${input}) : null`;
|
571
|
+
}
|
572
|
+
return `${context.modelPrefix}${enumName}.fromString(typeFromDynamic<String>(${input}, ""))`;
|
573
|
+
},
|
574
|
+
toJson(input) {
|
575
|
+
if (context.isOptional) {
|
576
|
+
return `${input}!.serialValue`;
|
577
|
+
}
|
578
|
+
if (schema.nullable) {
|
579
|
+
return `${input}?.serialValue`;
|
580
|
+
}
|
581
|
+
return `${input}.serialValue`;
|
582
|
+
},
|
583
|
+
toQueryString(input, target, key) {
|
584
|
+
if (context.isOptional) {
|
585
|
+
return `if (${input} != null) ${target}.add("${key}=\${${input}!.serialValue}")`;
|
586
|
+
}
|
587
|
+
if (schema.nullable) {
|
588
|
+
return `${target}.add("${key}=\${${input}?.serialValue}")`;
|
589
|
+
}
|
590
|
+
return `${target}.add("${key}=\${${input}.serialValue}")`;
|
591
|
+
},
|
592
|
+
content: ""
|
593
|
+
};
|
594
|
+
if (context.generatedTypes.includes(enumName)) {
|
595
|
+
return output;
|
513
596
|
}
|
514
|
-
${
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
597
|
+
output.content = `enum ${context.modelPrefix}${enumName} implements Comparable<${context.modelPrefix}${enumName}> {
|
598
|
+
${enumValues.map((val) => ` ${val.name}("${val.serialValue}")`).join(",\n")};
|
599
|
+
|
600
|
+
const ${context.modelPrefix}${enumName}(this.serialValue);
|
601
|
+
final String serialValue;
|
602
|
+
|
603
|
+
factory ${context.modelPrefix}${enumName}.fromString(String input) {
|
604
|
+
for (final val in values) {
|
605
|
+
if (val.serialValue == input) {
|
606
|
+
return val;
|
607
|
+
}
|
608
|
+
}
|
609
|
+
return ${enumValues[0].name};
|
520
610
|
}
|
611
|
+
|
612
|
+
@override
|
613
|
+
int compareTo(${enumName} other) => name.compareTo(other.name);
|
614
|
+
}`;
|
615
|
+
context.generatedTypes.push(enumName);
|
616
|
+
return output;
|
521
617
|
}
|
522
|
-
${subContentParts.join("\n")}
|
523
618
|
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
additionalOptions.existingClassNames.push(className);
|
529
|
-
}
|
530
|
-
const isNullable = def.nullable ?? additionalOptions?.isOptional;
|
531
|
-
const typeName = isNullable ? `${className}?` : className;
|
619
|
+
function dartStringFromSchema(schema, context) {
|
620
|
+
const isNullable = outputIsNullable(schema, context);
|
621
|
+
const typeName = isNullable ? `String?` : "String";
|
622
|
+
const defaultValue = isNullable ? "null" : '""';
|
532
623
|
return {
|
533
624
|
typeName,
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
625
|
+
isNullable,
|
626
|
+
defaultValue,
|
627
|
+
fromJson(input, _key) {
|
628
|
+
if (isNullable) {
|
629
|
+
return `nullableTypeFromDynamic<String>(${input})`;
|
630
|
+
}
|
631
|
+
return `typeFromDynamic<String>(${input}, "")`;
|
632
|
+
},
|
633
|
+
toJson(input, _target, _key) {
|
634
|
+
return input;
|
635
|
+
},
|
636
|
+
toQueryString(input, target, key) {
|
637
|
+
if (context.isOptional) {
|
638
|
+
return `if (${input} != null) ${target}.add("${key}=$${input}")`;
|
639
|
+
}
|
640
|
+
return `${target}.add("${key}=$${input}")`;
|
641
|
+
},
|
642
|
+
content: ""
|
544
643
|
};
|
545
644
|
}
|
546
|
-
function
|
547
|
-
const
|
548
|
-
const
|
645
|
+
function dartBoolFromSchema(schema, context) {
|
646
|
+
const isNullable = outputIsNullable(schema, context);
|
647
|
+
const typeName = isNullable ? "bool?" : "bool";
|
648
|
+
const defaultValue = isNullable ? "null" : "false";
|
549
649
|
return {
|
550
|
-
typeName
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
557
|
-
|
558
|
-
|
559
|
-
|
650
|
+
typeName,
|
651
|
+
isNullable,
|
652
|
+
defaultValue,
|
653
|
+
fromJson(input, _key) {
|
654
|
+
if (isNullable) {
|
655
|
+
return `nullableTypeFromDynamic<bool>(${input})`;
|
656
|
+
}
|
657
|
+
return `typeFromDynamic<bool>(${input}, false)`;
|
658
|
+
},
|
659
|
+
toJson(input, _target, _key) {
|
660
|
+
return input;
|
661
|
+
},
|
662
|
+
toQueryString(input, target, key) {
|
663
|
+
if (context.isOptional) {
|
664
|
+
return `if (${input} != null) ${target}.add("${key}=$${input}")`;
|
665
|
+
}
|
666
|
+
return `${target}.add("${key}=$${input}")`;
|
667
|
+
},
|
560
668
|
content: ""
|
561
669
|
};
|
562
670
|
}
|
563
|
-
function
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
`;
|
568
|
-
}
|
569
|
-
if (description) {
|
570
|
-
const parts = description.split("\n");
|
571
|
-
for (const part of parts) {
|
572
|
-
result += `/// ${part}
|
573
|
-
`;
|
574
|
-
}
|
575
|
-
}
|
576
|
-
result += `final ${typeName} ${key}`;
|
577
|
-
return result;
|
578
|
-
}
|
579
|
-
function dartArrayFromJtdSchema(nodePath, def, additionalOptions) {
|
580
|
-
const isNullable = additionalOptions.isOptional || (def.nullable ?? false);
|
581
|
-
const jsonKey = nodePath.split(".").pop() ?? "";
|
582
|
-
const key = camelCaseWrapper(jsonKey);
|
583
|
-
const subtype = dartTypeFromJtdSchema(`${nodePath}.Item`, def.elements, {
|
584
|
-
existingClassNames: additionalOptions.existingClassNames,
|
585
|
-
isOptional: false
|
586
|
-
});
|
587
|
-
const typeName = isNullable ? `List<${subtype.typeName}>?` : `List<${subtype.typeName}>`;
|
671
|
+
function dartDateTimeFromSchema(schema, context) {
|
672
|
+
const isNullable = outputIsNullable(schema, context);
|
673
|
+
const typeName = isNullable ? "DateTime?" : "DateTime";
|
674
|
+
const defaultValue = isNullable ? "null" : "DateTime.now()";
|
588
675
|
return {
|
589
676
|
typeName,
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
def.metadata?.description,
|
594
|
-
def.metadata?.isDeprecated
|
595
|
-
),
|
596
|
-
constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
|
597
|
-
fromJsonTemplate: (input) => {
|
677
|
+
isNullable,
|
678
|
+
defaultValue,
|
679
|
+
fromJson(input, _key) {
|
598
680
|
if (isNullable) {
|
599
|
-
return
|
600
|
-
// ignore: unnecessary_cast
|
601
|
-
(${input} as List).map((item) => ${subtype.fromJsonTemplate(
|
602
|
-
"item"
|
603
|
-
)}).toList() as ${typeName} : null`;
|
681
|
+
return `nullableDateTimeFromDynamic(${input})`;
|
604
682
|
}
|
605
|
-
return
|
606
|
-
// ignore: unnecessary_cast
|
607
|
-
(${input} as List).map((item) => ${subtype.fromJsonTemplate(
|
608
|
-
"item"
|
609
|
-
)}).toList() as ${typeName} : <${subtype.typeName}>[]`;
|
683
|
+
return `dateTimeFromDynamic(${input}, DateTime.now())`;
|
610
684
|
},
|
611
|
-
|
612
|
-
|
685
|
+
toJson(input, _target, _key) {
|
686
|
+
if (context.isOptional) {
|
687
|
+
return `${input}!.toUtc().toIso8601String()`;
|
688
|
+
}
|
689
|
+
if (schema.nullable) {
|
690
|
+
return `${input}?.toUtc().toIso8601String()`;
|
691
|
+
}
|
692
|
+
return `${input}.toUtc().toIso8601String()`;
|
693
|
+
},
|
694
|
+
toQueryString(input, target, key) {
|
695
|
+
if (context.isOptional) {
|
696
|
+
return `if (${input} != null) ${target}.add("${key}=\${${input}!.toUtc().toIso8601String()}")`;
|
697
|
+
}
|
698
|
+
if (schema.nullable) {
|
699
|
+
return `${target}.add("${key}=\${${input}?.toUtc().toIso8601String()}")`;
|
700
|
+
}
|
701
|
+
return `${target}.add("${key}=\${${input}.toUtc().toIso8601String()}")`;
|
613
702
|
},
|
614
|
-
content:
|
703
|
+
content: ""
|
615
704
|
};
|
616
705
|
}
|
617
|
-
function
|
618
|
-
const isNullable =
|
619
|
-
const
|
620
|
-
const
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
706
|
+
function dartDoubleFromSchema(schema, context) {
|
707
|
+
const isNullable = outputIsNullable(schema, context);
|
708
|
+
const typeName = isNullable ? "double?" : "double";
|
709
|
+
const defaultValue = isNullable ? "null" : "0.0";
|
710
|
+
return {
|
711
|
+
typeName,
|
712
|
+
isNullable,
|
713
|
+
defaultValue,
|
714
|
+
fromJson(input, _key) {
|
626
715
|
if (isNullable) {
|
627
|
-
return {
|
628
|
-
typeName: "bool?",
|
629
|
-
fieldTemplate: fieldTemplateString(
|
630
|
-
"bool?",
|
631
|
-
key,
|
632
|
-
description,
|
633
|
-
def.metadata?.isDeprecated
|
634
|
-
),
|
635
|
-
constructorTemplate: defaultInitializationTemplate,
|
636
|
-
fromJsonTemplate: (input) => `nullableTypeFromDynamic<bool>(${input})`,
|
637
|
-
toJsonTemplate: defaultToJsonTemplate,
|
638
|
-
content: ""
|
639
|
-
};
|
716
|
+
return `nullableDoubleFromDynamic(${input})`;
|
640
717
|
}
|
641
|
-
return {
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
)
|
649
|
-
constructorTemplate: defaultInitializationTemplate,
|
650
|
-
fromJsonTemplate: (input) => `typeFromDynamic<bool>(${input}, false)`,
|
651
|
-
toJsonTemplate: defaultToJsonTemplate,
|
652
|
-
content: ""
|
653
|
-
};
|
654
|
-
case "float32":
|
655
|
-
case "float64":
|
656
|
-
if (isNullable) {
|
657
|
-
return {
|
658
|
-
typeName: "double?",
|
659
|
-
fieldTemplate: fieldTemplateString(
|
660
|
-
"double?",
|
661
|
-
key,
|
662
|
-
description,
|
663
|
-
def.metadata?.isDeprecated
|
664
|
-
),
|
665
|
-
constructorTemplate: defaultInitializationTemplate,
|
666
|
-
fromJsonTemplate: (input) => `nullableDoubleFromDynamic(${input})`,
|
667
|
-
toJsonTemplate: defaultToJsonTemplate,
|
668
|
-
content: ""
|
669
|
-
};
|
718
|
+
return `doubleFromDynamic(${input}, 0.0)`;
|
719
|
+
},
|
720
|
+
toJson(input, _, __) {
|
721
|
+
return input;
|
722
|
+
},
|
723
|
+
toQueryString(input, target, key) {
|
724
|
+
if (context.isOptional) {
|
725
|
+
return `if (${input} != null) ${target}.add("${key}=$${input}")`;
|
670
726
|
}
|
671
|
-
return {
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
case "int32":
|
686
|
-
case "int8":
|
687
|
-
case "uint16":
|
688
|
-
case "uint32":
|
689
|
-
case "uint8":
|
727
|
+
return `${target}.add("${key}=$${input}")`;
|
728
|
+
},
|
729
|
+
content: ""
|
730
|
+
};
|
731
|
+
}
|
732
|
+
function dartIntFromSchema(schema, context) {
|
733
|
+
const isNullable = outputIsNullable(schema, context);
|
734
|
+
const typeName = isNullable ? "int?" : "int";
|
735
|
+
const defaultValue = isNullable ? "null" : "0";
|
736
|
+
return {
|
737
|
+
typeName,
|
738
|
+
isNullable,
|
739
|
+
defaultValue,
|
740
|
+
fromJson(input, _key) {
|
690
741
|
if (isNullable) {
|
691
|
-
return {
|
692
|
-
typeName: "int?",
|
693
|
-
fieldTemplate: fieldTemplateString(
|
694
|
-
"int?",
|
695
|
-
key,
|
696
|
-
description,
|
697
|
-
def.metadata?.isDeprecated
|
698
|
-
),
|
699
|
-
constructorTemplate: defaultInitializationTemplate,
|
700
|
-
fromJsonTemplate: (input) => `nullableIntFromDynamic(${input})`,
|
701
|
-
toJsonTemplate: defaultToJsonTemplate,
|
702
|
-
content: ""
|
703
|
-
};
|
742
|
+
return `nullableIntFromDynamic(${input})`;
|
704
743
|
}
|
705
|
-
return {
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
)
|
713
|
-
constructorTemplate: defaultInitializationTemplate,
|
714
|
-
fromJsonTemplate: (input) => `intFromDynamic(${input}, 0)`,
|
715
|
-
toJsonTemplate: defaultToJsonTemplate,
|
716
|
-
content: ""
|
717
|
-
};
|
718
|
-
case "int64":
|
719
|
-
case "uint64":
|
720
|
-
if (isNullable) {
|
721
|
-
return {
|
722
|
-
typeName: "BigInt?",
|
723
|
-
fieldTemplate: fieldTemplateString(
|
724
|
-
`BigInt?`,
|
725
|
-
key,
|
726
|
-
description,
|
727
|
-
def.metadata?.isDeprecated
|
728
|
-
),
|
729
|
-
constructorTemplate: defaultInitializationTemplate,
|
730
|
-
fromJsonTemplate: (input) => `nullableBigIntFromDynamic(${input})`,
|
731
|
-
toJsonTemplate: (input) => `${input}?.toString()`,
|
732
|
-
content: ""
|
733
|
-
};
|
744
|
+
return `intFromDynamic(${input}, 0)`;
|
745
|
+
},
|
746
|
+
toJson(input) {
|
747
|
+
return input;
|
748
|
+
},
|
749
|
+
toQueryString(input, target, key) {
|
750
|
+
if (context.isOptional) {
|
751
|
+
return `if (${input} != null) ${target}.add("${key}=$${input}")`;
|
734
752
|
}
|
735
|
-
return {
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
|
742
|
-
|
743
|
-
|
744
|
-
|
745
|
-
|
746
|
-
|
747
|
-
|
748
|
-
|
753
|
+
return `${target}.add("${key}=$${input}")`;
|
754
|
+
},
|
755
|
+
content: ""
|
756
|
+
};
|
757
|
+
}
|
758
|
+
function dartBigIntFromSchema(schema, context) {
|
759
|
+
const isNullable = outputIsNullable(schema, context);
|
760
|
+
const typeName = isNullable ? "BigInt?" : "BigInt";
|
761
|
+
const defaultValue = isNullable ? "null" : "BigInt.zero";
|
762
|
+
return {
|
763
|
+
typeName,
|
764
|
+
isNullable,
|
765
|
+
defaultValue,
|
766
|
+
fromJson(input, _key) {
|
749
767
|
if (isNullable) {
|
750
|
-
return {
|
751
|
-
typeName: "DateTime?",
|
752
|
-
fieldTemplate: fieldTemplateString(
|
753
|
-
"DateTime?",
|
754
|
-
key,
|
755
|
-
description,
|
756
|
-
def.metadata?.isDeprecated
|
757
|
-
),
|
758
|
-
constructorTemplate: defaultInitializationTemplate,
|
759
|
-
fromJsonTemplate: (input) => `nullableDateTimeFromDynamic(${input})`,
|
760
|
-
toJsonTemplate: (input) => `${input}?.toUtc().toIso8601String()`,
|
761
|
-
content: ""
|
762
|
-
};
|
768
|
+
return `nullableBigIntFromDynamic(${input})`;
|
763
769
|
}
|
764
|
-
return {
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
769
|
-
|
770
|
-
|
771
|
-
)
|
772
|
-
constructorTemplate: defaultInitializationTemplate,
|
773
|
-
fromJsonTemplate: (input) => `dateTimeFromDynamic(
|
774
|
-
${input},
|
775
|
-
DateTime.fromMillisecondsSinceEpoch(0),
|
776
|
-
)`,
|
777
|
-
toJsonTemplate: (input) => `${input}.toUtc().toIso8601String()`,
|
778
|
-
content: ""
|
779
|
-
};
|
780
|
-
case "string":
|
781
|
-
if (isNullable) {
|
782
|
-
return {
|
783
|
-
typeName: "String?",
|
784
|
-
fieldTemplate: fieldTemplateString(
|
785
|
-
"String?",
|
786
|
-
key,
|
787
|
-
description,
|
788
|
-
def.metadata?.isDeprecated
|
789
|
-
),
|
790
|
-
constructorTemplate: defaultInitializationTemplate,
|
791
|
-
fromJsonTemplate: (input) => `nullableTypeFromDynamic<String>(${input})`,
|
792
|
-
toJsonTemplate: defaultToJsonTemplate,
|
793
|
-
content: ""
|
794
|
-
};
|
770
|
+
return `bigIntFromDynamic(${input}, BigInt.zero)`;
|
771
|
+
},
|
772
|
+
toJson(input, _target, _key) {
|
773
|
+
if (context.isOptional) {
|
774
|
+
return `${input}!.toString()`;
|
775
|
+
}
|
776
|
+
if (schema.nullable) {
|
777
|
+
return `${input}?.toString()`;
|
795
778
|
}
|
796
|
-
return {
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
779
|
+
return `${input}.toString()`;
|
780
|
+
},
|
781
|
+
toQueryString(input, target, key) {
|
782
|
+
if (context.isOptional) {
|
783
|
+
return `if (${input} != null) ${target}.add("${key}=$${input}")`;
|
784
|
+
}
|
785
|
+
return `${target}.add("${key}=$${input}")`;
|
786
|
+
},
|
787
|
+
content: ""
|
788
|
+
};
|
789
|
+
}
|
790
|
+
|
791
|
+
function dartRpcFromSchema(schema, context) {
|
792
|
+
switch (schema.transport) {
|
793
|
+
case "http":
|
794
|
+
return dartHttpRpcFromSchema(schema, context);
|
795
|
+
case "ws":
|
796
|
+
return dartWsRpcFromSchema(schema, context);
|
809
797
|
default:
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
key,
|
815
|
-
description,
|
816
|
-
def.metadata?.isDeprecated
|
817
|
-
),
|
818
|
-
constructorTemplate: defaultInitializationTemplate,
|
819
|
-
fromJsonTemplate: (input) => input,
|
820
|
-
toJsonTemplate: defaultToJsonTemplate,
|
821
|
-
content: ""
|
822
|
-
};
|
798
|
+
console.warn(
|
799
|
+
`[WARNING] unsupported transport "${schema.transport}". Skipping ${context.instancePath}.`
|
800
|
+
);
|
801
|
+
return "";
|
823
802
|
}
|
824
803
|
}
|
825
|
-
function
|
826
|
-
const
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
className = codegenUtils.pascalCase(nodePath.split(".").join("_"));
|
804
|
+
function dartHttpRpcFromSchema(schema, context) {
|
805
|
+
const functionName = getFunctionName(context.instancePath);
|
806
|
+
let responseType = "void";
|
807
|
+
let paramsType = "";
|
808
|
+
if (schema.response) {
|
809
|
+
responseType = `${context.modelPrefix}${validDartClassName(schema.response, context.modelPrefix)}`;
|
832
810
|
}
|
833
|
-
|
834
|
-
|
835
|
-
for (const val of def.enum) {
|
836
|
-
valNames.push(`${camelCaseWrapper(val)}`);
|
837
|
-
fieldParts.push(`${camelCaseWrapper(val)}("${val}")`);
|
811
|
+
if (schema.params) {
|
812
|
+
paramsType = `${context.modelPrefix}${validDartClassName(schema.params, context.modelPrefix)}`;
|
838
813
|
}
|
839
|
-
|
840
|
-
|
841
|
-
|
842
|
-
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
|
851
|
-
|
852
|
-
|
853
|
-
|
854
|
-
|
855
|
-
|
856
|
-
|
857
|
-
|
858
|
-
|
859
|
-
|
814
|
+
if (schema.isEventStream) {
|
815
|
+
return `EventSource<${responseType}> ${functionName}(
|
816
|
+
${paramsType ? `${paramsType} params, ` : ""} {
|
817
|
+
void Function(${responseType} data, EventSource<${responseType}> connection)? onMessage,
|
818
|
+
void Function(http.StreamedResponse response, EventSource<${responseType}> connection)? onOpen,
|
819
|
+
void Function(EventSource<${responseType}> connection)? onClose,
|
820
|
+
void Function(ArriError error, EventSource<${responseType}> connection)? onError,
|
821
|
+
Duration? retryDelay,
|
822
|
+
int? maxRetryCount,
|
823
|
+
String? lastEventId,
|
824
|
+
}) {
|
825
|
+
return parsedArriSseRequest(
|
826
|
+
"$_baseUrl${schema.path}",
|
827
|
+
method: HttpMethod.${schema.method.toLowerCase()},
|
828
|
+
httpClient: _httpClient,
|
829
|
+
headers: _headers,
|
830
|
+
clientVersion: _clientVersion,
|
831
|
+
retryDelay: retryDelay,
|
832
|
+
maxRetryCount: maxRetryCount,
|
833
|
+
lastEventId: lastEventId,
|
834
|
+
${paramsType ? "params: params.toJson()," : ""}
|
835
|
+
parser: (body) ${schema.response ? `=> ${responseType}.fromJsonString(body)` : `{}`},
|
836
|
+
onMessage: onMessage,
|
837
|
+
onOpen: onOpen,
|
838
|
+
onClose: onClose,
|
839
|
+
onError: onError,
|
840
|
+
);
|
841
|
+
}`;
|
860
842
|
}
|
861
|
-
return {
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
868
|
-
|
869
|
-
|
870
|
-
|
871
|
-
|
872
|
-
return `${input} is String ? ${className}.fromJson(${input}) : null`;
|
873
|
-
}
|
874
|
-
return `${className}.fromJson(${input})`;
|
875
|
-
},
|
876
|
-
toJsonTemplate: (input) => `${input}${isNullable ? "?" : ""}.value`,
|
877
|
-
content
|
878
|
-
};
|
843
|
+
return `Future<${responseType}> ${functionName}(${paramsType ? `${paramsType} params` : ""}) async {
|
844
|
+
return parsedArriRequest(
|
845
|
+
"$_baseUrl${schema.path}",
|
846
|
+
method: HttpMethod.${schema.method.toLowerCase()},
|
847
|
+
httpClient: _httpClient,
|
848
|
+
headers: _headers,
|
849
|
+
clientVersion: _clientVersion,
|
850
|
+
${paramsType ? "params: params.toJson()," : ""}
|
851
|
+
parser: (body) ${schema.response ? `=> ${responseType}.fromJsonString(body)` : "{}"},
|
852
|
+
);
|
853
|
+
}`;
|
879
854
|
}
|
880
|
-
function
|
881
|
-
const
|
882
|
-
|
883
|
-
const key = camelCaseWrapper(jsonKey);
|
884
|
-
const innerType = dartTypeFromJtdSchema(`${nodePath}.Value`, def.values, {
|
885
|
-
existingClassNames: additionalOptions.existingClassNames,
|
886
|
-
isOptional: false
|
887
|
-
});
|
888
|
-
const typeName = `Map<String, ${innerType.typeName}>${isNullable ? "?" : ""}`;
|
889
|
-
return {
|
890
|
-
typeName: isNullable ? `Map<String, ${innerType.typeName}>?` : `Map<String, ${innerType.typeName}>`,
|
891
|
-
fieldTemplate: fieldTemplateString(
|
892
|
-
typeName,
|
893
|
-
key,
|
894
|
-
def.metadata?.description,
|
895
|
-
def.metadata?.isDeprecated
|
896
|
-
),
|
897
|
-
constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
|
898
|
-
fromJsonTemplate: (input) => `${input} is Map<String, dynamic>
|
899
|
-
? (${input} as Map<String, dynamic>).map(
|
900
|
-
(key, value) => MapEntry(key, ${innerType.fromJsonTemplate(
|
901
|
-
"value"
|
902
|
-
)}))
|
903
|
-
: <String, ${innerType.typeName}>{}`,
|
904
|
-
toJsonTemplate: (input) => `${input}${isNullable ? "?" : ""}.map((key, value) => MapEntry(key, ${innerType.toJsonTemplate(
|
905
|
-
"value"
|
906
|
-
)}))`,
|
907
|
-
content: innerType.content
|
908
|
-
};
|
855
|
+
function getFunctionName(instancePath) {
|
856
|
+
const parts = instancePath.split(".");
|
857
|
+
return parts.pop() ?? "";
|
909
858
|
}
|
910
|
-
function
|
911
|
-
const
|
912
|
-
|
913
|
-
|
914
|
-
|
915
|
-
|
916
|
-
|
917
|
-
|
918
|
-
|
919
|
-
|
920
|
-
|
921
|
-
|
922
|
-
|
923
|
-
|
924
|
-
|
925
|
-
|
926
|
-
|
927
|
-
|
928
|
-
|
929
|
-
|
930
|
-
|
931
|
-
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
859
|
+
function dartWsRpcFromSchema(schema, context) {
|
860
|
+
const functionName = getFunctionName(context.instancePath);
|
861
|
+
let responseType;
|
862
|
+
let paramsType;
|
863
|
+
if (schema.response) {
|
864
|
+
responseType = `${context.modelPrefix}${validDartClassName(schema.response, context.modelPrefix)}`;
|
865
|
+
}
|
866
|
+
if (schema.params) {
|
867
|
+
paramsType = `${context.modelPrefix}${validDartClassName(schema.params, context.modelPrefix)}`;
|
868
|
+
}
|
869
|
+
return `Future<ArriWebsocketController<${responseType ?? "void"}, ${paramsType ?? "void"}>> ${functionName}() {
|
870
|
+
return arriWebsocketRequest(
|
871
|
+
"$_baseUrl${schema.path}",
|
872
|
+
headers: _headers,
|
873
|
+
clientVersion: _clientVersion,
|
874
|
+
parser: (msg) ${responseType ? `=> ${responseType}.fromJsonString(msg)` : "{}"},
|
875
|
+
serializer: (msg) ${paramsType ? "=> msg.toJsonString()" : '=> ""'},
|
876
|
+
);
|
877
|
+
}`;
|
878
|
+
}
|
879
|
+
function dartServiceFromSchema(schema, context) {
|
880
|
+
const rpcParts = [];
|
881
|
+
const subServices = [];
|
882
|
+
const subServiceParts = [];
|
883
|
+
const serviceName = getServiceName(
|
884
|
+
context.instancePath,
|
885
|
+
context.clientName
|
886
|
+
);
|
887
|
+
for (const key of Object.keys(schema)) {
|
888
|
+
const subSchema = schema[key];
|
889
|
+
if (codegenUtils.isServiceDefinition(subSchema)) {
|
890
|
+
const subSchemaResult = dartServiceFromSchema(subSchema, {
|
891
|
+
clientName: context.clientName,
|
892
|
+
modelPrefix: context.modelPrefix,
|
893
|
+
generatedTypes: context.generatedTypes,
|
894
|
+
instancePath: `${context.instancePath}.${key}`,
|
895
|
+
schemaPath: `${context.schemaPath}.${key}`
|
896
|
+
});
|
897
|
+
if (subSchemaResult) {
|
898
|
+
subServiceParts.push(subSchemaResult);
|
899
|
+
subServices.push({
|
900
|
+
key: validDartIdentifier(key),
|
901
|
+
name: getServiceName(
|
902
|
+
`${context.instancePath}.${key}`,
|
903
|
+
context.clientName
|
904
|
+
)
|
905
|
+
});
|
936
906
|
}
|
937
|
-
|
938
|
-
fromJsonCaseParts.push(`case "${discKeyValue}":
|
939
|
-
return ${child.typeName}.fromJson(json);`);
|
940
|
-
childContentParts.push(child.content);
|
941
|
-
});
|
942
|
-
let content = "";
|
943
|
-
if (!additionalOptions.existingClassNames.includes(className)) {
|
944
|
-
content = `${getAnnotations(def.metadata)}sealed class ${className} {
|
945
|
-
final String ${discriminatorKey};
|
946
|
-
const ${className}({
|
947
|
-
required this.${discriminatorKey},
|
948
|
-
});
|
949
|
-
factory ${className}.fromJson(Map<String, dynamic> json) {
|
950
|
-
if(json["${discriminatorJsonKey}"] is! String) {
|
951
|
-
throw Exception(
|
952
|
-
"Unable to decode ${className}. Expected String from \\"${discriminatorJsonKey}\\". Received \${json["${discriminatorJsonKey}"]}}",
|
953
|
-
);
|
907
|
+
continue;
|
954
908
|
}
|
955
|
-
|
956
|
-
|
909
|
+
if (codegenUtils.isRpcDefinition(subSchema)) {
|
910
|
+
const subSchemaResult = dartRpcFromSchema(subSchema, {
|
911
|
+
clientName: context.clientName,
|
912
|
+
modelPrefix: context.modelPrefix,
|
913
|
+
generatedTypes: context.generatedTypes,
|
914
|
+
instancePath: `${context.instancePath}.${key}`,
|
915
|
+
schemaPath: `${context.schemaPath}.${key}`
|
916
|
+
});
|
917
|
+
if (subSchemaResult) {
|
918
|
+
rpcParts.push(subSchemaResult);
|
919
|
+
}
|
920
|
+
continue;
|
957
921
|
}
|
958
|
-
|
959
|
-
|
922
|
+
console.warn(
|
923
|
+
`Unknown schema in procedures at "${context.instancePath}".`
|
960
924
|
);
|
961
925
|
}
|
962
|
-
|
926
|
+
return `class ${serviceName}{
|
927
|
+
final http.Client? _httpClient;
|
928
|
+
final String _baseUrl;
|
929
|
+
final String _clientVersion = "${context.clientVersion ?? ""}";
|
930
|
+
late final FutureOr<Map<String, String>> Function()? _headers;
|
931
|
+
${serviceName}({
|
932
|
+
http.Client? httpClient,
|
933
|
+
required String baseUrl,
|
934
|
+
FutureOr<Map<String, String>> Function()? headers,
|
935
|
+
}) : _httpClient = httpClient,
|
936
|
+
_baseUrl = baseUrl,
|
937
|
+
_headers = headers;
|
938
|
+
|
939
|
+
${rpcParts.join("\n\n")}
|
940
|
+
|
941
|
+
${subServices.map(
|
942
|
+
(service) => ` ${service.name} get ${service.key} => ${service.name}(
|
943
|
+
baseUrl: _baseUrl,
|
944
|
+
headers: _headers,
|
945
|
+
httpClient: _httpClient,
|
946
|
+
);`
|
947
|
+
).join("\n\n")}
|
963
948
|
}
|
964
|
-
${
|
965
|
-
|
966
|
-
|
967
|
-
|
949
|
+
${subServiceParts.join("\n\n")}`;
|
950
|
+
}
|
951
|
+
function getServiceName(instancePath, clientName) {
|
952
|
+
return validDartClassName(
|
953
|
+
`${clientName}_${instancePath.split(".").join("_")}_Service`,
|
954
|
+
""
|
955
|
+
);
|
956
|
+
}
|
957
|
+
|
958
|
+
function dartMapFromSchema(schema, context) {
|
959
|
+
const isNullable = outputIsNullable(schema, context);
|
960
|
+
const innerType = dartTypeFromSchema(schema.values, {
|
961
|
+
clientName: context.clientName,
|
962
|
+
modelPrefix: context.modelPrefix,
|
963
|
+
generatedTypes: context.generatedTypes,
|
964
|
+
instancePath: `${context.instancePath}/[entry]`,
|
965
|
+
schemaPath: `${context.schemaPath}/values`
|
966
|
+
});
|
967
|
+
const typeName = isNullable ? `Map<String, ${innerType.typeName}>?` : `Map<String, ${innerType.typeName}>`;
|
968
|
+
const defaultValue = isNullable ? "null" : "{}";
|
968
969
|
return {
|
969
970
|
typeName,
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
def.metadata?.description,
|
974
|
-
def.metadata?.isDeprecated
|
975
|
-
),
|
976
|
-
constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
|
977
|
-
fromJsonTemplate: (input) => {
|
971
|
+
isNullable,
|
972
|
+
defaultValue,
|
973
|
+
fromJson(input) {
|
978
974
|
if (isNullable) {
|
979
|
-
return `${input} is Map<String, dynamic>
|
975
|
+
return `${input} is Map<String, dynamic>
|
976
|
+
? (${input} as Map<String, dynamic>).map(
|
977
|
+
(_key_, _val_) => MapEntry(
|
978
|
+
_key_,
|
979
|
+
${innerType.fromJson("_val_")},
|
980
|
+
),
|
981
|
+
)
|
982
|
+
: null`;
|
980
983
|
}
|
981
|
-
return `${
|
984
|
+
return `${input} is Map<String, dynamic>
|
985
|
+
? (${input} as Map<String, dynamic>).map(
|
986
|
+
(_key_, _val_) => MapEntry(
|
987
|
+
_key_,
|
988
|
+
${innerType.fromJson("_val_")},
|
989
|
+
),
|
990
|
+
)
|
991
|
+
: <String, ${innerType.typeName}>{}`;
|
982
992
|
},
|
983
|
-
|
984
|
-
if (
|
985
|
-
return `${input}
|
993
|
+
toJson(input) {
|
994
|
+
if (context.isOptional) {
|
995
|
+
return `${input}!.map((_key_, _val_) => MapEntry(_key_, ${innerType.toJson("_val_", "", "")},),)`;
|
986
996
|
}
|
987
|
-
|
997
|
+
if (schema.nullable) {
|
998
|
+
return `${input}?.map((_key_, _val_) => MapEntry(_key_, ${innerType.toJson("_val_", "", "")},),)`;
|
999
|
+
}
|
1000
|
+
return `${input}.map((_key_, _val_) => MapEntry(_key_, ${innerType.toJson("_val_", "", "")},),)`;
|
1001
|
+
},
|
1002
|
+
toQueryString() {
|
1003
|
+
return `print(
|
1004
|
+
"[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
|
988
1005
|
},
|
989
|
-
content
|
1006
|
+
content: innerType.content
|
990
1007
|
};
|
991
1008
|
}
|
992
|
-
|
993
|
-
|
994
|
-
const
|
995
|
-
const className =
|
996
|
-
|
997
|
-
|
1009
|
+
|
1010
|
+
function dartRefFromSchema(schema, context) {
|
1011
|
+
const isNullable = outputIsNullable(schema, context);
|
1012
|
+
const className = sanitizeIdentifier(
|
1013
|
+
codegenUtils.pascalCase(schema.ref, { normalize: true })
|
1014
|
+
);
|
1015
|
+
const finalClassName = `${context.modelPrefix}${className}`;
|
1016
|
+
const typeName = isNullable ? `${finalClassName}?` : finalClassName;
|
1017
|
+
const defaultValue = isNullable ? `null` : `${finalClassName}.empty()`;
|
998
1018
|
return {
|
999
1019
|
typeName,
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
def.metadata?.description,
|
1004
|
-
def.metadata?.isDeprecated
|
1005
|
-
),
|
1006
|
-
constructorTemplate: additionalOptions.isOptional ? `this.${key}` : `required this.${key}`,
|
1007
|
-
fromJsonTemplate(input) {
|
1020
|
+
isNullable,
|
1021
|
+
defaultValue,
|
1022
|
+
fromJson(input) {
|
1008
1023
|
if (isNullable) {
|
1009
|
-
return `${input} is Map<String, dynamic>
|
1024
|
+
return `${input} is Map<String, dynamic>
|
1025
|
+
? ${finalClassName}.fromJson(${input})
|
1026
|
+
: null`;
|
1010
1027
|
}
|
1011
|
-
return `${
|
1028
|
+
return `${input} is Map<String, dynamic>
|
1029
|
+
? ${finalClassName}.fromJson(${input})
|
1030
|
+
: ${finalClassName}.empty()`;
|
1012
1031
|
},
|
1013
|
-
|
1014
|
-
if (
|
1032
|
+
toJson(input) {
|
1033
|
+
if (context.isOptional) {
|
1034
|
+
return `${input}!.toJson()`;
|
1035
|
+
}
|
1036
|
+
if (schema.nullable) {
|
1015
1037
|
return `${input}?.toJson()`;
|
1016
1038
|
}
|
1017
1039
|
return `${input}.toJson()`;
|
1018
1040
|
},
|
1041
|
+
toQueryString() {
|
1042
|
+
return `print(
|
1043
|
+
"[WARNING] nested objects cannot be serialized to query params. Skipping field at ${context.instancePath}.")`;
|
1044
|
+
},
|
1019
1045
|
content: ""
|
1020
1046
|
};
|
1021
1047
|
}
|
1022
1048
|
|
1023
|
-
|
1049
|
+
const dartClientGenerator = codegenUtils.defineGeneratorPlugin(
|
1050
|
+
(options) => {
|
1051
|
+
return {
|
1052
|
+
async generator(def) {
|
1053
|
+
if (!options.outputFile) {
|
1054
|
+
throw new Error(
|
1055
|
+
'Missing "outputFile" cannot generate dart code'
|
1056
|
+
);
|
1057
|
+
}
|
1058
|
+
try {
|
1059
|
+
const result = createDartClient(def, options);
|
1060
|
+
const destination = path__default.resolve(options.outputFile);
|
1061
|
+
await fs__default.writeFile(destination, result);
|
1062
|
+
if (options.format !== false) {
|
1063
|
+
node_child_process.execSync(`dart format ${destination}`, {
|
1064
|
+
stdio: "inherit"
|
1065
|
+
});
|
1066
|
+
}
|
1067
|
+
} catch (err) {
|
1068
|
+
console.error(err);
|
1069
|
+
}
|
1070
|
+
},
|
1071
|
+
options
|
1072
|
+
};
|
1073
|
+
}
|
1074
|
+
);
|
1075
|
+
function createDartClient(def, options) {
|
1076
|
+
const typeParts = [];
|
1077
|
+
const context = {
|
1078
|
+
clientName: options.clientName ?? "Client",
|
1079
|
+
modelPrefix: options.modelPrefix ?? "",
|
1080
|
+
generatedTypes: [],
|
1081
|
+
instancePath: "",
|
1082
|
+
schemaPath: "",
|
1083
|
+
clientVersion: def.info?.version
|
1084
|
+
};
|
1085
|
+
const services = codegenUtils.unflattenProcedures(def.procedures);
|
1086
|
+
const subServices = [];
|
1087
|
+
const subServiceParts = [];
|
1088
|
+
const rpcParts = [];
|
1089
|
+
for (const key of Object.keys(services)) {
|
1090
|
+
const subSchema = services[key];
|
1091
|
+
if (codegenUtils.isServiceDefinition(subSchema)) {
|
1092
|
+
const service = dartServiceFromSchema(subSchema, {
|
1093
|
+
clientName: context.clientName,
|
1094
|
+
modelPrefix: context.modelPrefix,
|
1095
|
+
generatedTypes: context.generatedTypes,
|
1096
|
+
instancePath: key,
|
1097
|
+
schemaPath: `procedures.${key}`,
|
1098
|
+
clientVersion: context.clientVersion
|
1099
|
+
});
|
1100
|
+
if (service) {
|
1101
|
+
subServiceParts.push(service);
|
1102
|
+
subServices.push({
|
1103
|
+
key: validDartIdentifier(key),
|
1104
|
+
name: getServiceName(key, context.clientName)
|
1105
|
+
});
|
1106
|
+
}
|
1107
|
+
continue;
|
1108
|
+
}
|
1109
|
+
if (codegenUtils.isRpcDefinition(subSchema)) {
|
1110
|
+
const rpc = dartRpcFromSchema(subSchema, {
|
1111
|
+
clientName: context.clientName,
|
1112
|
+
modelPrefix: context.modelPrefix,
|
1113
|
+
generatedTypes: context.generatedTypes,
|
1114
|
+
instancePath: key,
|
1115
|
+
schemaPath: `procedures.${key}`
|
1116
|
+
});
|
1117
|
+
if (rpc) {
|
1118
|
+
rpcParts.push(rpc);
|
1119
|
+
}
|
1120
|
+
continue;
|
1121
|
+
}
|
1122
|
+
console.warn(`Unknown schema in procedures at "${key}"`);
|
1123
|
+
}
|
1124
|
+
for (const key of Object.keys(def.definitions)) {
|
1125
|
+
const subDef = def.definitions[key];
|
1126
|
+
const result = dartTypeFromSchema(subDef, {
|
1127
|
+
clientName: context.clientName,
|
1128
|
+
modelPrefix: context.modelPrefix,
|
1129
|
+
generatedTypes: context.generatedTypes,
|
1130
|
+
instancePath: `/${key}`,
|
1131
|
+
schemaPath: `/${key}`
|
1132
|
+
});
|
1133
|
+
if (result.content) {
|
1134
|
+
typeParts.push(result.content);
|
1135
|
+
}
|
1136
|
+
}
|
1137
|
+
if (rpcParts.length === 0 && subServiceParts.length === 0) {
|
1138
|
+
const heading = `// this file was autogenerated by arri
|
1139
|
+
// ignore_for_file: type=lint, unused_field, unnecessary_cast
|
1140
|
+
import 'dart:convert';
|
1141
|
+
import 'package:arri_client/arri_client.dart';`;
|
1142
|
+
return `${heading}
|
1143
|
+
|
1144
|
+
${typeParts.join("\n\n")}`;
|
1145
|
+
}
|
1146
|
+
const clientName = validDartClassName(context.clientName, "");
|
1147
|
+
return `// this file was autogenerated by arri
|
1148
|
+
// ignore_for_file: type=lint, unused_field, unnecessary_cast
|
1149
|
+
import 'dart:async';
|
1150
|
+
import 'dart:convert';
|
1151
|
+
import 'package:arri_client/arri_client.dart';
|
1152
|
+
import 'package:http/http.dart' as http;
|
1153
|
+
|
1154
|
+
class ${clientName} {
|
1155
|
+
final http.Client? _httpClient;
|
1156
|
+
final String _baseUrl;
|
1157
|
+
final String _clientVersion = "${context.clientVersion ?? ""}";
|
1158
|
+
late final FutureOr<Map<String, String>> Function()? _headers;
|
1159
|
+
${clientName}({
|
1160
|
+
http.Client? httpClient,
|
1161
|
+
required String baseUrl,
|
1162
|
+
FutureOr<Map<String, String>> Function()? headers,
|
1163
|
+
}) : _httpClient = httpClient,
|
1164
|
+
_baseUrl = baseUrl,
|
1165
|
+
_headers = headers;
|
1166
|
+
|
1167
|
+
${rpcParts.join("\n\n")}
|
1168
|
+
|
1169
|
+
${subServices.map(
|
1170
|
+
(service) => ` ${service.name} get ${service.key} => ${service.name}(
|
1171
|
+
baseUrl: _baseUrl,
|
1172
|
+
headers: _headers,
|
1173
|
+
httpClient: _httpClient,
|
1174
|
+
);`
|
1175
|
+
).join("\n\n")}
|
1176
|
+
}
|
1177
|
+
|
1178
|
+
${subServiceParts.join("\n\n")}
|
1179
|
+
|
1180
|
+
${typeParts.join("\n\n")}`;
|
1181
|
+
}
|
1182
|
+
function dartTypeFromSchema(schema, context) {
|
1183
|
+
if (codegenUtils.isSchemaFormType(schema)) {
|
1184
|
+
switch (schema.type) {
|
1185
|
+
case "string":
|
1186
|
+
return dartStringFromSchema(schema, context);
|
1187
|
+
case "boolean":
|
1188
|
+
return dartBoolFromSchema(schema, context);
|
1189
|
+
case "timestamp":
|
1190
|
+
return dartDateTimeFromSchema(schema, context);
|
1191
|
+
case "float32":
|
1192
|
+
case "float64":
|
1193
|
+
return dartDoubleFromSchema(schema, context);
|
1194
|
+
case "int8":
|
1195
|
+
case "uint8":
|
1196
|
+
case "int16":
|
1197
|
+
case "uint16":
|
1198
|
+
case "int32":
|
1199
|
+
case "uint32":
|
1200
|
+
return dartIntFromSchema(schema, context);
|
1201
|
+
case "int64":
|
1202
|
+
case "uint64":
|
1203
|
+
return dartBigIntFromSchema(schema, context);
|
1204
|
+
default:
|
1205
|
+
schema.type;
|
1206
|
+
throw new Error(`Unhandled schema.type ${schema.type}`);
|
1207
|
+
}
|
1208
|
+
}
|
1209
|
+
if (codegenUtils.isSchemaFormEnum(schema)) {
|
1210
|
+
return dartEnumFromSchema(schema, context);
|
1211
|
+
}
|
1212
|
+
if (codegenUtils.isSchemaFormProperties(schema)) {
|
1213
|
+
return dartClassFromSchema(schema, context);
|
1214
|
+
}
|
1215
|
+
if (codegenUtils.isSchemaFormElements(schema)) {
|
1216
|
+
return dartListFromSchema(schema, context);
|
1217
|
+
}
|
1218
|
+
if (codegenUtils.isSchemaFormValues(schema)) {
|
1219
|
+
return dartMapFromSchema(schema, context);
|
1220
|
+
}
|
1221
|
+
if (codegenUtils.isSchemaFormDiscriminator(schema)) {
|
1222
|
+
return dartSealedClassFromSchema(schema, context);
|
1223
|
+
}
|
1224
|
+
if (codegenUtils.isSchemaFormRef(schema)) {
|
1225
|
+
return dartRefFromSchema(schema, context);
|
1226
|
+
}
|
1227
|
+
return dartAnyFromSchema(schema, context);
|
1228
|
+
}
|
1229
|
+
|
1024
1230
|
exports.createDartClient = createDartClient;
|
1025
|
-
exports.dartClassFromJtdSchema = dartClassFromJtdSchema;
|
1026
1231
|
exports.dartClientGenerator = dartClientGenerator;
|
1027
|
-
exports.
|
1028
|
-
exports.dartRpcFromDefinition = dartRpcFromDefinition;
|
1029
|
-
exports.dartServiceFromDefinition = dartServiceFromDefinition;
|
1030
|
-
exports.dartTypeFromJtdSchema = dartTypeFromJtdSchema;
|
1031
|
-
exports.dartWsRpcFromSchema = dartWsRpcFromSchema;
|
1032
|
-
exports.getAnnotations = getAnnotations;
|
1232
|
+
exports.dartTypeFromSchema = dartTypeFromSchema;
|