fumadocs-openapi 10.6.8 → 10.7.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.
Files changed (108) hide show
  1. package/css/generated/shared.css +0 -1
  2. package/dist/node_modules/.pnpm/@scalar_helpers@0.4.3/node_modules/@scalar/helpers/dist/general/create-limiter.js +43 -0
  3. package/dist/node_modules/.pnpm/@scalar_helpers@0.4.3/node_modules/@scalar/helpers/dist/object/is-object.js +26 -0
  4. package/dist/node_modules/.pnpm/@scalar_helpers@0.4.3/node_modules/@scalar/helpers/dist/object/prevent-pollution.js +33 -0
  5. package/dist/node_modules/.pnpm/@scalar_helpers@0.4.3/node_modules/@scalar/helpers/dist/queue/queue.js +106 -0
  6. package/dist/node_modules/.pnpm/@scalar_helpers@0.4.3/node_modules/@scalar/helpers/dist/string/generate-hash.js +120 -0
  7. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/bundle/bundle.js +346 -0
  8. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/bundle/plugins/fetch-urls/index.js +73 -0
  9. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/bundle/plugins/node.js +3 -0
  10. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/bundle/plugins/parse-yaml/index.js +1 -0
  11. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/bundle/plugins/read-files/index.js +51 -0
  12. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/bundle/value-generator.js +88 -0
  13. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/convert-to-local-ref.js +24 -0
  14. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/escape-json-pointer.js +11 -0
  15. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/get-schemas.js +44 -0
  16. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/get-segments-from-path.js +10 -0
  17. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/get-value-by-path.js +42 -0
  18. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/is-file-path.js +23 -0
  19. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/is-http-url.js +23 -0
  20. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/is-json-object.js +28 -0
  21. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/is-yaml.js +21 -0
  22. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/normalize.js +26 -0
  23. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/resolve-reference-path.js +30 -0
  24. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/set-value-at-path.js +70 -0
  25. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/to-relative-path.js +33 -0
  26. package/dist/node_modules/.pnpm/@scalar_json-magic@0.12.5/node_modules/@scalar/json-magic/dist/helpers/unescape-json-pointer.js +12 -0
  27. package/dist/node_modules/.pnpm/@scalar_openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/2.0-to-3.0/upgrade-from-two-to-three.js +487 -0
  28. package/dist/node_modules/.pnpm/@scalar_openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/3.0-to-3.1/upgrade-from-three-to-three-one.js +95 -0
  29. package/dist/node_modules/.pnpm/@scalar_openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/3.1-to-3.2/upgrade-from-three-one-to-three-two.js +59 -0
  30. package/dist/node_modules/.pnpm/@scalar_openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/helpers/traverse.js +25 -0
  31. package/dist/node_modules/.pnpm/@scalar_openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/upgrade.js +15 -0
  32. package/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/index.js +19 -0
  33. package/dist/node_modules/.pnpm/pathe@2.0.3/node_modules/pathe/dist/shared/pathe.M-eThtNZ.js +430 -0
  34. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/compose-collection.js +50 -0
  35. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/compose-doc.js +39 -0
  36. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/compose-node.js +85 -0
  37. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/compose-scalar.js +57 -0
  38. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/composer.js +193 -0
  39. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/resolve-block-map.js +82 -0
  40. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/resolve-block-scalar.js +173 -0
  41. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/resolve-block-seq.js +40 -0
  42. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/resolve-end.js +36 -0
  43. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/resolve-flow-collection.js +153 -0
  44. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/resolve-flow-scalar.js +204 -0
  45. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/resolve-props.js +105 -0
  46. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/util-contains-newline.js +27 -0
  47. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/util-empty-scalar-position.js +25 -0
  48. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/util-flow-indent-check.js +10 -0
  49. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/compose/util-map-includes.js +10 -0
  50. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/doc/Document.js +277 -0
  51. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/doc/anchors.js +57 -0
  52. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/doc/applyReviver.js +38 -0
  53. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/doc/createNode.js +61 -0
  54. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/doc/directives.js +163 -0
  55. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/errors.js +48 -0
  56. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/index.js +16 -0
  57. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/log.js +6 -0
  58. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/Alias.js +91 -0
  59. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/Collection.js +117 -0
  60. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/Node.js +32 -0
  61. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/Pair.js +29 -0
  62. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/Scalar.js +24 -0
  63. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/YAMLMap.js +106 -0
  64. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/YAMLSeq.js +104 -0
  65. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/addPairToJSMap.js +49 -0
  66. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/identity.js +33 -0
  67. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/nodes/toJS.js +35 -0
  68. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/parse/cst-scalar.js +3 -0
  69. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/parse/cst-visit.js +89 -0
  70. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/parse/cst.js +40 -0
  71. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/parse/lexer.js +517 -0
  72. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/parse/line-counter.js +45 -0
  73. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/parse/parser.js +852 -0
  74. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/public-api.js +44 -0
  75. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/Schema.js +27 -0
  76. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/common/map.js +16 -0
  77. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/common/null.js +13 -0
  78. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/common/seq.js +16 -0
  79. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/common/string.js +14 -0
  80. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/core/bool.js +17 -0
  81. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/core/float.js +38 -0
  82. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/core/int.js +37 -0
  83. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/core/schema.js +23 -0
  84. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/json/schema.js +61 -0
  85. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/tags.js +81 -0
  86. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/binary.js +44 -0
  87. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/bool.js +24 -0
  88. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/float.js +41 -0
  89. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/int.js +70 -0
  90. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/merge.js +36 -0
  91. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/omap.js +60 -0
  92. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/pairs.js +56 -0
  93. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/schema.js +39 -0
  94. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/set.js +65 -0
  95. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/schema/yaml-1.1/timestamp.js +79 -0
  96. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/foldFlowLines.js +111 -0
  97. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/stringify.js +105 -0
  98. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/stringifyCollection.js +116 -0
  99. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/stringifyComment.js +16 -0
  100. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/stringifyDocument.js +59 -0
  101. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/stringifyNumber.js +19 -0
  102. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/stringifyPair.js +95 -0
  103. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/stringify/stringifyString.js +222 -0
  104. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/dist/visit.js +187 -0
  105. package/dist/node_modules/.pnpm/yaml@2.8.3/node_modules/yaml/browser/index.js +16 -0
  106. package/dist/scalar/client.js +1 -1
  107. package/dist/utils/document/process.js +5 -3
  108. package/package.json +16 -16
