@kubb/adapter-oas 5.12.5 → 5.12.7

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
@@ -36,7 +36,7 @@ var compatibility = {
36
36
  };
37
37
  //#endregion
38
38
  //#region package.json
39
- var version = "5.12.5";
39
+ var version = "5.12.7";
40
40
  //#endregion
41
41
  //#region src/constants.ts
42
42
  /**
@@ -121,24 +121,35 @@ const numericFormats = /* @__PURE__ */ new Set([
121
121
  /**
122
122
  * Static map from OAS `format` strings to Kubb `SchemaType` values.
123
123
  *
124
- * Only formats whose AST type differs from the OAS `type` field appear here.
124
+ * Lists formats whose AST type differs from the OAS `type` field, plus string formats that
125
+ * `KUBB_UNSUPPORTED_FORMAT` should not flag.
125
126
  * Formats that depend on runtime options (`int64`, `date-time`, `date`, `time`) are handled
126
- * separately in the parser. `ipv4` and `ipv6` map to their own dedicated schema types. `hostname`
127
- * and `idn-hostname` map to `'url'` as the closest generic string-format type.
127
+ * separately in the parser. `ipv4` and `ipv6` map to their own dedicated schema types.
128
+ * `uri-reference`, `iri`, `iri-reference`, `hostname` and `idn-hostname` map to `'string'`: a relative
129
+ * reference, a Unicode IRI or a bare host name is not a URL, so a `'url'` validator would reject valid
130
+ * values. `base64url`, `jwt`, `ulid`, `iban` and `duration` map to `'string'` because plugins check
131
+ * them by `format`.
128
132
  */
129
133
  const formatMap = {
130
134
  uuid: "uuid",
131
135
  email: "email",
132
136
  "idn-email": "email",
133
137
  uri: "url",
134
- "uri-reference": "url",
138
+ "uri-reference": "string",
139
+ iri: "string",
140
+ "iri-reference": "string",
135
141
  url: "url",
136
142
  ipv4: "ipv4",
137
143
  ipv6: "ipv6",
138
- hostname: "url",
139
- "idn-hostname": "url",
144
+ hostname: "string",
145
+ "idn-hostname": "string",
140
146
  binary: "blob",
141
147
  byte: "blob",
148
+ base64url: "string",
149
+ jwt: "string",
150
+ ulid: "string",
151
+ iban: "string",
152
+ duration: "string",
142
153
  int32: "integer",
143
154
  float: "number",
144
155
  double: "number"
@@ -730,23 +741,73 @@ function extractSchemaFromContent(content, preferredContentType) {
730
741
  /**
731
742
  * Walks a schema tree and collects the names of all `#/components/schemas/<name>` `$ref`s.
732
743
  */
733
- function* collectRefs(schema) {
744
+ function* collectRefs(schema, renames) {
734
745
  if (Array.isArray(schema)) {
735
- for (const item of schema) yield* collectRefs(item);
746
+ for (const item of schema) yield* collectRefs(item, renames);
736
747
  return;
737
748
  }
738
749
  if (schema && typeof schema === "object") for (const key in schema) {
739
750
  const value = schema[key];
740
751
  if (!(key === "$ref" && typeof value === "string")) {
741
- yield* collectRefs(value);
752
+ yield* collectRefs(value, renames);
742
753
  continue;
743
754
  }
744
755
  if (value.startsWith("#/components/schemas/")) {
745
- const name = value.slice(21);
756
+ const name = renames.get(value) ?? value.slice(21);
746
757
  if (name) yield name;
747
758
  }
748
759
  }
749
760
  }
761
+ const schemaChildKeywords = [
762
+ "additionalProperties",
763
+ "allOf",
764
+ "anyOf",
765
+ "contains",
766
+ "contentSchema",
767
+ "else",
768
+ "if",
769
+ "items",
770
+ "not",
771
+ "oneOf",
772
+ "patternProperties",
773
+ "prefixItems",
774
+ "properties",
775
+ "propertyNames",
776
+ "then"
777
+ ];
778
+ /** Collects definitions only from schema locations, never from examples/defaults or arbitrary data. */
779
+ function* collectNestedDefinitions(schema, pointer, name) {
780
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) return;
781
+ const value = schema;
782
+ for (const keyword of ["$defs", "definitions"]) {
783
+ const definitions = value[keyword];
784
+ if (!definitions || typeof definitions !== "object" || Array.isArray(definitions)) continue;
785
+ for (const [key, definition] of Object.entries(definitions)) {
786
+ if (!definition || typeof definition !== "object" || Array.isArray(definition)) continue;
787
+ const definitionPointer = `${pointer}/${keyword}/${escapePointerToken(key)}`;
788
+ const nestedName = `${name}_${key}`;
789
+ yield {
790
+ schema: definition,
791
+ pointer: definitionPointer,
792
+ originalName: nestedName
793
+ };
794
+ yield* collectNestedDefinitions(definition, definitionPointer, nestedName);
795
+ }
796
+ }
797
+ for (const keyword of schemaChildKeywords) {
798
+ const child = value[keyword];
799
+ if (!child || typeof child !== "object") continue;
800
+ if (Array.isArray(child)) {
801
+ for (const [index, item] of child.entries()) yield* collectNestedDefinitions(item, `${pointer}/${keyword}/${index}`, name);
802
+ continue;
803
+ }
804
+ if (keyword === "properties" || keyword === "patternProperties") {
805
+ for (const [key, item] of Object.entries(child)) yield* collectNestedDefinitions(item, `${pointer}/${keyword}/${escapePointerToken(key)}`, name);
806
+ continue;
807
+ }
808
+ yield* collectNestedDefinitions(child, `${pointer}/${keyword}`, name);
809
+ }
810
+ }
750
811
  /**
751
812
  * Returns a copy of `schemas` topologically sorted by `$ref` dependency.
752
813
  *
@@ -759,9 +820,9 @@ function* collectRefs(schema) {
759
820
  * // Pet appears before Order when Order.$ref points at Pet
760
821
  * ```
761
822
  */
762
- function sortSchemas(schemas) {
823
+ function sortSchemas(schemas, renames) {
763
824
  const deps = /* @__PURE__ */ new Map();
764
- for (const [name, schema] of Object.entries(schemas)) deps.set(name, [...new Set(collectRefs(schema))]);
825
+ for (const [name, schema] of Object.entries(schemas)) deps.set(name, [...new Set(collectRefs(schema, renames))]);
765
826
  const sorted = [];
766
827
  const visited = /* @__PURE__ */ new Set();
767
828
  function visit(name, stack) {
@@ -804,16 +865,25 @@ function getSchemas(document, { contentType }, refs) {
804
865
  const resolved = refs.resolve(schema.$ref);
805
866
  return resolved && !isReference(resolved) ? resolved : schema;
806
867
  }
807
- const candidates = [...Object.entries(components?.schemas ?? {}).map(([name, schema]) => ({
808
- schema: resolveSchemaRef(schema),
809
- source: "schemas",
810
- originalName: name
811
- })), ...["responses", "requestBodies"].flatMap((source) => Object.entries(components?.[source] ?? {}).flatMap(([name, item]) => {
868
+ const candidates = [...Object.entries(components?.schemas ?? {}).flatMap(([name, schema]) => {
869
+ const pointer = `#/components/schemas/${escapePointerToken(name)}`;
870
+ return [{
871
+ schema: resolveSchemaRef(schema),
872
+ source: "schemas",
873
+ originalName: name,
874
+ pointer
875
+ }, ...[...collectNestedDefinitions(schema, pointer, name)].map((nested) => ({
876
+ ...nested,
877
+ source: "schemas",
878
+ nested: true
879
+ }))];
880
+ }), ...["responses", "requestBodies"].flatMap((source) => Object.entries(components?.[source] ?? {}).flatMap(([name, item]) => {
812
881
  const schema = extractSchemaFromContent(item.content, contentType);
813
882
  return schema ? [{
814
883
  schema: resolveSchemaRef(schema),
815
884
  source,
816
- originalName: name
885
+ originalName: name,
886
+ pointer: `#/components/${source}/${escapePointerToken(name)}`
817
887
  }] : [];
818
888
  }))];
819
889
  const normalizedNames = /* @__PURE__ */ new Map();
@@ -832,11 +902,11 @@ function getSchemas(document, { contentType }, refs) {
832
902
  const suffix = isSingle ? "" : hasMultipleSources ? semanticSuffixes[item.source] : index ? String(index + 1) : "";
833
903
  const uniqueName = item.originalName + suffix;
834
904
  schemas[uniqueName] = item.schema;
835
- if (suffix) renames.set(`#/components/${item.source}/${item.originalName}`, uniqueName);
905
+ if (suffix || item.nested) renames.set(item.pointer, uniqueName);
836
906
  });
837
907
  }
838
908
  return {
839
- schemas: sortSchemas(schemas),
909
+ schemas: sortSchemas(schemas, renames),
840
910
  renames
841
911
  };
842
912
  }
@@ -1768,6 +1838,10 @@ function convertFormat(context) {
1768
1838
  });
1769
1839
  }
1770
1840
  const specialType = formatMap[schema.format];
1841
+ if (specialType === "string") {
1842
+ if (type === "integer" || type === "number") return convertNumeric(context, type);
1843
+ return convertString(context);
1844
+ }
1771
1845
  const isNumeric = specialType === "number" || specialType === "integer";
1772
1846
  return createNode(context, {
1773
1847
  primitive: isNumeric ? specialType : "string",