@kubb/adapter-oas 5.0.2 → 5.0.3

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 CHANGED
@@ -185,11 +185,11 @@ function buildDiscriminatorChildMap(schemas) {
185
185
  if (!existing) {
186
186
  childMap.set(refNode.name, {
187
187
  propertyName: discriminatorPropertyName,
188
- enumValues: [...enumValues]
188
+ enumValues: [...new Set(enumValues)]
189
189
  });
190
190
  continue;
191
191
  }
192
- existing.enumValues.push(...enumValues);
192
+ existing.enumValues = [.../* @__PURE__ */ new Set([...existing.enumValues, ...enumValues])];
193
193
  }
194
194
  }
195
195
  return childMap;
@@ -197,10 +197,11 @@ function buildDiscriminatorChildMap(schemas) {
197
197
  /**
198
198
  * Patches a single top-level `SchemaNode` with its discriminator entry (adds or replaces
199
199
  * the discriminant property).
200
+ *
201
+ * A child declared with `allOf` parses to an intersection rather than an object, so the
202
+ * discriminant is intersected on as an extra member instead.
200
203
  */
201
204
  function patchDiscriminatorNode(node, entry) {
202
- const objectNode = _kubb_ast.ast.narrowSchema(node, "object");
203
- if (!objectNode) return node;
204
205
  const { propertyName, enumValues } = entry;
205
206
  const enumSchema = _kubb_ast.ast.factory.createSchema({
206
207
  type: "enum",
@@ -211,11 +212,27 @@ function patchDiscriminatorNode(node, entry) {
211
212
  required: true,
212
213
  schema: enumSchema
213
214
  });
214
- const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
215
- const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
215
+ const objectNode = _kubb_ast.ast.narrowSchema(node, "object");
216
+ if (objectNode) {
217
+ const existingIdx = objectNode.properties.findIndex((p) => p.name === propertyName);
218
+ const newProperties = existingIdx >= 0 ? objectNode.properties.map((p, i) => i === existingIdx ? newProp : p) : [...objectNode.properties, newProp];
219
+ return {
220
+ ...objectNode,
221
+ properties: newProperties
222
+ };
223
+ }
224
+ const intersectionNode = _kubb_ast.ast.narrowSchema(node, "intersection");
225
+ if (!intersectionNode?.members) return node;
226
+ const discriminantNode = _kubb_ast.ast.factory.createSchema({
227
+ type: "object",
228
+ primitive: "object",
229
+ properties: [newProp]
230
+ });
231
+ const patchedIdx = intersectionNode.members.findIndex((member) => _kubb_ast.ast.narrowSchema(member, "object")?.properties.some((p) => p.name === propertyName));
232
+ const newMembers = patchedIdx >= 0 ? intersectionNode.members.map((member, i) => i === patchedIdx ? patchDiscriminatorNode(member, entry) : member) : [...intersectionNode.members, discriminantNode];
216
233
  return {
217
- ...objectNode,
218
- properties: newProperties
234
+ ...intersectionNode,
235
+ members: newMembers
219
236
  };
220
237
  }
221
238
  //#endregion
@@ -1102,11 +1119,11 @@ function createNode({ schema, name, nullable, defaultValue }, extras) {
1102
1119
  *
1103
1120
  * @example
1104
1121
  * ```ts
1105
- * createDiscriminantNode({ propertyName: 'type', value: 'dog' })
1122
+ * createDiscriminantNode({ propertyName: 'type', values: ['dog'] })
1106
1123
  * // -> { type: 'object', properties: [{ name: 'type', required: true, schema: enum('dog') }] }
1107
1124
  * ```
1108
1125
  */
1109
- function createDiscriminantNode({ propertyName, value }) {
1126
+ function createDiscriminantNode({ propertyName, values }) {
1110
1127
  return _kubb_ast.ast.factory.createSchema({
1111
1128
  type: "object",
1112
1129
  primitive: "object",
@@ -1115,23 +1132,26 @@ function createDiscriminantNode({ propertyName, value }) {
1115
1132
  schema: _kubb_ast.ast.factory.createSchema({
1116
1133
  type: "enum",
1117
1134
  primitive: "string",
1118
- enumValues: [value]
1135
+ enumValues: values
1119
1136
  }),
1120
1137
  required: true
1121
1138
  })]
1122
1139
  });
1123
1140
  }
1124
1141
  /**
1125
- * Returns the discriminator key whose mapping value matches `ref`, or `null` when there is no match.
1142
+ * Returns every discriminator key whose mapping value matches `ref`, in mapping order.
1143
+ *
1144
+ * A mapping may point several keys at the same schema, in which case the member has to be
1145
+ * narrowed to all of them — keeping only the first would drop the rest from the union.
1126
1146
  *
1127
1147
  * @example
1128
1148
  * ```ts
1129
- * findDiscriminator({ dog: '#/components/schemas/Dog' }, '#/components/schemas/Dog') // 'dog'
1149
+ * findDiscriminators({ dog: '#/components/schemas/Dog', hound: '#/components/schemas/Dog' }, '#/components/schemas/Dog') // ['dog', 'hound']
1130
1150
  * ```
1131
1151
  */
1132
- function findDiscriminator(mapping, ref) {
1133
- if (!mapping || !ref) return null;
1134
- return Object.entries(mapping).find(([, value]) => value === ref)?.[0] ?? null;
1152
+ function findDiscriminators(mapping, ref) {
1153
+ if (!mapping || !ref) return [];
1154
+ return Object.entries(mapping).filter(([, value]) => value === ref).map(([key]) => key);
1135
1155
  }
1136
1156
  /**
1137
1157
  * Narrows each `oneOf`/`anyOf` member with its discriminant value, intersecting the member's own
@@ -1176,21 +1196,23 @@ function narrowUnionMembers({ unionMembers, discriminator, sharedPropertiesNode,
1176
1196
  }
1177
1197
  return unionMembers.map((s) => {
1178
1198
  const ref = isReference(s) ? s.$ref : void 0;
1179
- const discriminatorValue = findDiscriminator(discriminator?.mapping, ref) ?? implicitDiscriminantValue(s);
1199
+ const mappedValues = findDiscriminators(discriminator?.mapping, ref);
1200
+ const implicitValue = mappedValues.length ? null : implicitDiscriminantValue(s);
1201
+ const discriminatorValues = mappedValues.length ? mappedValues : implicitValue ? [implicitValue] : [];
1180
1202
  const memberNode = parse({
1181
1203
  schema: s,
1182
1204
  name
1183
1205
  }, rawOptions);
1184
- if (!discriminatorValue || !discriminator) return memberNode;
1206
+ if (!discriminatorValues.length || !discriminator) return memberNode;
1185
1207
  const narrowedDiscriminatorNode = sharedPropertiesNode ? pickDiscriminatorPropertyNode(_kubb_ast.ast.applyMacros(sharedPropertiesNode, [(0, _kubb_kit.macroDiscriminatorEnum)({
1186
1208
  propertyName: discriminator.propertyName,
1187
- values: [discriminatorValue]
1209
+ values: discriminatorValues
1188
1210
  })], { depth: "shallow" }), discriminator.propertyName) : void 0;
1189
1211
  return _kubb_ast.ast.factory.createSchema({
1190
1212
  type: "intersection",
1191
1213
  members: [memberNode, narrowedDiscriminatorNode ?? createDiscriminantNode({
1192
1214
  propertyName: discriminator.propertyName,
1193
- value: discriminatorValue
1215
+ values: discriminatorValues
1194
1216
  })]
1195
1217
  });
1196
1218
  });
@@ -1215,10 +1237,10 @@ function extractDiscriminatedAllOfMembers({ allOfMembers, name, refs }) {
1215
1237
  const inOneOf = parentUnion.some((oneOfItem) => isReference(oneOfItem) && oneOfItem.$ref === childRef);
1216
1238
  const inMapping = Object.values(deref.discriminator.mapping ?? {}).some((v) => v === childRef);
1217
1239
  if (inOneOf || inMapping) {
1218
- const discriminatorValue = findDiscriminator(deref.discriminator.mapping, childRef);
1219
- if (discriminatorValue) discriminantValues.push({
1240
+ const values = findDiscriminators(deref.discriminator.mapping, childRef);
1241
+ if (values.length) discriminantValues.push({
1220
1242
  propertyName: deref.discriminator.propertyName,
1221
- value: discriminatorValue
1243
+ values
1222
1244
  });
1223
1245
  return false;
1224
1246
  }
@@ -1323,9 +1345,9 @@ function convertAllOf({ schema, name, nullable, defaultValue, rawOptions, parse,
1323
1345
  const { allOf: _allOf, ...schemaWithoutAllOf } = schema;
1324
1346
  allOfMembers.push(parse({ schema: schemaWithoutAllOf }, rawOptions));
1325
1347
  }
1326
- for (const { propertyName, value } of discriminantValues) allOfMembers.push(createDiscriminantNode({
1348
+ for (const { propertyName, values } of discriminantValues) allOfMembers.push(createDiscriminantNode({
1327
1349
  propertyName,
1328
- value
1350
+ values
1329
1351
  }));
1330
1352
  return createNode({
1331
1353
  schema,