@kubb/adapter-oas 5.0.0-alpha.15 → 5.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +126 -373
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -25
- package/dist/index.js +126 -373
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/adapter.ts +10 -3
- package/src/constants.ts +1 -51
- package/src/oas/types.ts +10 -4
- package/src/parser.ts +161 -335
- package/src/types.ts +1 -26
- package/src/utils.ts +0 -168
package/dist/index.cjs
CHANGED
|
@@ -104,44 +104,10 @@ const formatMap = {
|
|
|
104
104
|
double: "number"
|
|
105
105
|
};
|
|
106
106
|
/**
|
|
107
|
-
* Exhaustive list of media types that Kubb recognizes.
|
|
108
|
-
*/
|
|
109
|
-
const knownMediaTypes = new Set([
|
|
110
|
-
"application/json",
|
|
111
|
-
"application/xml",
|
|
112
|
-
"application/x-www-form-urlencoded",
|
|
113
|
-
"application/octet-stream",
|
|
114
|
-
"application/pdf",
|
|
115
|
-
"application/zip",
|
|
116
|
-
"application/graphql",
|
|
117
|
-
"multipart/form-data",
|
|
118
|
-
"text/plain",
|
|
119
|
-
"text/html",
|
|
120
|
-
"text/csv",
|
|
121
|
-
"text/xml",
|
|
122
|
-
"image/png",
|
|
123
|
-
"image/jpeg",
|
|
124
|
-
"image/gif",
|
|
125
|
-
"image/webp",
|
|
126
|
-
"image/svg+xml",
|
|
127
|
-
"audio/mpeg",
|
|
128
|
-
"video/mp4"
|
|
129
|
-
]);
|
|
130
|
-
/**
|
|
131
107
|
* Vendor extension keys used to attach human-readable labels to enum values.
|
|
132
108
|
* Checked in priority order: the first key found wins.
|
|
133
109
|
*/
|
|
134
110
|
const enumExtensionKeys = ["x-enumNames", "x-enum-varnames"];
|
|
135
|
-
/**
|
|
136
|
-
* Scalar primitive schema types used for union member simplification.
|
|
137
|
-
*/
|
|
138
|
-
const SCALAR_PRIMITIVE_TYPES = new Set([
|
|
139
|
-
"string",
|
|
140
|
-
"number",
|
|
141
|
-
"integer",
|
|
142
|
-
"bigint",
|
|
143
|
-
"boolean"
|
|
144
|
-
]);
|
|
145
111
|
//#endregion
|
|
146
112
|
//#region src/oas/resolveServerUrl.ts
|
|
147
113
|
/**
|
|
@@ -944,136 +910,6 @@ function resolveCollisions(schemasWithMeta) {
|
|
|
944
910
|
};
|
|
945
911
|
}
|
|
946
912
|
//#endregion
|
|
947
|
-
//#region src/utils.ts
|
|
948
|
-
/**
|
|
949
|
-
* Extracts the schema name from a `$ref` string.
|
|
950
|
-
* For `#/components/schemas/Order` this returns `'Order'`.
|
|
951
|
-
* Falls back to the full ref string when no slash is present.
|
|
952
|
-
*/
|
|
953
|
-
function extractRefName($ref) {
|
|
954
|
-
return $ref.split("/").at(-1) ?? $ref;
|
|
955
|
-
}
|
|
956
|
-
/**
|
|
957
|
-
* Replaces the discriminator property's schema inside an `ObjectSchemaNode`
|
|
958
|
-
* with an enum of the given `values`.
|
|
959
|
-
*
|
|
960
|
-
* - When `enumName` is provided the enum is named, which lets printers emit a
|
|
961
|
-
* standalone enum declaration + type reference (e.g. `PetTypeEnum`).
|
|
962
|
-
* - When `enumName` is omitted the enum stays anonymous, so printers inline it
|
|
963
|
-
* as a literal union (e.g. `'dog'`).
|
|
964
|
-
*
|
|
965
|
-
* Returns the node unchanged when it is not an object or lacks the target property.
|
|
966
|
-
*/
|
|
967
|
-
function applyDiscriminatorEnum({ node, propertyName, values, enumName }) {
|
|
968
|
-
if (node.type !== "object" || !node.properties?.length) return node;
|
|
969
|
-
if (!node.properties.some((prop) => prop.name === propertyName)) return node;
|
|
970
|
-
return (0, _kubb_ast.createSchema)({
|
|
971
|
-
...node,
|
|
972
|
-
properties: node.properties.map((prop) => {
|
|
973
|
-
if (prop.name !== propertyName) return prop;
|
|
974
|
-
const enumSchema = (0, _kubb_ast.createSchema)({
|
|
975
|
-
type: "enum",
|
|
976
|
-
primitive: "string",
|
|
977
|
-
enumValues: values,
|
|
978
|
-
name: enumName,
|
|
979
|
-
readOnly: prop.schema.readOnly,
|
|
980
|
-
writeOnly: prop.schema.writeOnly
|
|
981
|
-
});
|
|
982
|
-
return (0, _kubb_ast.createProperty)({
|
|
983
|
-
...prop,
|
|
984
|
-
schema: enumSchema
|
|
985
|
-
});
|
|
986
|
-
})
|
|
987
|
-
});
|
|
988
|
-
}
|
|
989
|
-
/**
|
|
990
|
-
* Merges consecutive anonymous (`name`-less) `ObjectSchemaNode`s in `members` into a
|
|
991
|
-
* single object by combining their `properties` arrays.
|
|
992
|
-
*
|
|
993
|
-
* Only adjacent pairs are merged — non-object or named nodes act as boundaries.
|
|
994
|
-
* This collapses patterns like `Address & { streetNumber } & { streetName }` into
|
|
995
|
-
* `Address & { streetNumber; streetName }`.
|
|
996
|
-
*/
|
|
997
|
-
function mergeAdjacentAnonymousObjects(members) {
|
|
998
|
-
return members.reduce((acc, member) => {
|
|
999
|
-
const obj = (0, _kubb_ast.narrowSchema)(member, "object");
|
|
1000
|
-
if (obj && !obj.name) {
|
|
1001
|
-
const prev = acc[acc.length - 1];
|
|
1002
|
-
const prevObj = prev ? (0, _kubb_ast.narrowSchema)(prev, "object") : null;
|
|
1003
|
-
if (prevObj && !prevObj.name) {
|
|
1004
|
-
acc[acc.length - 1] = (0, _kubb_ast.createSchema)({
|
|
1005
|
-
...prevObj,
|
|
1006
|
-
properties: [...prevObj.properties ?? [], ...obj.properties ?? []]
|
|
1007
|
-
});
|
|
1008
|
-
return acc;
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
acc.push(member);
|
|
1012
|
-
return acc;
|
|
1013
|
-
}, []);
|
|
1014
|
-
}
|
|
1015
|
-
/**
|
|
1016
|
-
* Simplifies a union member list by removing `enum` nodes whose `primitive` type is
|
|
1017
|
-
* already represented by a broader scalar node in the same union.
|
|
1018
|
-
*
|
|
1019
|
-
* For example `['placed', 'approved'] | string` collapses to `string` because
|
|
1020
|
-
* `string` subsumes all string literals. `'' | string` similarly becomes `string`.
|
|
1021
|
-
*
|
|
1022
|
-
* Only scalar primitives (`string`, `number`, `integer`, `bigint`, `boolean`) are
|
|
1023
|
-
* considered — object, array, and ref members are left untouched.
|
|
1024
|
-
*
|
|
1025
|
-
* Const-derived enums (those without an `enumType`, produced from an OpenAPI `const`
|
|
1026
|
-
* keyword) are **never** removed — `'accepted' | string` must stay as-is because the
|
|
1027
|
-
* literal is intentional.
|
|
1028
|
-
*/
|
|
1029
|
-
function simplifyUnionMembers(members) {
|
|
1030
|
-
const scalarPrimitives = new Set(members.filter((m) => SCALAR_PRIMITIVE_TYPES.has(m.type)).map((m) => m.type));
|
|
1031
|
-
if (!scalarPrimitives.size) return members;
|
|
1032
|
-
return members.filter((m) => {
|
|
1033
|
-
if (m.type !== "enum") return true;
|
|
1034
|
-
const prim = m.primitive;
|
|
1035
|
-
if (!prim) return true;
|
|
1036
|
-
if (!m.enumType) return true;
|
|
1037
|
-
if (scalarPrimitives.has(prim)) return false;
|
|
1038
|
-
if ((prim === "integer" || prim === "number") && (scalarPrimitives.has("integer") || scalarPrimitives.has("number"))) return false;
|
|
1039
|
-
return true;
|
|
1040
|
-
});
|
|
1041
|
-
}
|
|
1042
|
-
/**
|
|
1043
|
-
* `nameMapping`, and calls `resolve` to obtain the `{ name, path }` pair for
|
|
1044
|
-
* each import. When `oas` is supplied, only `$ref`s that are resolvable in the
|
|
1045
|
-
* spec are included; omit it to skip the existence check.
|
|
1046
|
-
*
|
|
1047
|
-
* This function is the pure, state-free alternative to `OasParser.getImports`.
|
|
1048
|
-
* Because it receives `nameMapping` explicitly it can be called without holding
|
|
1049
|
-
* a reference to the parser or the OAS instance.
|
|
1050
|
-
*
|
|
1051
|
-
* @example
|
|
1052
|
-
* ```ts
|
|
1053
|
-
* // Use adapter state directly — no parser reference needed
|
|
1054
|
-
* const imports = getImports({
|
|
1055
|
-
* node: schemaNode,
|
|
1056
|
-
* nameMapping: adapter.options.nameMapping,
|
|
1057
|
-
* resolve: (schemaName) => ({
|
|
1058
|
-
* name: schemaManager.getName(schemaName, { type: 'type' }),
|
|
1059
|
-
* path: schemaManager.getFile(schemaName).path,
|
|
1060
|
-
* }),
|
|
1061
|
-
* })
|
|
1062
|
-
* ```
|
|
1063
|
-
*/
|
|
1064
|
-
function getImports({ node, nameMapping, resolve }) {
|
|
1065
|
-
return (0, _kubb_ast.collect)(node, { schema(schemaNode) {
|
|
1066
|
-
if (schemaNode.type !== "ref" || !schemaNode.ref) return;
|
|
1067
|
-
const rawName = extractRefName(schemaNode.ref);
|
|
1068
|
-
const result = resolve(nameMapping.get(rawName) ?? rawName);
|
|
1069
|
-
if (!result) return;
|
|
1070
|
-
return {
|
|
1071
|
-
name: [result.name],
|
|
1072
|
-
path: result.path
|
|
1073
|
-
};
|
|
1074
|
-
} });
|
|
1075
|
-
}
|
|
1076
|
-
//#endregion
|
|
1077
913
|
//#region src/parser.ts
|
|
1078
914
|
/**
|
|
1079
915
|
* Looks up the Kubb `SchemaType` for a given OAS `format` string.
|
|
@@ -1098,7 +934,7 @@ function getPrimitiveType(type) {
|
|
|
1098
934
|
* Returns `undefined` for content types not present in `KNOWN_MEDIA_TYPES`.
|
|
1099
935
|
*/
|
|
1100
936
|
function toMediaType(contentType) {
|
|
1101
|
-
return
|
|
937
|
+
return Object.values(_kubb_ast.mediaTypes).includes(contentType) ? contentType : void 0;
|
|
1102
938
|
}
|
|
1103
939
|
/**
|
|
1104
940
|
* Creates an OAS parser that converts an OpenAPI/Swagger spec into
|
|
@@ -1121,14 +957,28 @@ function toMediaType(contentType) {
|
|
|
1121
957
|
*/
|
|
1122
958
|
function createOasParser(oas, { contentType } = {}) {
|
|
1123
959
|
const { schemas: schemaObjects, nameMapping } = oas.getSchemas({ contentType });
|
|
960
|
+
const TYPE_OPTION_MAP = {
|
|
961
|
+
any: _kubb_ast.schemaTypes.any,
|
|
962
|
+
unknown: _kubb_ast.schemaTypes.unknown,
|
|
963
|
+
void: _kubb_ast.schemaTypes.void
|
|
964
|
+
};
|
|
1124
965
|
/**
|
|
1125
966
|
* Maps an `'any' | 'unknown' | 'void'` option string to the corresponding `SchemaType` constant.
|
|
1126
967
|
* Used for both `unknownType` (unannotated schemas) and `emptySchemaType` (empty `{}` schemas).
|
|
1127
968
|
*/
|
|
1128
969
|
function resolveTypeOption(value) {
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
970
|
+
return TYPE_OPTION_MAP[value];
|
|
971
|
+
}
|
|
972
|
+
function normalizeArrayEnum(schema) {
|
|
973
|
+
const normalizedItems = {
|
|
974
|
+
...typeof schema.items === "object" && !Array.isArray(schema.items) ? schema.items : {},
|
|
975
|
+
enum: schema.enum
|
|
976
|
+
};
|
|
977
|
+
const { enum: _enum, ...schemaWithoutEnum } = schema;
|
|
978
|
+
return {
|
|
979
|
+
...schemaWithoutEnum,
|
|
980
|
+
items: normalizedItems
|
|
981
|
+
};
|
|
1132
982
|
}
|
|
1133
983
|
/**
|
|
1134
984
|
* Resolves the AST type and datetime modifiers for a date/time format, honoring the `dateType` option.
|
|
@@ -1190,7 +1040,7 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1190
1040
|
function convertRef({ schema, nullable, defaultValue }) {
|
|
1191
1041
|
return (0, _kubb_ast.createSchema)({
|
|
1192
1042
|
type: "ref",
|
|
1193
|
-
name: extractRefName(schema.$ref),
|
|
1043
|
+
name: (0, _kubb_ast.extractRefName)(schema.$ref),
|
|
1194
1044
|
ref: schema.$ref,
|
|
1195
1045
|
nullable,
|
|
1196
1046
|
description: schema.description,
|
|
@@ -1217,10 +1067,10 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1217
1067
|
* Circular references through discriminator parents are detected and skipped to prevent
|
|
1218
1068
|
* infinite recursion during code generation.
|
|
1219
1069
|
*/
|
|
1220
|
-
function convertAllOf({ schema, name, nullable, defaultValue,
|
|
1070
|
+
function convertAllOf({ schema, name, nullable, defaultValue, rawOptions }) {
|
|
1221
1071
|
if (schema.allOf.length === 1 && !schema.properties && !(Array.isArray(schema.required) && schema.required.length) && schema.additionalProperties === void 0) {
|
|
1222
1072
|
const [memberSchema] = schema.allOf;
|
|
1223
|
-
const memberNode = convertSchema({ schema: memberSchema },
|
|
1073
|
+
const memberNode = convertSchema({ schema: memberSchema }, rawOptions);
|
|
1224
1074
|
const { kind: _kind, ...memberNodeProps } = memberNode;
|
|
1225
1075
|
const mergedNullable = nullable || memberNode.nullable || void 0;
|
|
1226
1076
|
const mergedDefault = schema.default === null && mergedNullable ? void 0 : schema.default ?? memberNode.default;
|
|
@@ -1249,7 +1099,7 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1249
1099
|
const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
|
|
1250
1100
|
const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
|
|
1251
1101
|
if (inOneOf || inMapping) {
|
|
1252
|
-
const discriminatorValue =
|
|
1102
|
+
const discriminatorValue = (0, _kubb_ast.findDiscriminator)(deref.discriminator.mapping, childRef);
|
|
1253
1103
|
if (discriminatorValue) filteredDiscriminantValues.push({
|
|
1254
1104
|
propertyName: deref.discriminator.propertyName,
|
|
1255
1105
|
value: discriminatorValue
|
|
@@ -1257,7 +1107,7 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1257
1107
|
return false;
|
|
1258
1108
|
}
|
|
1259
1109
|
return true;
|
|
1260
|
-
}).map((s) => convertSchema({ schema: s },
|
|
1110
|
+
}).map((s) => convertSchema({ schema: s }, rawOptions));
|
|
1261
1111
|
const syntheticStart = allOfMembers.length;
|
|
1262
1112
|
if (Array.isArray(schema.required) && schema.required.length) {
|
|
1263
1113
|
const outerKeys = schema.properties ? new Set(Object.keys(schema.properties)) : /* @__PURE__ */ new Set();
|
|
@@ -1272,31 +1122,22 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1272
1122
|
allOfMembers.push(convertSchema({ schema: {
|
|
1273
1123
|
properties: { [key]: resolved.properties[key] },
|
|
1274
1124
|
required: [key]
|
|
1275
|
-
} },
|
|
1125
|
+
} }, rawOptions));
|
|
1276
1126
|
break;
|
|
1277
1127
|
}
|
|
1278
1128
|
}
|
|
1279
1129
|
}
|
|
1280
1130
|
if (schema.properties) {
|
|
1281
1131
|
const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
|
|
1282
|
-
allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf },
|
|
1132
|
+
allOfMembers.push(convertSchema({ schema: schemaWithoutAllOf }, rawOptions));
|
|
1283
1133
|
}
|
|
1284
|
-
for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push((0, _kubb_ast.
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
properties: [(0, _kubb_ast.createProperty)({
|
|
1288
|
-
name: propertyName,
|
|
1289
|
-
schema: (0, _kubb_ast.createSchema)({
|
|
1290
|
-
type: "enum",
|
|
1291
|
-
primitive: "string",
|
|
1292
|
-
enumValues: [value]
|
|
1293
|
-
}),
|
|
1294
|
-
required: true
|
|
1295
|
-
})]
|
|
1134
|
+
for (const { propertyName, value } of filteredDiscriminantValues) allOfMembers.push((0, _kubb_ast.createDiscriminantNode)({
|
|
1135
|
+
propertyName,
|
|
1136
|
+
value
|
|
1296
1137
|
}));
|
|
1297
1138
|
return (0, _kubb_ast.createSchema)({
|
|
1298
1139
|
type: "intersection",
|
|
1299
|
-
members: [...
|
|
1140
|
+
members: [...(0, _kubb_ast.mergeAdjacentObjects)(allOfMembers.slice(0, syntheticStart)), ...(0, _kubb_ast.mergeAdjacentObjects)(allOfMembers.slice(syntheticStart))],
|
|
1300
1141
|
...renderSchemaBase(schema, name, nullable, defaultValue)
|
|
1301
1142
|
});
|
|
1302
1143
|
}
|
|
@@ -1308,69 +1149,63 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1308
1149
|
* individually intersected with the shared properties node to match the OAS pattern of
|
|
1309
1150
|
* adding common fields next to a discriminated union.
|
|
1310
1151
|
*/
|
|
1311
|
-
function convertUnion({ schema, name, nullable, defaultValue,
|
|
1152
|
+
function convertUnion({ schema, name, nullable, defaultValue, rawOptions }) {
|
|
1153
|
+
function pickDiscriminatorPropertyNode(node, propertyName) {
|
|
1154
|
+
const discriminatorProperty = (0, _kubb_ast.narrowSchema)(node, "object")?.properties?.find((property) => property.name === propertyName);
|
|
1155
|
+
if (!discriminatorProperty) return;
|
|
1156
|
+
return (0, _kubb_ast.createSchema)({
|
|
1157
|
+
type: "object",
|
|
1158
|
+
primitive: "object",
|
|
1159
|
+
properties: [discriminatorProperty]
|
|
1160
|
+
});
|
|
1161
|
+
}
|
|
1312
1162
|
const unionMembers = [...schema.oneOf ?? [], ...schema.anyOf ?? []];
|
|
1313
1163
|
const unionBase = {
|
|
1314
1164
|
...renderSchemaBase(schema, name, nullable, defaultValue),
|
|
1315
1165
|
discriminatorPropertyName: isDiscriminator(schema) ? schema.discriminator.propertyName : void 0
|
|
1316
1166
|
};
|
|
1317
|
-
|
|
1167
|
+
const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
|
|
1168
|
+
const sharedPropertiesNode = schema.properties ? (() => {
|
|
1318
1169
|
const { oneOf: _oneOf, anyOf: _anyOf, ...schemaWithoutUnion } = schema;
|
|
1319
|
-
|
|
1320
|
-
const sharedPropertiesNode = convertSchema({
|
|
1170
|
+
return convertSchema({
|
|
1321
1171
|
schema: discriminator ? Object.fromEntries(Object.entries(schemaWithoutUnion).filter(([key]) => key !== "discriminator")) : schemaWithoutUnion,
|
|
1322
1172
|
name
|
|
1323
|
-
},
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
members: unionMembers.map((s) => {
|
|
1328
|
-
const ref = isReference(s) ? s.$ref : void 0;
|
|
1329
|
-
const discriminatorValue = discriminator?.mapping && ref ? Object.entries(discriminator.mapping).find(([, v]) => v === ref)?.[0] : void 0;
|
|
1330
|
-
let propertiesNode = sharedPropertiesNode;
|
|
1331
|
-
if (discriminatorValue && discriminator) propertiesNode = applyDiscriminatorEnum({
|
|
1332
|
-
node: propertiesNode,
|
|
1333
|
-
propertyName: discriminator.propertyName,
|
|
1334
|
-
values: [discriminatorValue]
|
|
1335
|
-
});
|
|
1336
|
-
return (0, _kubb_ast.createSchema)({
|
|
1337
|
-
type: "intersection",
|
|
1338
|
-
members: [convertSchema({ schema: s }, options), propertiesNode]
|
|
1339
|
-
});
|
|
1340
|
-
})
|
|
1341
|
-
});
|
|
1342
|
-
}
|
|
1343
|
-
const discriminator = isDiscriminator(schema) ? schema.discriminator : void 0;
|
|
1344
|
-
if (discriminator?.mapping) return (0, _kubb_ast.createSchema)({
|
|
1345
|
-
type: "union",
|
|
1346
|
-
...unionBase,
|
|
1347
|
-
members: unionMembers.map((s) => {
|
|
1173
|
+
}, rawOptions);
|
|
1174
|
+
})() : void 0;
|
|
1175
|
+
if (sharedPropertiesNode || discriminator?.mapping) {
|
|
1176
|
+
const members = unionMembers.map((s) => {
|
|
1348
1177
|
const ref = isReference(s) ? s.$ref : void 0;
|
|
1349
|
-
const discriminatorValue =
|
|
1350
|
-
const memberNode = convertSchema({ schema: s },
|
|
1351
|
-
if (!discriminatorValue) return memberNode;
|
|
1178
|
+
const discriminatorValue = (0, _kubb_ast.findDiscriminator)(discriminator?.mapping, ref);
|
|
1179
|
+
const memberNode = convertSchema({ schema: s }, rawOptions);
|
|
1180
|
+
if (!discriminatorValue || !discriminator) return memberNode;
|
|
1352
1181
|
return (0, _kubb_ast.createSchema)({
|
|
1353
1182
|
type: "intersection",
|
|
1354
|
-
members: [memberNode, (0, _kubb_ast.
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
primitive: "string",
|
|
1362
|
-
enumValues: [discriminatorValue]
|
|
1363
|
-
}),
|
|
1364
|
-
required: true
|
|
1365
|
-
})]
|
|
1183
|
+
members: [memberNode, (sharedPropertiesNode ? pickDiscriminatorPropertyNode((0, _kubb_ast.setDiscriminatorEnum)({
|
|
1184
|
+
node: sharedPropertiesNode,
|
|
1185
|
+
propertyName: discriminator.propertyName,
|
|
1186
|
+
values: [discriminatorValue]
|
|
1187
|
+
}), discriminator.propertyName) : void 0) ?? (0, _kubb_ast.createDiscriminantNode)({
|
|
1188
|
+
propertyName: discriminator.propertyName,
|
|
1189
|
+
value: discriminatorValue
|
|
1366
1190
|
})]
|
|
1367
1191
|
});
|
|
1368
|
-
})
|
|
1369
|
-
|
|
1192
|
+
});
|
|
1193
|
+
const unionNode = (0, _kubb_ast.createSchema)({
|
|
1194
|
+
type: "union",
|
|
1195
|
+
...unionBase,
|
|
1196
|
+
members
|
|
1197
|
+
});
|
|
1198
|
+
if (!sharedPropertiesNode) return unionNode;
|
|
1199
|
+
return (0, _kubb_ast.createSchema)({
|
|
1200
|
+
type: "intersection",
|
|
1201
|
+
...renderSchemaBase(schema, name, nullable, defaultValue),
|
|
1202
|
+
members: [unionNode, sharedPropertiesNode]
|
|
1203
|
+
});
|
|
1204
|
+
}
|
|
1370
1205
|
return (0, _kubb_ast.createSchema)({
|
|
1371
1206
|
type: "union",
|
|
1372
1207
|
...unionBase,
|
|
1373
|
-
members:
|
|
1208
|
+
members: (0, _kubb_ast.simplifyUnion)(unionMembers.map((s) => convertSchema({ schema: s }, rawOptions)))
|
|
1374
1209
|
});
|
|
1375
1210
|
}
|
|
1376
1211
|
/**
|
|
@@ -1400,10 +1235,10 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1400
1235
|
* Returns `undefined` when the format should fall through to string handling
|
|
1401
1236
|
* (i.e. `format: 'date-time'` with `dateType: false`).
|
|
1402
1237
|
*/
|
|
1403
|
-
function convertFormat({ schema, name, nullable, defaultValue,
|
|
1238
|
+
function convertFormat({ schema, name, nullable, defaultValue, options }) {
|
|
1404
1239
|
const base = renderSchemaBase(schema, name, nullable, defaultValue);
|
|
1405
1240
|
if (schema.format === "int64") return (0, _kubb_ast.createSchema)({
|
|
1406
|
-
type:
|
|
1241
|
+
type: options.integerType === "bigint" ? "bigint" : "integer",
|
|
1407
1242
|
primitive: "integer",
|
|
1408
1243
|
...base,
|
|
1409
1244
|
min: schema.minimum,
|
|
@@ -1412,7 +1247,7 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1412
1247
|
exclusiveMaximum: typeof schema.exclusiveMaximum === "number" ? schema.exclusiveMaximum : void 0
|
|
1413
1248
|
});
|
|
1414
1249
|
if (schema.format === "date-time" || schema.format === "date" || schema.format === "time") {
|
|
1415
|
-
const dateType = getDateType(
|
|
1250
|
+
const dateType = getDateType(options, schema.format);
|
|
1416
1251
|
if (!dateType) return void 0;
|
|
1417
1252
|
if (dateType.type === "datetime") return (0, _kubb_ast.createSchema)({
|
|
1418
1253
|
...base,
|
|
@@ -1457,28 +1292,19 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1457
1292
|
* - Numeric and boolean enums require a const-map representation because most generators cannot
|
|
1458
1293
|
* use string-enum syntax for non-string values.
|
|
1459
1294
|
*/
|
|
1460
|
-
function convertEnum({ schema, name, nullable, type,
|
|
1461
|
-
if (type === "array") {
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
};
|
|
1466
|
-
const { enum: _enum, ...schemaWithoutEnum } = schema;
|
|
1467
|
-
return convertSchema({
|
|
1468
|
-
schema: {
|
|
1469
|
-
...schemaWithoutEnum,
|
|
1470
|
-
items: normalizedItems
|
|
1471
|
-
},
|
|
1472
|
-
name
|
|
1473
|
-
}, options);
|
|
1474
|
-
}
|
|
1295
|
+
function convertEnum({ schema, name, nullable, type, rawOptions }) {
|
|
1296
|
+
if (type === "array") return convertSchema({
|
|
1297
|
+
schema: normalizeArrayEnum(schema),
|
|
1298
|
+
name
|
|
1299
|
+
}, rawOptions);
|
|
1475
1300
|
const nullInEnum = schema.enum.includes(null);
|
|
1476
1301
|
const filteredValues = nullInEnum ? schema.enum.filter((v) => v !== null) : schema.enum;
|
|
1477
1302
|
const enumNullable = nullable || nullInEnum || void 0;
|
|
1478
1303
|
const enumDefault = schema.default === null && enumNullable ? void 0 : schema.default;
|
|
1304
|
+
const enumPrimitive = getPrimitiveType(type);
|
|
1479
1305
|
const enumBase = {
|
|
1480
1306
|
type: "enum",
|
|
1481
|
-
primitive:
|
|
1307
|
+
primitive: enumPrimitive,
|
|
1482
1308
|
name,
|
|
1483
1309
|
title: schema.title,
|
|
1484
1310
|
description: schema.description,
|
|
@@ -1490,38 +1316,19 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1490
1316
|
example: schema.example
|
|
1491
1317
|
};
|
|
1492
1318
|
const extensionKey = enumExtensionKeys.find((key) => key in schema);
|
|
1493
|
-
if (extensionKey) {
|
|
1494
|
-
const
|
|
1495
|
-
const
|
|
1496
|
-
const enumType = getPrimitiveType(type) === "number" || getPrimitiveType(type) === "integer" ? "number" : getPrimitiveType(type) === "boolean" ? "boolean" : "string";
|
|
1319
|
+
if (extensionKey || enumPrimitive === "number" || enumPrimitive === "integer" || enumPrimitive === "boolean") {
|
|
1320
|
+
const enumPrimitiveType = enumPrimitive === "number" || enumPrimitive === "integer" ? "number" : enumPrimitive === "boolean" ? "boolean" : "string";
|
|
1321
|
+
const sourceValues = extensionKey ? [...new Set(schema[extensionKey])] : [...new Set(filteredValues)];
|
|
1497
1322
|
return (0, _kubb_ast.createSchema)({
|
|
1498
1323
|
...enumBase,
|
|
1499
|
-
|
|
1500
|
-
namedEnumValues:
|
|
1324
|
+
primitive: enumPrimitiveType,
|
|
1325
|
+
namedEnumValues: sourceValues.map((label, index) => ({
|
|
1501
1326
|
name: String(label),
|
|
1502
|
-
value: filteredValues[index] ?? label,
|
|
1503
|
-
|
|
1327
|
+
value: extensionKey ? filteredValues[index] ?? label : label,
|
|
1328
|
+
primitive: enumPrimitiveType
|
|
1504
1329
|
}))
|
|
1505
1330
|
});
|
|
1506
1331
|
}
|
|
1507
|
-
if (type === "number" || type === "integer") return (0, _kubb_ast.createSchema)({
|
|
1508
|
-
...enumBase,
|
|
1509
|
-
enumType: "number",
|
|
1510
|
-
namedEnumValues: [...new Set(filteredValues)].map((value) => ({
|
|
1511
|
-
name: String(value),
|
|
1512
|
-
value,
|
|
1513
|
-
format: "number"
|
|
1514
|
-
}))
|
|
1515
|
-
});
|
|
1516
|
-
if (type === "boolean") return (0, _kubb_ast.createSchema)({
|
|
1517
|
-
...enumBase,
|
|
1518
|
-
enumType: "boolean",
|
|
1519
|
-
namedEnumValues: [...new Set(filteredValues)].map((value) => ({
|
|
1520
|
-
name: String(value),
|
|
1521
|
-
value,
|
|
1522
|
-
format: "boolean"
|
|
1523
|
-
}))
|
|
1524
|
-
});
|
|
1525
1332
|
return (0, _kubb_ast.createSchema)({
|
|
1526
1333
|
...enumBase,
|
|
1527
1334
|
enumValues: [...new Set(filteredValues)]
|
|
@@ -1539,57 +1346,18 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1539
1346
|
* - not required + not nullable → `optional: true`
|
|
1540
1347
|
* - not required + nullable → `nullish: true`
|
|
1541
1348
|
*/
|
|
1542
|
-
|
|
1543
|
-
* Builds the propagation name for a child property during recursive schema conversion.
|
|
1544
|
-
*
|
|
1545
|
-
* The parent name is prepended so the full path is encoded
|
|
1546
|
-
* (e.g. `OrderParams` when parent is `Order`).
|
|
1547
|
-
*/
|
|
1548
|
-
function resolveChildName(parentName, propName) {
|
|
1549
|
-
return parentName ? pascalCase([parentName, propName].join(" ")) : void 0;
|
|
1550
|
-
}
|
|
1551
|
-
/**
|
|
1552
|
-
* Derives the final name for an enum property schema node.
|
|
1553
|
-
*
|
|
1554
|
-
* The resulting name always includes the enum suffix and full parent path context
|
|
1555
|
-
* (e.g. `OrderParamsStatusEnum`).
|
|
1556
|
-
*/
|
|
1557
|
-
function resolveEnumPropName(parentName, propName, enumSuffix) {
|
|
1558
|
-
return pascalCase([
|
|
1559
|
-
parentName,
|
|
1560
|
-
propName,
|
|
1561
|
-
enumSuffix
|
|
1562
|
-
].filter(Boolean).join(" "));
|
|
1563
|
-
}
|
|
1564
|
-
/**
|
|
1565
|
-
* Given a freshly-converted property schema, returns the node with a correct
|
|
1566
|
-
* `name` attached — or stripped — depending on whether the node is a named
|
|
1567
|
-
* enum, a boolean const-enum (always inlined), or a regular schema.
|
|
1568
|
-
*/
|
|
1569
|
-
function applyEnumName(propNode, parentName, propName, enumSuffix) {
|
|
1570
|
-
const enumNode = (0, _kubb_ast.narrowSchema)(propNode, "enum");
|
|
1571
|
-
if (enumNode?.primitive === "boolean") return {
|
|
1572
|
-
...propNode,
|
|
1573
|
-
name: void 0
|
|
1574
|
-
};
|
|
1575
|
-
if (enumNode) return {
|
|
1576
|
-
...propNode,
|
|
1577
|
-
name: resolveEnumPropName(parentName, propName, enumSuffix)
|
|
1578
|
-
};
|
|
1579
|
-
return propNode;
|
|
1580
|
-
}
|
|
1581
|
-
function convertObject({ schema, name, nullable, defaultValue, options, mergedOptions }) {
|
|
1349
|
+
function convertObject({ schema, name, nullable, defaultValue, rawOptions, options }) {
|
|
1582
1350
|
const properties = schema.properties ? Object.entries(schema.properties).map(([propName, propSchema]) => {
|
|
1583
1351
|
const required = Array.isArray(schema.required) ? schema.required.includes(propName) : !!schema.required;
|
|
1584
1352
|
const resolvedPropSchema = propSchema;
|
|
1585
1353
|
const propNullable = isNullable(resolvedPropSchema);
|
|
1586
|
-
let schemaNode =
|
|
1354
|
+
let schemaNode = (0, _kubb_ast.setEnumName)(convertSchema({
|
|
1587
1355
|
schema: resolvedPropSchema,
|
|
1588
|
-
name:
|
|
1589
|
-
},
|
|
1356
|
+
name: (0, _kubb_ast.childName)(name, propName)
|
|
1357
|
+
}, rawOptions), name, propName, options.enumSuffix);
|
|
1590
1358
|
const tupleNode = (0, _kubb_ast.narrowSchema)(schemaNode, "tuple");
|
|
1591
1359
|
if (tupleNode?.items) {
|
|
1592
|
-
const namedItems = tupleNode.items.map((item) =>
|
|
1360
|
+
const namedItems = tupleNode.items.map((item) => (0, _kubb_ast.setEnumName)(item, name, propName, options.enumSuffix));
|
|
1593
1361
|
if (namedItems.some((item, i) => item !== tupleNode.items[i])) schemaNode = {
|
|
1594
1362
|
...tupleNode,
|
|
1595
1363
|
items: namedItems
|
|
@@ -1607,11 +1375,11 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1607
1375
|
const additionalProperties = schema.additionalProperties;
|
|
1608
1376
|
let additionalPropertiesNode;
|
|
1609
1377
|
if (additionalProperties === true) additionalPropertiesNode = true;
|
|
1610
|
-
else if (additionalProperties && Object.keys(additionalProperties).length > 0) additionalPropertiesNode = convertSchema({ schema: additionalProperties },
|
|
1378
|
+
else if (additionalProperties && Object.keys(additionalProperties).length > 0) additionalPropertiesNode = convertSchema({ schema: additionalProperties }, rawOptions);
|
|
1611
1379
|
else if (additionalProperties === false) additionalPropertiesNode = void 0;
|
|
1612
|
-
else if (additionalProperties) additionalPropertiesNode = (0, _kubb_ast.createSchema)({ type: resolveTypeOption(
|
|
1380
|
+
else if (additionalProperties) additionalPropertiesNode = (0, _kubb_ast.createSchema)({ type: resolveTypeOption(options.unknownType) });
|
|
1613
1381
|
const rawPatternProperties = "patternProperties" in schema ? schema.patternProperties : void 0;
|
|
1614
|
-
const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? (0, _kubb_ast.createSchema)({ type: resolveTypeOption(
|
|
1382
|
+
const patternProperties = rawPatternProperties ? Object.fromEntries(Object.entries(rawPatternProperties).map(([pattern, patternSchema]) => [pattern, patternSchema === true || typeof patternSchema === "object" && Object.keys(patternSchema).length === 0 ? (0, _kubb_ast.createSchema)({ type: resolveTypeOption(options.unknownType) }) : convertSchema({ schema: patternSchema }, rawOptions)])) : void 0;
|
|
1615
1383
|
const objectNode = (0, _kubb_ast.createSchema)({
|
|
1616
1384
|
type: "object",
|
|
1617
1385
|
primitive: "object",
|
|
@@ -1622,11 +1390,11 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1622
1390
|
});
|
|
1623
1391
|
if (isDiscriminator(schema) && schema.discriminator.mapping) {
|
|
1624
1392
|
const discPropName = schema.discriminator.propertyName;
|
|
1625
|
-
return
|
|
1393
|
+
return (0, _kubb_ast.setDiscriminatorEnum)({
|
|
1626
1394
|
node: objectNode,
|
|
1627
1395
|
propertyName: discPropName,
|
|
1628
1396
|
values: Object.keys(schema.discriminator.mapping),
|
|
1629
|
-
enumName: name ?
|
|
1397
|
+
enumName: name ? (0, _kubb_ast.enumPropName)(name, discPropName, options.enumSuffix) : void 0
|
|
1630
1398
|
});
|
|
1631
1399
|
}
|
|
1632
1400
|
return objectNode;
|
|
@@ -1639,12 +1407,12 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1639
1407
|
* a rest element of type `any` is emitted to match JSON Schema semantics (absent `items`
|
|
1640
1408
|
* means additional items are allowed).
|
|
1641
1409
|
*/
|
|
1642
|
-
function convertTuple({ schema, name, nullable, defaultValue,
|
|
1410
|
+
function convertTuple({ schema, name, nullable, defaultValue, rawOptions }) {
|
|
1643
1411
|
return (0, _kubb_ast.createSchema)({
|
|
1644
1412
|
type: "tuple",
|
|
1645
1413
|
primitive: "array",
|
|
1646
|
-
items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item },
|
|
1647
|
-
rest: schema.items ? convertSchema({ schema: schema.items },
|
|
1414
|
+
items: (schema.prefixItems ?? []).map((item) => convertSchema({ schema: item }, rawOptions)),
|
|
1415
|
+
rest: schema.items ? convertSchema({ schema: schema.items }, rawOptions) : (0, _kubb_ast.createSchema)({ type: "any" }),
|
|
1648
1416
|
min: schema.minItems,
|
|
1649
1417
|
max: schema.maxItems,
|
|
1650
1418
|
...renderSchemaBase(schema, name, nullable, defaultValue)
|
|
@@ -1656,16 +1424,16 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1656
1424
|
* When the items schema is an inline enum, a name derived from the parent array's name and
|
|
1657
1425
|
* `enumSuffix` is forwarded so generators can emit a named enum declaration.
|
|
1658
1426
|
*/
|
|
1659
|
-
function convertArray({ schema, name, nullable, defaultValue,
|
|
1427
|
+
function convertArray({ schema, name, nullable, defaultValue, rawOptions, options }) {
|
|
1660
1428
|
const rawItems = schema.items;
|
|
1661
|
-
const itemName = rawItems?.enum?.length && name ?
|
|
1429
|
+
const itemName = rawItems?.enum?.length && name ? (0, _kubb_ast.enumPropName)(void 0, name, options.enumSuffix) : void 0;
|
|
1662
1430
|
return (0, _kubb_ast.createSchema)({
|
|
1663
1431
|
type: "array",
|
|
1664
1432
|
primitive: "array",
|
|
1665
1433
|
items: rawItems ? [convertSchema({
|
|
1666
1434
|
schema: rawItems,
|
|
1667
1435
|
name: itemName
|
|
1668
|
-
},
|
|
1436
|
+
}, rawOptions)] : [],
|
|
1669
1437
|
min: schema.minItems,
|
|
1670
1438
|
max: schema.maxItems,
|
|
1671
1439
|
unique: schema.uniqueItems ?? void 0,
|
|
@@ -1739,16 +1507,16 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1739
1507
|
* 10. Object / array / tuple / scalar by `type`
|
|
1740
1508
|
* 11. Empty schema fallback (`emptySchemaType` option)
|
|
1741
1509
|
*/
|
|
1742
|
-
function convertSchema({ schema, name },
|
|
1743
|
-
const
|
|
1510
|
+
function convertSchema({ schema, name }, rawOptions) {
|
|
1511
|
+
const options = {
|
|
1744
1512
|
...DEFAULT_PARSER_OPTIONS,
|
|
1745
|
-
...
|
|
1513
|
+
...rawOptions
|
|
1746
1514
|
};
|
|
1747
1515
|
const flattenedSchema = flattenSchema(schema);
|
|
1748
1516
|
if (flattenedSchema && flattenedSchema !== schema) return convertSchema({
|
|
1749
1517
|
schema: flattenedSchema,
|
|
1750
1518
|
name
|
|
1751
|
-
},
|
|
1519
|
+
}, rawOptions);
|
|
1752
1520
|
const nullable = isNullable(schema) || void 0;
|
|
1753
1521
|
const defaultValue = schema.default === null && nullable ? void 0 : schema.default;
|
|
1754
1522
|
const type = Array.isArray(schema.type) ? schema.type[0] : schema.type;
|
|
@@ -1758,8 +1526,8 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1758
1526
|
nullable,
|
|
1759
1527
|
defaultValue,
|
|
1760
1528
|
type,
|
|
1761
|
-
|
|
1762
|
-
|
|
1529
|
+
rawOptions,
|
|
1530
|
+
options
|
|
1763
1531
|
};
|
|
1764
1532
|
if (isReference(schema)) return convertRef(ctx);
|
|
1765
1533
|
if (schema.allOf?.length) return convertAllOf(ctx);
|
|
@@ -1785,7 +1553,7 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1785
1553
|
type: t
|
|
1786
1554
|
},
|
|
1787
1555
|
name
|
|
1788
|
-
},
|
|
1556
|
+
}, rawOptions)),
|
|
1789
1557
|
...renderSchemaBase(schema, name, arrayNullable, defaultValue)
|
|
1790
1558
|
});
|
|
1791
1559
|
}
|
|
@@ -1803,7 +1571,7 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1803
1571
|
if (type === "boolean") return convertBoolean(ctx);
|
|
1804
1572
|
if (type === "null") return convertNull(ctx);
|
|
1805
1573
|
return (0, _kubb_ast.createSchema)({
|
|
1806
|
-
type: resolveTypeOption(
|
|
1574
|
+
type: resolveTypeOption(options.emptySchemaType),
|
|
1807
1575
|
name,
|
|
1808
1576
|
title: schema.title,
|
|
1809
1577
|
description: schema.description
|
|
@@ -1889,34 +1657,12 @@ function createOasParser(oas, { contentType } = {}) {
|
|
|
1889
1657
|
operations: Object.entries(paths).flatMap(([_path, methods]) => Object.entries(methods).map(([, operation]) => operation ? parseOperation(mergedOptions, oas, operation) : null).filter((op) => op !== null))
|
|
1890
1658
|
});
|
|
1891
1659
|
}
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
* Collision-resolved names (from `nameMapping`) are applied before user-supplied resolvers.
|
|
1899
|
-
*/
|
|
1900
|
-
function resolveRefs(node, resolveName, resolveEnumName) {
|
|
1901
|
-
return (0, _kubb_ast.transform)(node, { schema(schemaNode) {
|
|
1902
|
-
const schemaRef = (0, _kubb_ast.narrowSchema)(schemaNode, _kubb_ast.schemaTypes.ref);
|
|
1903
|
-
if (schemaRef && (schemaRef.ref || schemaRef.name)) {
|
|
1904
|
-
const rawRef = schemaRef.ref ?? schemaRef.name;
|
|
1905
|
-
const resolved = resolveName(nameMapping.get(rawRef) ?? rawRef);
|
|
1906
|
-
if (resolved) return {
|
|
1907
|
-
...schemaNode,
|
|
1908
|
-
name: resolved
|
|
1909
|
-
};
|
|
1910
|
-
}
|
|
1911
|
-
if (schemaNode.type === "enum" && schemaNode.name) {
|
|
1912
|
-
const resolved = (resolveEnumName ?? resolveName)(schemaNode.name);
|
|
1913
|
-
if (resolved) return {
|
|
1914
|
-
...schemaNode,
|
|
1915
|
-
name: resolved
|
|
1916
|
-
};
|
|
1917
|
-
}
|
|
1918
|
-
} });
|
|
1919
|
-
}
|
|
1660
|
+
const resolveRefs = (node, resolveName, resolveEnumName) => (0, _kubb_ast.resolveNames)({
|
|
1661
|
+
node,
|
|
1662
|
+
nameMapping,
|
|
1663
|
+
resolveName,
|
|
1664
|
+
resolveEnumName
|
|
1665
|
+
});
|
|
1920
1666
|
return {
|
|
1921
1667
|
parse,
|
|
1922
1668
|
convertSchema,
|
|
@@ -1965,10 +1711,17 @@ const adapterOas = (0, _kubb_core.createAdapter)((options) => {
|
|
|
1965
1711
|
nameMapping
|
|
1966
1712
|
},
|
|
1967
1713
|
getImports(node, resolve) {
|
|
1968
|
-
return
|
|
1714
|
+
return (0, _kubb_ast.collectImports)({
|
|
1969
1715
|
node,
|
|
1970
1716
|
nameMapping,
|
|
1971
|
-
resolve
|
|
1717
|
+
resolve: (schemaName) => {
|
|
1718
|
+
const result = resolve(schemaName);
|
|
1719
|
+
if (!result) return;
|
|
1720
|
+
return {
|
|
1721
|
+
name: [result.name],
|
|
1722
|
+
path: result.path
|
|
1723
|
+
};
|
|
1724
|
+
}
|
|
1972
1725
|
});
|
|
1973
1726
|
},
|
|
1974
1727
|
async parse(source) {
|