@@ -0,0 +1,487 @@
1
+ import { traverse } from "../helpers/traverse.js";
2
+ //#region ../../node_modules/.pnpm/@scalar+openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/2.0-to-3.0/upgrade-from-two-to-three.js
3
+ const DEFAULT_MEDIA_TYPE = "application/json";
4
+ /** Extracts and removes x-example and x-examples extensions from an object */
5
+ function extractXExampleExtensions(obj) {
6
+ const xExample = obj["x-example"];
7
+ const xExamples = obj["x-examples"];
8
+ delete obj["x-example"];
9
+ delete obj["x-examples"];
10
+ return {
11
+ xExample,
12
+ xExamples
13
+ };
14
+ }
15
+ /** Checks if a value is a non-null, non-array object with at least one entry */
16
+ function isNonEmptyObject(value) {
17
+ return typeof value === "object" && value !== null && !Array.isArray(value) && Object.keys(value).length > 0;
18
+ }
19
+ /**
20
+ * Checks if a value looks like a collection of named examples (all values are objects).
21
+ * This helps distinguish between:
22
+ * - A single example: { message: 'OK', type: 'success' } - values are primitives
23
+ * - Named examples: { 'my-example': { message: 'OK' } } - values are objects
24
+ */
25
+ function isNamedExamplesCollection(value) {
26
+ return isNonEmptyObject(value) && Object.values(value).every((v) => typeof v === "object" && v !== null && !Array.isArray(v));
27
+ }
28
+ /** Checks if a schema is empty (no meaningful properties defined) */
29
+ function isEmptySchema(schema) {
30
+ if (typeof schema !== "object" || schema === null) return true;
31
+ const s = schema;
32
+ if (s.allOf || s.oneOf || s.anyOf || s.items || s.$ref || "additionalProperties" in s || [
33
+ "enum",
34
+ "const",
35
+ "not",
36
+ "format",
37
+ "multipleOf",
38
+ "maximum",
39
+ "exclusiveMaximum",
40
+ "minimum",
41
+ "exclusiveMinimum",
42
+ "maxLength",
43
+ "minLength",
44
+ "pattern",
45
+ "maxItems",
46
+ "minItems",
47
+ "uniqueItems",
48
+ "maxProperties",
49
+ "minProperties",
50
+ "required"
51
+ ].some((key) => key in s)) return false;
52
+ if (typeof s.properties === "object" && s.properties !== null && Object.keys(s.properties).length > 0) return false;
53
+ return true;
54
+ }
55
+ /**
56
+ * Removes content entries that only have an empty schema (no example/examples)
57
+ * when other entries with actual examples exist. This prevents the UI from
58
+ * selecting a meaningless produces-based entry over one with a real example.
59
+ */
60
+ function removeEmptySchemaOnlyContentEntries(content) {
61
+ const keys = Object.keys(content);
62
+ if (!keys.some((key) => {
63
+ const entry = content[key];
64
+ return entry?.example !== void 0 || entry?.examples !== void 0;
65
+ })) return;
66
+ for (const key of keys) {
67
+ const entry = content[key];
68
+ if (!entry) continue;
69
+ const hasExample = entry.example !== void 0 || entry.examples !== void 0;
70
+ if (entry.schema !== void 0 && !hasExample && Object.keys(entry).length === 1 && isEmptySchema(entry.schema)) delete content[key];
71
+ }
72
+ }
73
+ /** The allowed properties for an OpenAPI 3.x ExampleObject */
74
+ const EXAMPLE_OBJECT_PROPERTIES = new Set([
75
+ "summary",
76
+ "description",
77
+ "value",
78
+ "externalValue"
79
+ ]);
80
+ /**
81
+ * Checks if a value is a valid OpenAPI 3.x ExampleObject.
82
+ *
83
+ * An ExampleObject must have a `value` (or `externalValue`) property and can only contain
84
+ * properties from the allowed set: `summary`, `description`, `value`, `externalValue`.
85
+ *
86
+ * This prevents false positives when user's example data happens to have a `value` property
87
+ * (e.g., `{ value: "some data", count: 5 }` should NOT be treated as an ExampleObject).
88
+ */
89
+ function isExampleObject(value) {
90
+ if (typeof value !== "object" || value === null) return false;
91
+ const obj = value;
92
+ const hasValueOrExternalValue = "value" in obj || "externalValue" in obj;
93
+ const onlyHasAllowedProperties = Object.keys(obj).every((key) => EXAMPLE_OBJECT_PROPERTIES.has(key));
94
+ return hasValueOrExternalValue && onlyHasAllowedProperties;
95
+ }
96
+ /** Wraps a value as an ExampleObject, preserving existing structure if valid */
97
+ function wrapAsExampleObject(value) {
98
+ if (isExampleObject(value)) return value;
99
+ return { value };
100
+ }
101
+ /**
102
+ * True if the key looks like a MIME media type (e.g. application/json, text/plain).
103
+ * Used to distinguish media-type example keys from named example keys when migrating
104
+ * Swagger 2.0 examples to OpenAPI 3.0 content. Requires exactly one slash and
105
+ * token-style type/subtype (no spaces or semicolons) to avoid false positives
106
+ * for named keys that contain a slash (e.g. "Error 404/Not Found").
107
+ */
108
+ const MEDIA_TYPE_KEY_PATTERN = /^[a-zA-Z0-9*+.-]+\/[a-zA-Z0-9*+.+-]+$/;
109
+ function isMediaTypeKey(key) {
110
+ return MEDIA_TYPE_KEY_PATTERN.test(key);
111
+ }
112
+ /** Transforms x-example entries to OpenAPI 3.x examples format */
113
+ function transformXExampleToExamples(xExample) {
114
+ return Object.entries(xExample).reduce((acc, [key, value]) => {
115
+ acc[key] = { value };
116
+ return acc;
117
+ }, {});
118
+ }
119
+ /** Update the flow names to OpenAPI 3.1.0 format */
120
+ const upgradeFlow = (flow) => {
121
+ switch (flow) {
122
+ case "application": return "clientCredentials";
123
+ case "accessCode": return "authorizationCode";
124
+ case "implicit": return "implicit";
125
+ case "password": return "password";
126
+ default: return flow;
127
+ }
128
+ };
129
+ /**
130
+ * Upgrade Swagger 2.0 to OpenAPI 3.0
131
+ *
132
+ * https://swagger.io/blog/news/whats-new-in-openapi-3-0/
133
+ */
134
+ function upgradeFromTwoToThree(originalSpecification) {
135
+ let document = originalSpecification;
136
+ if (document !== null && typeof document === "object" && typeof document.swagger === "string" && document.swagger?.startsWith("2.0")) {
137
+ document.openapi = "3.0.4";
138
+ delete document.swagger;
139
+ } else return document;
140
+ if (document.host) {
141
+ const schemes = Array.isArray(document.schemes) && document.schemes?.length ? document.schemes : ["http"];
142
+ document.servers = schemes.map((scheme) => ({ url: `${scheme}://${document.host}${document.basePath ?? ""}` }));
143
+ delete document.basePath;
144
+ delete document.schemes;
145
+ delete document.host;
146
+ } else if (document.basePath) {
147
+ document.servers = [{ url: document.basePath }];
148
+ delete document.basePath;
149
+ }
150
+ if (document.definitions) {
151
+ document.components = Object.assign({}, document.components, { schemas: document.definitions });
152
+ delete document.definitions;
153
+ document = traverse(document, (schema) => {
154
+ if (typeof schema.$ref === "string" && schema.$ref.startsWith("#/definitions/")) schema.$ref = schema.$ref.replace(/^#\/definitions\//, "#/components/schemas/");
155
+ return schema;
156
+ });
157
+ }
158
+ document = traverse(document, (schema) => {
159
+ if (schema.type === "file") {
160
+ schema.type = "string";
161
+ schema.format = "binary";
162
+ }
163
+ return schema;
164
+ });
165
+ if (Object.hasOwn(document, "parameters")) {
166
+ document = traverse(document, (schema) => {
167
+ if (typeof schema.$ref === "string" && schema.$ref.startsWith("#/parameters/")) {
168
+ const schemaName = schema.$ref.split("/")[2];
169
+ if (!schemaName) return schema;
170
+ const param = document.parameters && typeof document.parameters === "object" && schemaName in document.parameters ? document.parameters[schemaName] : void 0;
171
+ if (param && typeof param === "object" && "in" in param && (param.in === "body" || param.in === "formData")) schema.$ref = schema.$ref.replace(/^#\/parameters\//, "#/components/requestBodies/");
172
+ else schema.$ref = schema.$ref.replace(/^#\/parameters\//, "#/components/parameters/");
173
+ }
174
+ return schema;
175
+ });
176
+ document.components ??= {};
177
+ const params = {};
178
+ const bodyParams = {};
179
+ const parameters = document.parameters && typeof document.parameters === "object" ? document.parameters : {};
180
+ for (const [name, param] of Object.entries(parameters)) if (param && typeof param === "object") {
181
+ if ("$ref" in param) params[name] = transformParameterObject(param);
182
+ else if ("in" in param) if (param.in === "body") bodyParams[name] = migrateBodyParameter(param, document.consumes ?? [DEFAULT_MEDIA_TYPE]);
183
+ else if (param.in === "formData") bodyParams[name] = migrateFormDataParameter([param], document.consumes);
184
+ else params[name] = transformParameterObject(param);
185
+ }
186
+ if (Object.keys(params).length > 0) document.components.parameters = params;
187
+ if (Object.keys(bodyParams).length > 0) document.components.requestBodies = bodyParams;
188
+ delete document.parameters;
189
+ }
190
+ if (Object.hasOwn(document, "responses") && typeof document.responses === "object" && document.responses !== null) {
191
+ document = traverse(document, (schema) => {
192
+ if (typeof schema.$ref === "string" && schema.$ref.startsWith("#/responses/")) schema.$ref = schema.$ref.replace(/^#\/responses\//, "#/components/responses/");
193
+ return schema;
194
+ });
195
+ document.components ??= {};
196
+ const migratedResponses = {};
197
+ const responses = document.responses;
198
+ for (const [name, response] of Object.entries(responses)) if (response && typeof response === "object") if ("$ref" in response) migratedResponses[name] = response;
199
+ else {
200
+ const responseObj = response;
201
+ const produces = document.produces ?? [DEFAULT_MEDIA_TYPE];
202
+ if (responseObj.schema) {
203
+ if (typeof responseObj.content !== "object") responseObj.content = {};
204
+ for (const type of produces) responseObj.content[type] = { schema: responseObj.schema };
205
+ delete responseObj.schema;
206
+ }
207
+ if (responseObj.examples && typeof responseObj.examples === "object") {
208
+ if (typeof responseObj.content !== "object") responseObj.content = {};
209
+ const defaultMediaType = produces[0] ?? DEFAULT_MEDIA_TYPE;
210
+ for (const [key, exampleValue] of Object.entries(responseObj.examples)) if (isMediaTypeKey(key)) {
211
+ if (typeof responseObj.content[key] !== "object") responseObj.content[key] = {};
212
+ responseObj.content[key].example = exampleValue;
213
+ } else {
214
+ if (typeof responseObj.content[defaultMediaType] !== "object") responseObj.content[defaultMediaType] = {};
215
+ const mediaEntry = responseObj.content[defaultMediaType];
216
+ if (typeof mediaEntry.examples !== "object") mediaEntry.examples = {};
217
+ mediaEntry.examples[key] = wrapAsExampleObject(exampleValue);
218
+ }
219
+ delete responseObj.examples;
220
+ }
221
+ if (responseObj.content && typeof responseObj.content === "object") removeEmptySchemaOnlyContentEntries(responseObj.content);
222
+ if (responseObj.headers && typeof responseObj.headers === "object") responseObj.headers = Object.entries(responseObj.headers).reduce((acc, [headerName, header]) => {
223
+ if (header && typeof header === "object") return {
224
+ [headerName]: transformResponseHeader(header),
225
+ ...acc
226
+ };
227
+ return acc;
228
+ }, {});
229
+ migratedResponses[name] = responseObj;
230
+ }
231
+ if (Object.keys(migratedResponses).length > 0) document.components.responses = migratedResponses;
232
+ delete document.responses;
233
+ }
234
+ if (typeof document.paths === "object") {
235
+ for (const path in document.paths) if (Object.hasOwn(document.paths, path)) {
236
+ const pathItem = document.paths && typeof document.paths === "object" && path in document.paths ? document.paths[path] : void 0;
237
+ if (!pathItem || typeof pathItem !== "object") continue;
238
+ let requestBodyObject;
239
+ for (const methodOrParameters in pathItem) if (methodOrParameters === "parameters" && Object.hasOwn(pathItem, methodOrParameters)) {
240
+ const pathItemParameters = migrateParameters(pathItem.parameters, document.consumes ?? [DEFAULT_MEDIA_TYPE]);
241
+ pathItem.parameters = pathItemParameters.parameters;
242
+ requestBodyObject = pathItemParameters.requestBody;
243
+ } else if (Object.hasOwn(pathItem, methodOrParameters)) {
244
+ const operationItem = pathItem[methodOrParameters];
245
+ if (requestBodyObject) operationItem.requestBody = requestBodyObject;
246
+ if (operationItem.parameters) {
247
+ const migrationResult = migrateParameters(operationItem.parameters, operationItem.consumes ?? document.consumes ?? [DEFAULT_MEDIA_TYPE]);
248
+ operationItem.parameters = migrationResult.parameters;
249
+ if (migrationResult.requestBody) operationItem.requestBody = migrationResult.requestBody;
250
+ }
251
+ delete operationItem.consumes;
252
+ if (operationItem.responses) {
253
+ for (const response in operationItem.responses) if (Object.hasOwn(operationItem.responses, response)) {
254
+ const responseItem = operationItem.responses[response];
255
+ if (responseItem.headers && typeof responseItem.headers === "object") responseItem.headers = Object.entries(responseItem.headers).reduce((acc, [name, header]) => {
256
+ if (header && typeof header === "object") return {
257
+ [name]: transformResponseHeader(header),
258
+ ...acc
259
+ };
260
+ return acc;
261
+ }, {});
262
+ if (responseItem.schema) {
263
+ const produces = document.produces ?? operationItem.produces ?? [DEFAULT_MEDIA_TYPE];
264
+ if (typeof responseItem.content !== "object") responseItem.content = {};
265
+ for (const type of produces) responseItem.content[type] = { schema: responseItem.schema };
266
+ delete responseItem.schema;
267
+ }
268
+ if (responseItem.examples && typeof responseItem.examples === "object") {
269
+ if (typeof responseItem.content !== "object") responseItem.content = {};
270
+ const defaultMediaType = (document.produces ?? operationItem.produces ?? [DEFAULT_MEDIA_TYPE])[0] ?? DEFAULT_MEDIA_TYPE;
271
+ for (const [key, exampleValue] of Object.entries(responseItem.examples)) if (isMediaTypeKey(key)) {
272
+ if (typeof responseItem.content[key] !== "object") responseItem.content[key] = {};
273
+ responseItem.content[key].example = exampleValue;
274
+ } else {
275
+ if (typeof responseItem.content[defaultMediaType] !== "object") responseItem.content[defaultMediaType] = {};
276
+ const mediaEntry = responseItem.content[defaultMediaType];
277
+ if (typeof mediaEntry.examples !== "object") mediaEntry.examples = {};
278
+ mediaEntry.examples[key] = wrapAsExampleObject(exampleValue);
279
+ }
280
+ delete responseItem.examples;
281
+ }
282
+ if (responseItem.content && typeof responseItem.content === "object") removeEmptySchemaOnlyContentEntries(responseItem.content);
283
+ }
284
+ }
285
+ delete operationItem.produces;
286
+ if (operationItem.parameters?.length === 0) delete operationItem.parameters;
287
+ }
288
+ }
289
+ }
290
+ if (document.securityDefinitions) {
291
+ if (typeof document.components !== "object" || document.components === null) document.components = {};
292
+ if (document.components && typeof document.components === "object") Object.assign(document.components, { securitySchemes: {} });
293
+ for (const [key, securityScheme] of Object.entries(document.securityDefinitions)) if (typeof securityScheme === "object") {
294
+ if ("type" in securityScheme && securityScheme.type === "oauth2") {
295
+ const { flow, authorizationUrl, tokenUrl, scopes } = securityScheme;
296
+ if (document.components && typeof document.components === "object" && "securitySchemes" in document.components && document.components.securitySchemes) Object.assign(document.components.securitySchemes, { [key]: {
297
+ type: "oauth2",
298
+ flows: { [upgradeFlow(flow || "implicit")]: Object.assign({}, authorizationUrl && { authorizationUrl }, tokenUrl && { tokenUrl }, scopes && { scopes }) }
299
+ } });
300
+ } else if ("type" in securityScheme && securityScheme.type === "basic") {
301
+ if (document.components && typeof document.components === "object" && "securitySchemes" in document.components && document.components.securitySchemes) Object.assign(document.components.securitySchemes, { [key]: {
302
+ type: "http",
303
+ scheme: "basic"
304
+ } });
305
+ } else if (document.components && typeof document.components === "object" && "securitySchemes" in document.components && document.components.securitySchemes) Object.assign(document.components.securitySchemes, { [key]: securityScheme });
306
+ }
307
+ delete document.securityDefinitions;
308
+ }
309
+ delete document.consumes;
310
+ delete document.produces;
311
+ return document;
312
+ }
313
+ function transformItemsObject(obj) {
314
+ return [
315
+ "type",
316
+ "format",
317
+ "default",
318
+ "items",
319
+ "maximum",
320
+ "exclusiveMaximum",
321
+ "minimum",
322
+ "exclusiveMinimum",
323
+ "maxLength",
324
+ "minLength",
325
+ "pattern",
326
+ "maxItems",
327
+ "minItems",
328
+ "uniqueItems",
329
+ "enum",
330
+ "multipleOf"
331
+ ].reduce((acc, property) => {
332
+ if (Object.hasOwn(obj, property)) {
333
+ acc[property] = obj[property];
334
+ delete obj[property];
335
+ }
336
+ return acc;
337
+ }, {});
338
+ }
339
+ function getParameterLocation(location) {
340
+ if (location === "formData") throw new Error("Encountered a formData parameter which should have been filtered out by the caller");
341
+ if (location === "body") throw new Error("Encountered a body parameter which should have been filtered out by the caller");
342
+ return location;
343
+ }
344
+ function transformParameterObject(parameter) {
345
+ if (Object.hasOwn(parameter, "$ref") && typeof parameter.$ref === "string") return { $ref: parameter.$ref };
346
+ const serializationStyle = getParameterSerializationStyle(parameter);
347
+ const schema = transformItemsObject(parameter);
348
+ const { xExample, xExamples } = extractXExampleExtensions(parameter);
349
+ if (isNonEmptyObject(xExample)) parameter.examples = transformXExampleToExamples(xExample);
350
+ else if (isNonEmptyObject(xExamples)) parameter.examples = Object.entries(xExamples).reduce((acc, [key, exampleValue]) => {
351
+ acc[key] = wrapAsExampleObject(exampleValue);
352
+ return acc;
353
+ }, {});
354
+ delete parameter.collectionFormat;
355
+ delete parameter.default;
356
+ if (!parameter.in) throw new Error("Parameter object must have an \"in\" property");
357
+ return {
358
+ schema,
359
+ ...serializationStyle,
360
+ ...parameter,
361
+ in: getParameterLocation(parameter.in)
362
+ };
363
+ }
364
+ /**
365
+ * Transform OpenAPI 2.0 response header to OpenAPI 3.0 format.
366
+ * Response headers do not have "in", "name", "style", or "explode" properties.
367
+ */
368
+ function transformResponseHeader(header) {
369
+ if (Object.hasOwn(header, "$ref") && typeof header.$ref === "string") return { $ref: header.$ref };
370
+ const schema = transformItemsObject(header);
371
+ return {
372
+ ...header,
373
+ schema
374
+ };
375
+ }
376
+ const querySerialization = {
377
+ ssv: {
378
+ style: "spaceDelimited",
379
+ explode: false
380
+ },
381
+ pipes: {
382
+ style: "pipeDelimited",
383
+ explode: false
384
+ },
385
+ multi: {
386
+ style: "form",
387
+ explode: true
388
+ },
389
+ csv: {
390
+ style: "form",
391
+ explode: false
392
+ },
393
+ tsv: {}
394
+ };
395
+ const pathAndHeaderSerialization = {
396
+ ssv: {},
397
+ pipes: {},
398
+ multi: {},
399
+ csv: {
400
+ style: "simple",
401
+ explode: false
402
+ },
403
+ tsv: {}
404
+ };
405
+ const serializationStyles = {
406
+ header: pathAndHeaderSerialization,
407
+ query: querySerialization,
408
+ path: pathAndHeaderSerialization
409
+ };
410
+ function getParameterSerializationStyle(parameter) {
411
+ if (parameter.type !== "array" || !(parameter.in === "query" || parameter.in === "path" || parameter.in === "header")) return {};
412
+ const collectionFormat = parameter.collectionFormat ?? "csv";
413
+ if (parameter.in in serializationStyles && collectionFormat in serializationStyles[parameter.in]) return serializationStyles[parameter.in][collectionFormat];
414
+ return {};
415
+ }
416
+ function migrateBodyParameter(bodyParameter, consumes) {
417
+ const { xExample, xExamples } = extractXExampleExtensions(bodyParameter);
418
+ delete bodyParameter.name;
419
+ delete bodyParameter.in;
420
+ const { schema, ...requestBody } = bodyParameter;
421
+ const requestBodyObject = {
422
+ content: {},
423
+ ...requestBody
424
+ };
425
+ if (requestBodyObject.content) for (const type of consumes) {
426
+ requestBodyObject.content[type] = { schema };
427
+ if (isNonEmptyObject(xExamples) && type in xExamples) {
428
+ const examples = xExamples[type];
429
+ if (isNonEmptyObject(examples) && Object.values(examples).every((example) => isExampleObject(example))) requestBodyObject.content[type].examples = examples;
430
+ else if (isNamedExamplesCollection(examples)) requestBodyObject.content[type].examples = Object.entries(examples).reduce((acc, [key, exampleValue]) => {
431
+ acc[key] = wrapAsExampleObject(exampleValue);
432
+ return acc;
433
+ }, {});
434
+ else requestBodyObject.content[type].examples = { default: wrapAsExampleObject(examples) };
435
+ } else if (isNonEmptyObject(xExamples) && !Object.keys(xExamples).some(isMediaTypeKey)) requestBodyObject.content[type].examples = Object.entries(xExamples).reduce((acc, [key, exampleValue]) => {
436
+ acc[key] = wrapAsExampleObject(exampleValue);
437
+ return acc;
438
+ }, {});
439
+ if (!requestBodyObject.content[type].examples && isNonEmptyObject(xExample) && type in xExample) requestBodyObject.content[type].example = xExample[type];
440
+ }
441
+ return requestBodyObject;
442
+ }
443
+ function migrateFormDataParameter(parameters, consumes = ["multipart/form-data"]) {
444
+ const requestBodyObject = { content: {} };
445
+ const filtered = consumes.filter((type) => type === "multipart/form-data" || type === "application/x-www-form-urlencoded");
446
+ const contentTypes = filtered.length > 0 ? filtered : ["multipart/form-data"];
447
+ if (requestBodyObject.content) for (const contentType of contentTypes) {
448
+ requestBodyObject.content[contentType] = { schema: {
449
+ type: "object",
450
+ properties: {},
451
+ required: []
452
+ } };
453
+ const formContent = requestBodyObject.content?.[contentType];
454
+ if (formContent?.schema && typeof formContent.schema === "object" && "properties" in formContent.schema) {
455
+ for (const param of parameters) if (param.name && formContent.schema.properties) {
456
+ formContent.schema.properties[param.name] = {
457
+ type: param.type,
458
+ description: param.description,
459
+ ...param.format ? { format: param.format } : {}
460
+ };
461
+ if (param.required && Array.isArray(formContent.schema.required)) formContent.schema.required.push(param.name);
462
+ }
463
+ }
464
+ }
465
+ return requestBodyObject;
466
+ }
467
+ function migrateParameters(parameters, consumes) {
468
+ const result = { parameters: parameters.filter((parameter) => !(parameter.in === "body" || parameter.in === "formData")).map((parameter) => transformParameterObject(parameter)) };
469
+ const bodyParameter = structuredClone(parameters.find((parameter) => parameter.in === "body") ?? {});
470
+ if (bodyParameter && Object.keys(bodyParameter).length) result.requestBody = migrateBodyParameter(bodyParameter, consumes);
471
+ const formDataParameters = parameters.filter((parameter) => parameter.in === "formData");
472
+ if (formDataParameters.length > 0) {
473
+ const requestBodyObject = migrateFormDataParameter(formDataParameters, consumes);
474
+ if (typeof result.requestBody !== "object") result.requestBody = requestBodyObject;
475
+ else result.requestBody = {
476
+ ...result.requestBody,
477
+ content: {
478
+ ...result.requestBody.content,
479
+ ...requestBodyObject.content
480
+ }
481
+ };
482
+ if (typeof result.requestBody !== "object") result.requestBody = { content: {} };
483
+ }
484
+ return result;
485
+ }
486
+ //#endregion
487
+ export { upgradeFromTwoToThree };
@@ -0,0 +1,95 @@
1
+ import { traverse } from "../helpers/traverse.js";
2
+ //#region ../../node_modules/.pnpm/@scalar+openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/3.0-to-3.1/upgrade-from-three-to-three-one.js
3
+ const SCHEMA_SEGMENTS = new Set([
4
+ "properties",
5
+ "items",
6
+ "allOf",
7
+ "anyOf",
8
+ "oneOf",
9
+ "not",
10
+ "additionalProperties",
11
+ "schema"
12
+ ]);
13
+ /** Determine if the current path is within a schema - optimized version */
14
+ function isSchemaPath(path) {
15
+ if (!path) return false;
16
+ if (path.some((segment) => SCHEMA_SEGMENTS.has(segment))) return true;
17
+ if (path.some((segment) => segment.endsWith("Schema"))) return true;
18
+ if (path.length >= 2 && path[0] === "components" && path[1] === "schemas") return true;
19
+ return false;
20
+ }
21
+ /**
22
+ * Upgrade from OpenAPI 3.0.x to 3.1.1
23
+ *
24
+ * https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0
25
+ */
26
+ function upgradeFromThreeToThreeOne(originalContent) {
27
+ let content = originalContent;
28
+ if (content === null || typeof content.openapi !== "string" || !content.openapi.startsWith("3.0")) return content;
29
+ content.openapi = "3.1.1";
30
+ content = traverse(content, applyChangesToDocument);
31
+ return content;
32
+ }
33
+ const applyChangesToDocument = (schema, path) => {
34
+ if (schema.type !== void 0 && schema.nullable === true) {
35
+ schema.type = [schema.type, "null"];
36
+ delete schema.nullable;
37
+ }
38
+ if (schema.exclusiveMinimum === true) {
39
+ schema.exclusiveMinimum = schema.minimum;
40
+ delete schema.minimum;
41
+ } else if (schema.exclusiveMinimum === false) delete schema.exclusiveMinimum;
42
+ if (schema.exclusiveMaximum === true) {
43
+ schema.exclusiveMaximum = schema.maximum;
44
+ delete schema.maximum;
45
+ } else if (schema.exclusiveMaximum === false) delete schema.exclusiveMaximum;
46
+ const isInsideExamplesMap = path?.some((segment, index) => {
47
+ if (segment === "examples" && index > 0) return path[index - 1] !== "properties";
48
+ return false;
49
+ });
50
+ if (schema.example !== void 0 && !isInsideExamplesMap) {
51
+ if (isSchemaPath(path)) schema.examples = [schema.example];
52
+ else schema.examples = { default: { value: schema.example } };
53
+ delete schema.example;
54
+ }
55
+ if (schema.type === "object" && schema.properties !== void 0) {
56
+ if ((path?.slice(0, -1))?.some((segment, index) => {
57
+ return segment === "content" && path?.[index + 1] === "multipart/form-data";
58
+ }) && schema.properties !== null) {
59
+ for (const value of Object.values(schema.properties)) if (typeof value === "object" && value !== null && "type" in value && "format" in value && value.type === "string" && value.format === "binary") {
60
+ value.contentMediaType = "application/octet-stream";
61
+ delete value.format;
62
+ }
63
+ }
64
+ }
65
+ if (path?.includes("content") && path?.includes("application/octet-stream")) return {};
66
+ const { format: _, ...rest } = schema;
67
+ if (schema.type === "string") {
68
+ if (schema.format === "binary") return {
69
+ ...rest,
70
+ type: "string",
71
+ contentMediaType: "application/octet-stream"
72
+ };
73
+ if (schema.format === "base64") return {
74
+ ...rest,
75
+ type: "string",
76
+ contentEncoding: "base64"
77
+ };
78
+ if (schema.format === "byte") {
79
+ const contentMediaType = (path?.slice(0, -1))?.find((_, index) => path?.[index - 1] === "content");
80
+ return {
81
+ ...rest,
82
+ type: "string",
83
+ contentEncoding: "base64",
84
+ contentMediaType
85
+ };
86
+ }
87
+ }
88
+ if (schema["x-webhooks"] !== void 0) {
89
+ schema.webhooks = schema["x-webhooks"];
90
+ delete schema["x-webhooks"];
91
+ }
92
+ return schema;
93
+ };
94
+ //#endregion
95
+ export { upgradeFromThreeToThreeOne };
@@ -0,0 +1,59 @@
1
+ //#region ../../node_modules/.pnpm/@scalar+openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/3.1-to-3.2/upgrade-from-three-one-to-three-two.js
2
+ /**
3
+ * Recursively migrate XML object properties from 3.1 to 3.2 format
4
+ */
5
+ function migrateXmlObjects(obj) {
6
+ if (obj === null || typeof obj !== "object") return;
7
+ if (Array.isArray(obj)) {
8
+ for (const item of obj) migrateXmlObjects(item);
9
+ return;
10
+ }
11
+ if (obj.xml && typeof obj.xml === "object") {
12
+ if (obj.xml.wrapped === true && obj.xml.attribute === true) throw new Error("Invalid XML configuration: wrapped and attribute cannot be true at the same time.");
13
+ if (obj.xml.wrapped === true) {
14
+ delete obj.xml.wrapped;
15
+ obj.xml.nodeType = "element";
16
+ }
17
+ if (obj.xml.attribute === true) {
18
+ delete obj.xml.attribute;
19
+ obj.xml.nodeType = "attribute";
20
+ }
21
+ }
22
+ for (const key in obj) if (Object.hasOwn(obj, key)) migrateXmlObjects(obj[key]);
23
+ }
24
+ /**
25
+ * Migrate x-tagGroups to kind property on tags
26
+ */
27
+ function migrateTagGroups(document) {
28
+ if (document["x-tagGroups"] && Array.isArray(document["x-tagGroups"])) {
29
+ const tagGroups = document["x-tagGroups"];
30
+ if (!document.tags) document.tags = [];
31
+ const tagGroupMap = /* @__PURE__ */ new Map();
32
+ for (const group of tagGroups) for (const tagName of group.tags) tagGroupMap.set(tagName, group.name);
33
+ if (Array.isArray(document.tags)) {
34
+ for (const tag of document.tags) if (typeof tag === "object" && tag !== null && "name" in tag) {
35
+ const groupName = tagGroupMap.get(tag.name);
36
+ if (groupName) if (groupName.toLowerCase().includes("nav") || groupName.toLowerCase().includes("navigation")) tag.kind = "nav";
37
+ else if (groupName.toLowerCase().includes("audience")) tag.kind = "audience";
38
+ else if (groupName.toLowerCase().includes("badge")) tag.kind = "badge";
39
+ else tag.kind = "nav";
40
+ }
41
+ }
42
+ delete document["x-tagGroups"];
43
+ }
44
+ }
45
+ /**
46
+ * Upgrade OpenAPI 3.1 to 3.2
47
+ *
48
+ * @see https://github.com/OAI/OpenAPI-Specification/compare/main...v3.2-dev
49
+ */
50
+ function upgradeFromThreeOneToThreeTwo(originalDocument) {
51
+ const document = originalDocument;
52
+ if (document !== null && typeof document === "object" && typeof document.openapi === "string" && document.openapi?.startsWith("3.1")) document.openapi = "3.2.0";
53
+ else return document;
54
+ migrateTagGroups(document);
55
+ migrateXmlObjects(document);
56
+ return document;
57
+ }
58
+ //#endregion
59
+ export { upgradeFromThreeOneToThreeTwo };
@@ -0,0 +1,25 @@
1
+ //#region ../../node_modules/.pnpm/@scalar+openapi-upgrader@0.2.4/node_modules/@scalar/openapi-upgrader/dist/helpers/traverse.js
2
+ /**
3
+ * Recursively traverses the content and applies the transform function to each node.
4
+ */
5
+ function traverse(content, transform, path = []) {
6
+ const result = {};
7
+ for (const [key, value] of Object.entries(content)) {
8
+ const currentPath = [...path, key];
9
+ if (Array.isArray(value)) {
10
+ result[key] = value.map((item, index) => {
11
+ if (typeof item === "object" && !Array.isArray(item) && item !== null) return traverse(item, transform, [...currentPath, index.toString()]);
12
+ return item;
13
+ });
14
+ continue;
15
+ }
16
+ if (typeof value === "object" && value !== null) {
17
+ result[key] = traverse(value, transform, currentPath);
18
+ continue;
19
+ }
20
+ result[key] = value;
21
+ }
22
+ return transform(result, path);
23
+ }
24
+ //#endregion
25
+ export { traverse };