@scalar/openapi-parser 0.10.17 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @scalar/openapi-parser
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 483ca93: chore: require Node 20 (or above)
8
+
9
+ ### Patch Changes
10
+
11
+ - bd602d3: chore: mark pipeline syntax as deprecated
12
+ - 1d1470c: feat: speed up the upgrade utility
13
+
3
14
  ## 0.10.17
4
15
 
5
16
  ### Patch Changes
package/README.md CHANGED
@@ -7,14 +7,6 @@
7
7
 
8
8
  Modern OpenAPI parser written in TypeScript with support for OpenAPI 3.1, OpenAPI 3.0 and Swagger 2.0.
9
9
 
10
- ## Goals
11
-
12
- - [x] Written in TypeScript
13
- - [x] Runs in Node.js and in the browser (without any polyfills or configuration)
14
- - [x] Tested with hundreds of real world examples
15
- - [ ] Amazing error output
16
- - [ ] Support for OpenAPI 4.0 👀
17
-
18
10
  ## Installation
19
11
 
20
12
  ```bash
@@ -140,25 +132,6 @@ const result = sanitize({
140
132
  console.log(result)
141
133
  ```
142
134
 
143
- ### Pipeline syntax
144
-
145
- ```ts
146
- import { openapi } from '@scalar/openapi-parser'
147
-
148
- const specification = …
149
-
150
- // New pipeline …
151
- const result = openapi()
152
- // loads the specification …
153
- .load(specification)
154
- // upgrades to OpenAPI 3.1 …
155
- .upgrade()
156
- // removes all internal operations …
157
- .filter((schema) => !schema?.['x-internal'])
158
- // done!
159
- .get()
160
- ```
161
-
162
135
  ### Then/Catch syntax
163
136
 
164
137
  If you’re more the then/catch type of guy, that’s fine:
@@ -1,5 +1,6 @@
1
+ import type { Filesystem } from '../types/index.js';
1
2
  /**
2
3
  * Check if the value is a filesystem
3
4
  */
4
- export declare function isFilesystem(value: any): boolean;
5
+ export declare function isFilesystem(value: any): value is Filesystem;
5
6
  //# sourceMappingURL=isFilesystem.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"isFilesystem.d.ts","sourceRoot":"","sources":["../../src/utils/isFilesystem.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,WAOtC"}
1
+ {"version":3,"file":"isFilesystem.d.ts","sourceRoot":"","sources":["../../src/utils/isFilesystem.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAE1C;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,GAAG,GAAG,KAAK,IAAI,UAAU,CAO5D"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/isFilesystem.ts"],
4
- "sourcesContent": ["/**\n * Check if the value is a filesystem\n */\nexport function isFilesystem(value: any) {\n return (\n typeof value !== 'undefined' &&\n Array.isArray(value) &&\n value.length > 0 &&\n value.some((file) => file.isEntrypoint === true)\n )\n}\n"],
5
- "mappings": "AAGO,SAAS,aAAa,OAAY;AACvC,SACE,OAAO,UAAU,eACjB,MAAM,QAAQ,KAAK,KACnB,MAAM,SAAS,KACf,MAAM,KAAK,CAAC,SAAS,KAAK,iBAAiB,IAAI;AAEnD;",
4
+ "sourcesContent": ["import type { Filesystem } from '../types'\n\n/**\n * Check if the value is a filesystem\n */\nexport function isFilesystem(value: any): value is Filesystem {\n return (\n typeof value !== 'undefined' &&\n Array.isArray(value) &&\n value.length > 0 &&\n value.some((file) => file.isEntrypoint === true)\n )\n}\n"],
5
+ "mappings": "AAKO,SAAS,aAAa,OAAiC;AAC5D,SACE,OAAO,UAAU,eACjB,MAAM,QAAQ,KAAK,KACnB,MAAM,SAAS,KACf,MAAM,KAAK,CAAC,SAAS,KAAK,iBAAiB,IAAI;AAEnD;",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,8 @@ import type { AnyApiDefinitionFormat, OpenApiOptions } from '../../types/index.j
2
2
  import type { LoadOptions } from '../load/load.js';
3
3
  /**
4
4
  * Creates a fluent OpenAPI pipeline
5
+ *
6
+ * @deprecated We are about to drop the pipeline syntax. Use the individual utilities instead.
5
7
  */
6
8
  export declare function openapi(globalOptions?: OpenApiOptions): {
7
9
  load: (input: AnyApiDefinitionFormat, options?: LoadOptions) => {
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../src/utils/openapi/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAS,MAAM,mBAAmB,CAAA;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C;;GAEG;AACH,wBAAgB,OAAO,CAAC,aAAa,CAAC,EAAE,cAAc;kBASpC,sBAAsB,YAAY,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE9D"}
1
+ {"version":3,"file":"openapi.d.ts","sourceRoot":"","sources":["../../../src/utils/openapi/openapi.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,cAAc,EAAS,MAAM,mBAAmB,CAAA;AACtF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAG/C;;;;GAIG;AACH,wBAAgB,OAAO,CAAC,aAAa,CAAC,EAAE,cAAc;kBASpC,sBAAsB,YAAY,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAE9D"}
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/utils/openapi/openapi.ts"],
4
- "sourcesContent": ["import type { AnyApiDefinitionFormat, OpenApiOptions, Queue } from '../../types/index'\nimport type { LoadOptions } from '../load/load'\nimport { loadCommand } from './commands/loadCommand'\n\n/**\n * Creates a fluent OpenAPI pipeline\n */\nexport function openapi(globalOptions?: OpenApiOptions) {\n // Create a new queue\n const queue = {\n input: null,\n options: globalOptions,\n tasks: [],\n } as Queue<[]>\n\n return {\n load: (input: AnyApiDefinitionFormat, options?: LoadOptions) => loadCommand(queue, input, options),\n }\n}\n"],
5
- "mappings": "AAEA,SAAS,mBAAmB;AAKrB,SAAS,QAAQ,eAAgC;AAEtD,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,EACV;AAEA,SAAO;AAAA,IACL,MAAM,CAAC,OAA+B,YAA0B,YAAY,OAAO,OAAO,OAAO;AAAA,EACnG;AACF;",
4
+ "sourcesContent": ["import type { AnyApiDefinitionFormat, OpenApiOptions, Queue } from '../../types/index'\nimport type { LoadOptions } from '../load/load'\nimport { loadCommand } from './commands/loadCommand'\n\n/**\n * Creates a fluent OpenAPI pipeline\n *\n * @deprecated We are about to drop the pipeline syntax. Use the individual utilities instead.\n */\nexport function openapi(globalOptions?: OpenApiOptions) {\n // Create a new queue\n const queue = {\n input: null,\n options: globalOptions,\n tasks: [],\n } as Queue<[]>\n\n return {\n load: (input: AnyApiDefinitionFormat, options?: LoadOptions) => loadCommand(queue, input, options),\n }\n}\n"],
5
+ "mappings": "AAEA,SAAS,mBAAmB;AAOrB,SAAS,QAAQ,eAAgC;AAEtD,QAAM,QAAQ;AAAA,IACZ,OAAO;AAAA,IACP,SAAS;AAAA,IACT,OAAO,CAAC;AAAA,EACV;AAEA,SAAO;AAAA,IACL,MAAM,CAAC,OAA+B,YAA0B,YAAY,OAAO,OAAO,OAAO;AAAA,EACnG;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,6 @@
1
- import type { AnyObject } from '../types/index.js';
1
+ import type { UnknownObject } from '@scalar/types/utils';
2
2
  /**
3
- * Recursively traverses the specification and applies the transform function to each node.
3
+ * Recursively traverses the content and applies the transform function to each node.
4
4
  */
5
- export declare function traverse(specification: AnyObject, transform: (specification: AnyObject, path?: string[]) => AnyObject, path?: string[]): AnyObject;
5
+ export declare function traverse(content: UnknownObject, transform: (content: UnknownObject, path?: string[]) => UnknownObject, path?: string[]): UnknownObject;
6
6
  //# sourceMappingURL=traverse.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../src/utils/traverse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C;;GAEG;AACH,wBAAgB,QAAQ,CACtB,aAAa,EAAE,SAAS,EACxB,SAAS,EAAE,CAAC,aAAa,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,SAAS,EACnE,IAAI,GAAE,MAAM,EAAO,aAsBpB"}
1
+ {"version":3,"file":"traverse.d.ts","sourceRoot":"","sources":["../../src/utils/traverse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAGxD;;GAEG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,aAAa,EACtB,SAAS,EAAE,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,aAAa,EACrE,IAAI,GAAE,MAAM,EAAO,iBA6BpB"}
@@ -1,6 +1,6 @@
1
- function traverse(specification, transform, path = []) {
1
+ function traverse(content, transform, path = []) {
2
2
  const result = {};
3
- for (const [key, value] of Object.entries(specification)) {
3
+ for (const [key, value] of Object.entries(content)) {
4
4
  const currentPath = [...path, key];
5
5
  if (Array.isArray(value)) {
6
6
  result[key] = value.map((item, index) => {
@@ -9,11 +9,13 @@ function traverse(specification, transform, path = []) {
9
9
  }
10
10
  return item;
11
11
  });
12
- } else if (typeof value === "object" && !Array.isArray(value) && value !== null) {
12
+ continue;
13
+ }
14
+ if (typeof value === "object" && value !== null) {
13
15
  result[key] = traverse(value, transform, currentPath);
14
- } else {
15
- result[key] = value;
16
+ continue;
16
17
  }
18
+ result[key] = value;
17
19
  }
18
20
  return transform(result, path);
19
21
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/traverse.ts"],
4
- "sourcesContent": ["import type { AnyObject } from '../types/index'\n\n/**\n * Recursively traverses the specification and applies the transform function to each node.\n */\nexport function traverse(\n specification: AnyObject,\n transform: (specification: AnyObject, path?: string[]) => AnyObject,\n path: string[] = [],\n) {\n const result: AnyObject = {}\n\n for (const [key, value] of Object.entries(specification)) {\n const currentPath = [...path, key]\n if (Array.isArray(value)) {\n result[key] = value.map((item, index) => {\n if (typeof item === 'object' && !Array.isArray(item) && item !== null) {\n return traverse(item, transform, [...currentPath, index.toString()])\n }\n\n return item\n })\n } else if (typeof value === 'object' && !Array.isArray(value) && value !== null) {\n result[key] = traverse(value, transform, currentPath)\n } else {\n result[key] = value\n }\n }\n\n return transform(result, path)\n}\n"],
5
- "mappings": "AAKO,SAAS,SACd,eACA,WACA,OAAiB,CAAC,GAClB;AACA,QAAM,SAAoB,CAAC;AAE3B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxD,UAAM,cAAc,CAAC,GAAG,MAAM,GAAG;AACjC,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,GAAG,IAAI,MAAM,IAAI,CAAC,MAAM,UAAU;AACvC,YAAI,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,KAAK,SAAS,MAAM;AACrE,iBAAO,SAAS,MAAM,WAAW,CAAC,GAAG,aAAa,MAAM,SAAS,CAAC,CAAC;AAAA,QACrE;AAEA,eAAO;AAAA,MACT,CAAC;AAAA,IACH,WAAW,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,KAAK,UAAU,MAAM;AAC/E,aAAO,GAAG,IAAI,SAAS,OAAO,WAAW,WAAW;AAAA,IACtD,OAAO;AACL,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO,UAAU,QAAQ,IAAI;AAC/B;",
4
+ "sourcesContent": ["import type { UnknownObject } from '@scalar/types/utils'\nimport type { AnyObject } from '../types/index'\n\n/**\n * Recursively traverses the content and applies the transform function to each node.\n */\nexport function traverse(\n content: UnknownObject,\n transform: (content: UnknownObject, path?: string[]) => UnknownObject,\n path: string[] = [],\n) {\n const result: AnyObject = {}\n\n for (const [key, value] of Object.entries(content)) {\n const currentPath = [...path, key]\n\n if (Array.isArray(value)) {\n result[key] = value.map((item, index) => {\n if (typeof item === 'object' && !Array.isArray(item) && item !== null) {\n return traverse(item, transform, [...currentPath, index.toString()])\n }\n\n return item\n })\n\n continue\n }\n\n if (typeof value === 'object' && value !== null) {\n result[key] = traverse(value as UnknownObject, transform, currentPath)\n\n continue\n }\n\n result[key] = value\n }\n\n return transform(result, path)\n}\n"],
5
+ "mappings": "AAMO,SAAS,SACd,SACA,WACA,OAAiB,CAAC,GAClB;AACA,QAAM,SAAoB,CAAC;AAE3B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,OAAO,GAAG;AAClD,UAAM,cAAc,CAAC,GAAG,MAAM,GAAG;AAEjC,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,aAAO,GAAG,IAAI,MAAM,IAAI,CAAC,MAAM,UAAU;AACvC,YAAI,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,KAAK,SAAS,MAAM;AACrE,iBAAO,SAAS,MAAM,WAAW,CAAC,GAAG,aAAa,MAAM,SAAS,CAAC,CAAC;AAAA,QACrE;AAEA,eAAO;AAAA,MACT,CAAC;AAED;AAAA,IACF;AAEA,QAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,aAAO,GAAG,IAAI,SAAS,OAAwB,WAAW,WAAW;AAErE;AAAA,IACF;AAEA,WAAO,GAAG,IAAI;AAAA,EAChB;AAEA,SAAO,UAAU,QAAQ,IAAI;AAC/B;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=upgrade.bench.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upgrade.bench.d.ts","sourceRoot":"","sources":["../../src/utils/upgrade.bench.ts"],"names":[],"mappings":""}
@@ -0,0 +1,31 @@
1
+ import { bench, describe, expect } from "vitest";
2
+ import { upgrade } from "./upgrade.js";
3
+ import { upgradeFromTwoToThree } from "./upgradeFromTwoToThree.js";
4
+ const STRIPE = await fetch(
5
+ "https://raw.githubusercontent.com/stripe/openapi/refs/heads/master/openapi/spec3.json"
6
+ ).then((r) => r.json());
7
+ const PETSTORE = await fetch("https://petstore.swagger.io/v2/swagger.json").then((r) => r.json());
8
+ describe("upgrade", () => {
9
+ describe("Petstore: Swagger 2.0 to OpenAPI 3.0", () => {
10
+ bench("new", () => {
11
+ expect(PETSTORE.swagger).toBe("2.0");
12
+ const result = upgradeFromTwoToThree({ ...PETSTORE });
13
+ expect(result.openapi).toBe("3.0.4");
14
+ });
15
+ });
16
+ describe("Stripe: OpenAPI 3.0 to 3.1", () => {
17
+ bench("new", () => {
18
+ expect(STRIPE.openapi).toBe("3.0.0");
19
+ const { specification } = upgrade(JSON.stringify(STRIPE));
20
+ expect(specification?.openapi).toBe("3.1.1");
21
+ });
22
+ });
23
+ describe("Petstore: Swagger 2.0 to OpenAPI 3.1", () => {
24
+ bench("new", () => {
25
+ expect(PETSTORE.swagger).toBe("2.0");
26
+ const { specification } = upgrade(JSON.stringify(PETSTORE));
27
+ expect(specification?.openapi).toBe("3.1.1");
28
+ });
29
+ });
30
+ });
31
+ //# sourceMappingURL=upgrade.bench.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/utils/upgrade.bench.ts"],
4
+ "sourcesContent": ["import { bench, describe, expect } from 'vitest'\n\n// import { upgrade as upgradeOld } from './slow/upgrade'\n// import { upgradeFromTwoToThree as upgradeFromTwoToThreeOld } from './slow/upgradeFromTwoToThree'\nimport { upgrade } from './upgrade'\nimport { upgradeFromTwoToThree } from './upgradeFromTwoToThree'\n\n// Setup the test data\nconst STRIPE = await fetch(\n 'https://raw.githubusercontent.com/stripe/openapi/refs/heads/master/openapi/spec3.json',\n).then((r) => r.json())\n\nconst PETSTORE = await fetch('https://petstore.swagger.io/v2/swagger.json').then((r) => r.json())\n\ndescribe('upgrade', () => {\n describe('Petstore: Swagger 2.0 to OpenAPI 3.0', () => {\n bench('new', () => {\n expect(PETSTORE.swagger).toBe('2.0')\n\n const result = upgradeFromTwoToThree({ ...PETSTORE })\n\n expect(result.openapi).toBe('3.0.4')\n })\n\n // bench('old', () => {\n // expect(PETSTORE.swagger).toBe('2.0')\n\n // const result = upgradeFromTwoToThreeOld({ ...PETSTORE })\n\n // expect(result.openapi).toBe('3.0.4')\n // })\n })\n\n describe('Stripe: OpenAPI 3.0 to 3.1', () => {\n bench('new', () => {\n expect(STRIPE.openapi).toBe('3.0.0')\n\n const { specification } = upgrade(JSON.stringify(STRIPE))\n\n expect(specification?.openapi).toBe('3.1.1')\n })\n\n // bench('old', () => {\n // expect(STRIPE.openapi).toBe('3.0.0')\n\n // const { specification } = upgradeOld(JSON.stringify(STRIPE))\n\n // expect(specification?.openapi).toBe('3.1.1')\n // })\n })\n\n describe('Petstore: Swagger 2.0 to OpenAPI 3.1', () => {\n bench('new', () => {\n expect(PETSTORE.swagger).toBe('2.0')\n\n const { specification } = upgrade(JSON.stringify(PETSTORE))\n\n expect(specification?.openapi).toBe('3.1.1')\n })\n\n // bench('old', () => {\n // expect(PETSTORE.swagger).toBe('2.0')\n\n // const { specification } = upgradeOld(JSON.stringify(PETSTORE))\n\n // expect(specification?.openapi).toBe('3.1.1')\n // })\n })\n})\n"],
5
+ "mappings": "AAAA,SAAS,OAAO,UAAU,cAAc;AAIxC,SAAS,eAAe;AACxB,SAAS,6BAA6B;AAGtC,MAAM,SAAS,MAAM;AAAA,EACnB;AACF,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;AAEtB,MAAM,WAAW,MAAM,MAAM,6CAA6C,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC;AAEhG,SAAS,WAAW,MAAM;AACxB,WAAS,wCAAwC,MAAM;AACrD,UAAM,OAAO,MAAM;AACjB,aAAO,SAAS,OAAO,EAAE,KAAK,KAAK;AAEnC,YAAM,SAAS,sBAAsB,EAAE,GAAG,SAAS,CAAC;AAEpD,aAAO,OAAO,OAAO,EAAE,KAAK,OAAO;AAAA,IACrC,CAAC;AAAA,EASH,CAAC;AAED,WAAS,8BAA8B,MAAM;AAC3C,UAAM,OAAO,MAAM;AACjB,aAAO,OAAO,OAAO,EAAE,KAAK,OAAO;AAEnC,YAAM,EAAE,cAAc,IAAI,QAAQ,KAAK,UAAU,MAAM,CAAC;AAExD,aAAO,eAAe,OAAO,EAAE,KAAK,OAAO;AAAA,IAC7C,CAAC;AAAA,EASH,CAAC;AAED,WAAS,wCAAwC,MAAM;AACrD,UAAM,OAAO,MAAM;AACjB,aAAO,SAAS,OAAO,EAAE,KAAK,KAAK;AAEnC,YAAM,EAAE,cAAc,IAAI,QAAQ,KAAK,UAAU,QAAQ,CAAC;AAE1D,aAAO,eAAe,OAAO,EAAE,KAAK,OAAO;AAAA,IAC7C,CAAC;AAAA,EASH,CAAC;AACH,CAAC;",
6
+ "names": []
7
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAExD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAM1E;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,CAoBnG"}
1
+ {"version":3,"file":"upgrade.d.ts","sourceRoot":"","sources":["../../src/utils/upgrade.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AAGxD,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAc1E;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC,WAAW,CAAC,QAAQ,CAAC,CAmBnG"}
@@ -1,7 +1,14 @@
1
1
  import { getEntrypoint } from "./getEntrypoint.js";
2
- import { makeFilesystem } from "./makeFilesystem.js";
2
+ import { isFilesystem } from "./isFilesystem.js";
3
+ import { normalize } from "./normalize.js";
3
4
  import { upgradeFromThreeToThreeOne } from "./upgradeFromThreeToThreeOne.js";
4
5
  import { upgradeFromTwoToThree } from "./upgradeFromTwoToThree.js";
6
+ const upgraders = [
7
+ // Swagger 2.0 -> OpenAPI 3.0
8
+ upgradeFromTwoToThree,
9
+ // OpenAPI 3.0 -> OpenAPI 3.1
10
+ upgradeFromThreeToThreeOne
11
+ ];
5
12
  function upgrade(value) {
6
13
  if (!value) {
7
14
  return {
@@ -9,10 +16,9 @@ function upgrade(value) {
9
16
  version: "3.1"
10
17
  };
11
18
  }
12
- const upgraders = [upgradeFromTwoToThree, upgradeFromThreeToThreeOne];
13
19
  const result = upgraders.reduce(
14
20
  (currentSpecification, upgrader) => upgrader(currentSpecification),
15
- getEntrypoint(makeFilesystem(value)).specification
21
+ isFilesystem(value) ? getEntrypoint(value).specification : normalize(value)
16
22
  );
17
23
  return {
18
24
  specification: result,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/upgrade.ts"],
4
- "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\nimport type { AnyObject, Filesystem, UpgradeResult } from '../types/index'\nimport { getEntrypoint } from './getEntrypoint'\nimport { makeFilesystem } from './makeFilesystem'\nimport { upgradeFromThreeToThreeOne } from './upgradeFromThreeToThreeOne'\nimport { upgradeFromTwoToThree } from './upgradeFromTwoToThree'\n\n/**\n * Upgrade specification to OpenAPI 3.1.0\n */\nexport function upgrade(value: string | AnyObject | Filesystem): UpgradeResult<OpenAPIV3_1.Document> {\n if (!value) {\n return {\n specification: null,\n version: '3.1',\n }\n }\n const upgraders = [upgradeFromTwoToThree, upgradeFromThreeToThreeOne]\n\n // TODO: Run upgrade over the whole filesystem\n const result = upgraders.reduce(\n (currentSpecification, upgrader) => upgrader(currentSpecification),\n getEntrypoint(makeFilesystem(value)).specification,\n ) as OpenAPIV3_1.Document\n\n return {\n specification: result,\n // TODO: Make dynamic\n version: '3.1',\n } as UpgradeResult<OpenAPIV3_1.Document>\n}\n"],
5
- "mappings": "AAGA,SAAS,qBAAqB;AAC9B,SAAS,sBAAsB;AAC/B,SAAS,kCAAkC;AAC3C,SAAS,6BAA6B;AAK/B,SAAS,QAAQ,OAA6E;AACnG,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,eAAe;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AACA,QAAM,YAAY,CAAC,uBAAuB,0BAA0B;AAGpE,QAAM,SAAS,UAAU;AAAA,IACvB,CAAC,sBAAsB,aAAa,SAAS,oBAAoB;AAAA,IACjE,cAAc,eAAe,KAAK,CAAC,EAAE;AAAA,EACvC;AAEA,SAAO;AAAA,IACL,eAAe;AAAA;AAAA,IAEf,SAAS;AAAA,EACX;AACF;",
4
+ "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\n\nimport type { UnknownObject } from '@scalar/types/utils'\nimport type { AnyObject, Filesystem, UpgradeResult } from '../types/index'\nimport { getEntrypoint } from './getEntrypoint'\nimport { isFilesystem } from './isFilesystem'\nimport { normalize } from './normalize'\nimport { upgradeFromThreeToThreeOne } from './upgradeFromThreeToThreeOne'\nimport { upgradeFromTwoToThree } from './upgradeFromTwoToThree'\n\nconst upgraders = [\n // Swagger 2.0 -> OpenAPI 3.0\n upgradeFromTwoToThree,\n // OpenAPI 3.0 -> OpenAPI 3.1\n upgradeFromThreeToThreeOne,\n]\n\n/**\n * Upgrade specification to OpenAPI 3.1.0\n */\nexport function upgrade(value: string | AnyObject | Filesystem): UpgradeResult<OpenAPIV3_1.Document> {\n if (!value) {\n return {\n specification: null,\n version: '3.1',\n }\n }\n\n // TODO: Run upgrade over the whole filesystem\n const result = upgraders.reduce(\n (currentSpecification, upgrader) => upgrader(currentSpecification as UnknownObject),\n isFilesystem(value) ? getEntrypoint(value).specification : normalize(value),\n ) as OpenAPIV3_1.Document\n\n return {\n specification: result,\n // TODO: Make dynamic\n version: '3.1',\n } as UpgradeResult<OpenAPIV3_1.Document>\n}\n"],
5
+ "mappings": "AAIA,SAAS,qBAAqB;AAC9B,SAAS,oBAAoB;AAC7B,SAAS,iBAAiB;AAC1B,SAAS,kCAAkC;AAC3C,SAAS,6BAA6B;AAEtC,MAAM,YAAY;AAAA;AAAA,EAEhB;AAAA;AAAA,EAEA;AACF;AAKO,SAAS,QAAQ,OAA6E;AACnG,MAAI,CAAC,OAAO;AACV,WAAO;AAAA,MACL,eAAe;AAAA,MACf,SAAS;AAAA,IACX;AAAA,EACF;AAGA,QAAM,SAAS,UAAU;AAAA,IACvB,CAAC,sBAAsB,aAAa,SAAS,oBAAqC;AAAA,IAClF,aAAa,KAAK,IAAI,cAAc,KAAK,EAAE,gBAAgB,UAAU,KAAK;AAAA,EAC5E;AAEA,SAAO;AAAA,IACL,eAAe;AAAA;AAAA,IAEf,SAAS;AAAA,EACX;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,11 +1,13 @@
1
1
  import type { OpenAPIV3_1 } from '@scalar/openapi-types';
2
2
  import type { UnknownObject } from '@scalar/types/utils';
3
+ /** Determine if the current path is within a schema - optimized version */
4
+ export declare function isSchemaPath(path: string[]): boolean;
3
5
  /**
4
6
  * Upgrade from OpenAPI 3.0.x to 3.1.1
5
7
  *
6
8
  * https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0
7
9
  */
8
- export declare function upgradeFromThreeToThreeOne(originalSpecification: UnknownObject): (Omit<Omit<import("@scalar/openapi-types").OpenAPIV3.Document<{}>, "paths" | "components">, keyof {
10
+ export declare function upgradeFromThreeToThreeOne(originalContent: UnknownObject): (Omit<Omit<import("@scalar/openapi-types").OpenAPIV3.Document<{}>, "paths" | "components">, keyof {
9
11
  [customExtension: `x-${string}`]: any;
10
12
  [key: string]: any;
11
13
  }> & {
@@ -26,6 +28,4 @@ export declare function upgradeFromThreeToThreeOne(originalSpecification: Unknow
26
28
  [customExtension: `x-${string}`]: any;
27
29
  [key: string]: any;
28
30
  }) | UnknownObject;
29
- /** Determine if the current path is within a schema */
30
- export declare function isSchemaPath(path: string[]): boolean;
31
31
  //# sourceMappingURL=upgradeFromThreeToThreeOne.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"upgradeFromThreeToThreeOne.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromThreeToThreeOne.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAIxD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,qBAAqB,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;mBAuI9E;AAED,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAsBpD"}
1
+ {"version":3,"file":"upgradeFromThreeToThreeOne.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromThreeToThreeOne.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAkBxD,2EAA2E;AAC3E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAiBpD;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,aAAa;;;;;;;;;;;;;;;;;;;;mBAcxE"}
@@ -1,89 +1,97 @@
1
1
  import { traverse } from "./traverse.js";
2
- function upgradeFromThreeToThreeOne(originalSpecification) {
3
- let specification = originalSpecification;
4
- if (specification !== null && typeof specification.openapi === "string" && specification.openapi.startsWith("3.0")) {
5
- specification.openapi = "3.1.1";
6
- } else {
7
- return specification;
2
+ const SCHEMA_SEGMENTS = /* @__PURE__ */ new Set([
3
+ "properties",
4
+ "items",
5
+ "allOf",
6
+ "anyOf",
7
+ "oneOf",
8
+ "not",
9
+ "additionalProperties",
10
+ "schema"
11
+ ]);
12
+ const SCHEMA_PATHS = /* @__PURE__ */ new Set(["components/schemas"]);
13
+ function isSchemaPath(path) {
14
+ if (path.some((segment) => SCHEMA_SEGMENTS.has(segment))) {
15
+ return true;
8
16
  }
9
- specification = traverse(specification, (schema) => {
10
- if (schema.type !== "undefined" && schema.nullable === true) {
11
- schema.type = [schema.type, "null"];
12
- delete schema.nullable;
13
- }
14
- return schema;
15
- });
16
- specification = traverse(specification, (schema) => {
17
- if (schema.exclusiveMinimum === true) {
18
- schema.exclusiveMinimum = schema.minimum;
19
- delete schema.minimum;
20
- } else if (schema.exclusiveMinimum === false) {
21
- delete schema.exclusiveMinimum;
22
- }
23
- if (schema.exclusiveMaximum === true) {
24
- schema.exclusiveMaximum = schema.maximum;
25
- delete schema.maximum;
26
- } else if (schema.exclusiveMaximum === false) {
27
- delete schema.exclusiveMaximum;
28
- }
29
- return schema;
30
- });
31
- specification = traverse(specification, (schema, path) => {
32
- if (schema.example !== void 0) {
33
- if (isSchemaPath(path)) {
34
- schema.examples = [schema.example];
35
- } else {
36
- schema.examples = {
37
- default: {
38
- value: schema.example
39
- }
40
- };
41
- }
42
- delete schema.example;
17
+ if (path.some((segment) => segment.endsWith("Schema"))) {
18
+ return true;
19
+ }
20
+ if (path.length >= 2 && path[0] === "components" && path[1] === "schemas") {
21
+ return true;
22
+ }
23
+ return false;
24
+ }
25
+ function upgradeFromThreeToThreeOne(originalContent) {
26
+ let content = originalContent;
27
+ if (content === null || typeof content.openapi !== "string" || !content.openapi.startsWith("3.0")) {
28
+ return content;
29
+ }
30
+ content.openapi = "3.1.1";
31
+ content = traverse(content, applyChangesToDocument);
32
+ return content;
33
+ }
34
+ const applyChangesToDocument = (schema, path) => {
35
+ if (schema.type !== "undefined" && schema.nullable === true) {
36
+ schema.type = [schema.type, "null"];
37
+ delete schema.nullable;
38
+ }
39
+ if (schema.exclusiveMinimum === true) {
40
+ schema.exclusiveMinimum = schema.minimum;
41
+ delete schema.minimum;
42
+ } else if (schema.exclusiveMinimum === false) {
43
+ delete schema.exclusiveMinimum;
44
+ }
45
+ if (schema.exclusiveMaximum === true) {
46
+ schema.exclusiveMaximum = schema.maximum;
47
+ delete schema.maximum;
48
+ } else if (schema.exclusiveMaximum === false) {
49
+ delete schema.exclusiveMaximum;
50
+ }
51
+ if (schema.example !== void 0) {
52
+ if (isSchemaPath(path)) {
53
+ schema.examples = [schema.example];
54
+ } else {
55
+ schema.examples = {
56
+ default: {
57
+ value: schema.example
58
+ }
59
+ };
43
60
  }
44
- return schema;
45
- });
46
- specification = traverse(specification, (schema, path) => {
47
- if (schema.type === "object" && schema.properties !== void 0) {
48
- const parentPath = path.slice(0, -1);
49
- const isMultipart = parentPath.some((segment, index) => {
50
- return segment === "content" && path[index + 1] === "multipart/form-data";
51
- });
52
- if (isMultipart) {
53
- const entries = Object.entries(schema.properties);
54
- for (const [_, value] of entries) {
55
- if (typeof value === "object" && value.type === "string" && value.format === "binary") {
56
- value.contentMediaType = "application/octet-stream";
57
- delete value.format;
58
- }
61
+ delete schema.example;
62
+ }
63
+ if (schema.type === "object" && schema.properties !== void 0) {
64
+ const parentPath = path.slice(0, -1);
65
+ const isMultipart = parentPath.some((segment, index) => {
66
+ return segment === "content" && path[index + 1] === "multipart/form-data";
67
+ });
68
+ if (isMultipart) {
69
+ for (const value of Object.values(schema.properties)) {
70
+ if (typeof value === "object" && value !== null && "type" in value && "format" in value && value.type === "string" && value.format === "binary") {
71
+ ;
72
+ value.contentMediaType = "application/octet-stream";
73
+ delete value.format;
59
74
  }
60
75
  }
61
76
  }
62
- return schema;
63
- });
64
- specification = traverse(specification, (schema, path) => {
65
- if (path.includes("content") && path.includes("application/octet-stream")) {
66
- return {};
67
- }
68
- if (schema.type === "string" && schema.format === "binary") {
77
+ }
78
+ if (path.includes("content") && path.includes("application/octet-stream")) {
79
+ return {};
80
+ }
81
+ if (schema.type === "string") {
82
+ if (schema.format === "binary") {
69
83
  return {
70
84
  type: "string",
71
85
  contentMediaType: "application/octet-stream"
72
86
  };
73
87
  }
74
- return schema;
75
- });
76
- specification = traverse(specification, (schema) => {
77
- if (schema.type === "string" && schema.format === "base64") {
88
+ if (schema.format === "base64") {
78
89
  return {
79
90
  type: "string",
80
91
  contentEncoding: "base64"
81
92
  };
82
93
  }
83
- return schema;
84
- });
85
- specification = traverse(specification, (schema, path) => {
86
- if (schema.type === "string" && schema.format === "byte") {
94
+ if (schema.format === "byte") {
87
95
  const parentPath = path.slice(0, -1);
88
96
  const contentMediaType = parentPath.find((_, index) => path[index - 1] === "content");
89
97
  return {
@@ -92,28 +100,9 @@ function upgradeFromThreeToThreeOne(originalSpecification) {
92
100
  contentMediaType
93
101
  };
94
102
  }
95
- return schema;
96
- });
97
- return specification;
98
- }
99
- function isSchemaPath(path) {
100
- const schemaLocations = [
101
- ["components", "schemas"],
102
- "properties",
103
- "items",
104
- "allOf",
105
- "anyOf",
106
- "oneOf",
107
- "not",
108
- "additionalProperties"
109
- ];
110
- return schemaLocations.some((location) => {
111
- if (Array.isArray(location)) {
112
- return location.every((segment, index) => path[index] === segment);
113
- }
114
- return path.includes(location);
115
- }) || path.includes("schema") || path.some((segment) => segment.endsWith("Schema"));
116
- }
103
+ }
104
+ return schema;
105
+ };
117
106
  export {
118
107
  isSchemaPath,
119
108
  upgradeFromThreeToThreeOne
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/upgradeFromThreeToThreeOne.ts"],
4
- "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\nimport type { UnknownObject } from '@scalar/types/utils'\n\nimport { traverse } from './traverse'\n\n/**\n * Upgrade from OpenAPI 3.0.x to 3.1.1\n *\n * https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0\n */\nexport function upgradeFromThreeToThreeOne(originalSpecification: UnknownObject) {\n let specification = originalSpecification\n\n // Version\n if (specification !== null && typeof specification.openapi === 'string' && specification.openapi.startsWith('3.0')) {\n specification.openapi = '3.1.1'\n } else {\n // Skip if it\u2019s something else than 3.0.x\n return specification\n }\n\n // Nullable types\n specification = traverse(specification, (schema) => {\n if (schema.type !== 'undefined' && schema.nullable === true) {\n schema.type = [schema.type, 'null']\n delete schema.nullable\n }\n\n return schema\n })\n\n // exclusiveMinimum and exclusiveMaximum\n specification = traverse(specification, (schema) => {\n if (schema.exclusiveMinimum === true) {\n schema.exclusiveMinimum = schema.minimum\n delete schema.minimum\n } else if (schema.exclusiveMinimum === false) {\n delete schema.exclusiveMinimum\n }\n\n if (schema.exclusiveMaximum === true) {\n schema.exclusiveMaximum = schema.maximum\n delete schema.maximum\n } else if (schema.exclusiveMaximum === false) {\n delete schema.exclusiveMaximum\n }\n\n return schema\n })\n\n // Use examples not example\n specification = traverse(specification, (schema, path) => {\n if (schema.example !== undefined) {\n // Arrays in schemas\n if (isSchemaPath(path)) {\n schema.examples = [schema.example]\n }\n // Objects everywhere else\n else {\n schema.examples = {\n default: {\n value: schema.example,\n },\n }\n }\n delete schema.example\n }\n\n return schema\n })\n\n // Multipart file uploads with a binary file\n specification = traverse(specification, (schema, path) => {\n if (schema.type === 'object' && schema.properties !== undefined) {\n // Check if this is a multipart request body schema\n const parentPath = path.slice(0, -1)\n const isMultipart = parentPath.some((segment, index) => {\n return segment === 'content' && path[index + 1] === 'multipart/form-data'\n })\n\n if (isMultipart) {\n // Types\n const entries: [string, any][] = Object.entries(schema.properties)\n\n for (const [_, value] of entries) {\n if (typeof value === 'object' && value.type === 'string' && value.format === 'binary') {\n value.contentMediaType = 'application/octet-stream'\n delete value.format\n }\n }\n }\n }\n\n return schema\n })\n\n // Uploading a binary file in a POST request\n specification = traverse(specification, (schema, path) => {\n if (path.includes('content') && path.includes('application/octet-stream')) {\n return {}\n }\n\n if (schema.type === 'string' && schema.format === 'binary') {\n return {\n type: 'string',\n contentMediaType: 'application/octet-stream',\n }\n }\n\n return schema\n })\n\n // Uploading an image with base64 encoding\n specification = traverse(specification, (schema) => {\n if (schema.type === 'string' && schema.format === 'base64') {\n return {\n type: 'string',\n contentEncoding: 'base64',\n }\n }\n\n return schema\n })\n\n specification = traverse(specification, (schema, path) => {\n if (schema.type === 'string' && schema.format === 'byte') {\n const parentPath = path.slice(0, -1)\n const contentMediaType = parentPath.find((_, index) => path[index - 1] === 'content')\n\n return {\n type: 'string',\n contentEncoding: 'base64',\n contentMediaType,\n }\n }\n\n return schema\n })\n\n // Declaring $schema Dialects to protect against change\n // if (typeof specification.$schema === 'undefined') {\n // specification.$schema = 'http://json-schema.org/draft-07/schema#'\n // }\n\n return specification as OpenAPIV3_1.Document\n}\n\n/** Determine if the current path is within a schema */\nexport function isSchemaPath(path: string[]): boolean {\n const schemaLocations = [\n ['components', 'schemas'],\n 'properties',\n 'items',\n 'allOf',\n 'anyOf',\n 'oneOf',\n 'not',\n 'additionalProperties',\n ]\n\n return (\n schemaLocations.some((location) => {\n if (Array.isArray(location)) {\n return location.every((segment, index) => path[index] === segment)\n }\n return path.includes(location)\n }) ||\n path.includes('schema') ||\n path.some((segment) => segment.endsWith('Schema'))\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { OpenAPIV3_1 } from '@scalar/openapi-types'\nimport type { UnknownObject } from '@scalar/types/utils'\n\nimport { traverse } from './traverse'\n\n// Create Sets for faster schema path lookups\nconst SCHEMA_SEGMENTS = new Set([\n 'properties',\n 'items',\n 'allOf',\n 'anyOf',\n 'oneOf',\n 'not',\n 'additionalProperties',\n 'schema',\n])\n\nconst SCHEMA_PATHS = new Set(['components/schemas'])\n\n/** Determine if the current path is within a schema - optimized version */\nexport function isSchemaPath(path: string[]): boolean {\n // Check for schema segments first (most common case)\n if (path.some((segment) => SCHEMA_SEGMENTS.has(segment))) {\n return true\n }\n\n // Check for schema suffix\n if (path.some((segment) => segment.endsWith('Schema'))) {\n return true\n }\n\n // Check for components/schemas path\n if (path.length >= 2 && path[0] === 'components' && path[1] === 'schemas') {\n return true\n }\n\n return false\n}\n\n/**\n * Upgrade from OpenAPI 3.0.x to 3.1.1\n *\n * https://www.openapis.org/blog/2021/02/16/migrating-from-openapi-3-0-to-3-1-0\n */\nexport function upgradeFromThreeToThreeOne(originalContent: UnknownObject) {\n let content = originalContent\n\n // Version check - early return if not 3.0.x\n if (content === null || typeof content.openapi !== 'string' || !content.openapi.startsWith('3.0')) {\n return content\n }\n\n content.openapi = '3.1.1'\n\n // Single traversal that handles all transformations\n content = traverse(content, applyChangesToDocument)\n\n return content as OpenAPIV3_1.Document\n}\n\nconst applyChangesToDocument = (schema: UnknownObject, path: string[]) => {\n // 1. Handle nullable types\n if (schema.type !== 'undefined' && schema.nullable === true) {\n schema.type = [schema.type, 'null']\n delete schema.nullable\n }\n\n // 2. Handle exclusiveMinimum and exclusiveMaximum\n if (schema.exclusiveMinimum === true) {\n schema.exclusiveMinimum = schema.minimum\n delete schema.minimum\n } else if (schema.exclusiveMinimum === false) {\n delete schema.exclusiveMinimum\n }\n\n if (schema.exclusiveMaximum === true) {\n schema.exclusiveMaximum = schema.maximum\n delete schema.maximum\n } else if (schema.exclusiveMaximum === false) {\n delete schema.exclusiveMaximum\n }\n\n // 3. Handle examples\n if (schema.example !== undefined) {\n if (isSchemaPath(path)) {\n schema.examples = [schema.example]\n } else {\n schema.examples = {\n default: {\n value: schema.example,\n },\n }\n }\n delete schema.example\n }\n\n // 4. Handle multipart file uploads\n if (schema.type === 'object' && schema.properties !== undefined) {\n const parentPath = path.slice(0, -1)\n const isMultipart = parentPath.some((segment, index) => {\n return segment === 'content' && path[index + 1] === 'multipart/form-data'\n })\n\n if (isMultipart) {\n for (const value of Object.values(schema.properties)) {\n if (\n typeof value === 'object' &&\n value !== null &&\n 'type' in value &&\n 'format' in value &&\n value.type === 'string' &&\n value.format === 'binary'\n ) {\n ;(value as any).contentMediaType = 'application/octet-stream'\n delete (value as any).format\n }\n }\n }\n }\n\n // 5. Handle binary file uploads\n if (path.includes('content') && path.includes('application/octet-stream')) {\n return {}\n }\n\n if (schema.type === 'string') {\n if (schema.format === 'binary') {\n return {\n type: 'string',\n contentMediaType: 'application/octet-stream',\n }\n }\n\n if (schema.format === 'base64') {\n return {\n type: 'string',\n contentEncoding: 'base64',\n }\n }\n\n if (schema.format === 'byte') {\n const parentPath = path.slice(0, -1)\n const contentMediaType = parentPath.find((_, index) => path[index - 1] === 'content')\n return {\n type: 'string',\n contentEncoding: 'base64',\n contentMediaType,\n }\n }\n }\n\n return schema\n}\n"],
5
+ "mappings": "AAGA,SAAS,gBAAgB;AAGzB,MAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,MAAM,eAAe,oBAAI,IAAI,CAAC,oBAAoB,CAAC;AAG5C,SAAS,aAAa,MAAyB;AAEpD,MAAI,KAAK,KAAK,CAAC,YAAY,gBAAgB,IAAI,OAAO,CAAC,GAAG;AACxD,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,KAAK,CAAC,YAAY,QAAQ,SAAS,QAAQ,CAAC,GAAG;AACtD,WAAO;AAAA,EACT;AAGA,MAAI,KAAK,UAAU,KAAK,KAAK,CAAC,MAAM,gBAAgB,KAAK,CAAC,MAAM,WAAW;AACzE,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAOO,SAAS,2BAA2B,iBAAgC;AACzE,MAAI,UAAU;AAGd,MAAI,YAAY,QAAQ,OAAO,QAAQ,YAAY,YAAY,CAAC,QAAQ,QAAQ,WAAW,KAAK,GAAG;AACjG,WAAO;AAAA,EACT;AAEA,UAAQ,UAAU;AAGlB,YAAU,SAAS,SAAS,sBAAsB;AAElD,SAAO;AACT;AAEA,MAAM,yBAAyB,CAAC,QAAuB,SAAmB;AAExE,MAAI,OAAO,SAAS,eAAe,OAAO,aAAa,MAAM;AAC3D,WAAO,OAAO,CAAC,OAAO,MAAM,MAAM;AAClC,WAAO,OAAO;AAAA,EAChB;AAGA,MAAI,OAAO,qBAAqB,MAAM;AACpC,WAAO,mBAAmB,OAAO;AACjC,WAAO,OAAO;AAAA,EAChB,WAAW,OAAO,qBAAqB,OAAO;AAC5C,WAAO,OAAO;AAAA,EAChB;AAEA,MAAI,OAAO,qBAAqB,MAAM;AACpC,WAAO,mBAAmB,OAAO;AACjC,WAAO,OAAO;AAAA,EAChB,WAAW,OAAO,qBAAqB,OAAO;AAC5C,WAAO,OAAO;AAAA,EAChB;AAGA,MAAI,OAAO,YAAY,QAAW;AAChC,QAAI,aAAa,IAAI,GAAG;AACtB,aAAO,WAAW,CAAC,OAAO,OAAO;AAAA,IACnC,OAAO;AACL,aAAO,WAAW;AAAA,QAChB,SAAS;AAAA,UACP,OAAO,OAAO;AAAA,QAChB;AAAA,MACF;AAAA,IACF;AACA,WAAO,OAAO;AAAA,EAChB;AAGA,MAAI,OAAO,SAAS,YAAY,OAAO,eAAe,QAAW;AAC/D,UAAM,aAAa,KAAK,MAAM,GAAG,EAAE;AACnC,UAAM,cAAc,WAAW,KAAK,CAAC,SAAS,UAAU;AACtD,aAAO,YAAY,aAAa,KAAK,QAAQ,CAAC,MAAM;AAAA,IACtD,CAAC;AAED,QAAI,aAAa;AACf,iBAAW,SAAS,OAAO,OAAO,OAAO,UAAU,GAAG;AACpD,YACE,OAAO,UAAU,YACjB,UAAU,QACV,UAAU,SACV,YAAY,SACZ,MAAM,SAAS,YACf,MAAM,WAAW,UACjB;AACA;AAAC,UAAC,MAAc,mBAAmB;AACnC,iBAAQ,MAAc;AAAA,QACxB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,MAAI,KAAK,SAAS,SAAS,KAAK,KAAK,SAAS,0BAA0B,GAAG;AACzE,WAAO,CAAC;AAAA,EACV;AAEA,MAAI,OAAO,SAAS,UAAU;AAC5B,QAAI,OAAO,WAAW,UAAU;AAC9B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,kBAAkB;AAAA,MACpB;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,UAAU;AAC9B,aAAO;AAAA,QACL,MAAM;AAAA,QACN,iBAAiB;AAAA,MACnB;AAAA,IACF;AAEA,QAAI,OAAO,WAAW,QAAQ;AAC5B,YAAM,aAAa,KAAK,MAAM,GAAG,EAAE;AACnC,YAAM,mBAAmB,WAAW,KAAK,CAAC,GAAG,UAAU,KAAK,QAAQ,CAAC,MAAM,SAAS;AACpF,aAAO;AAAA,QACL,MAAM;AAAA,QACN,iBAAiB;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"upgradeFromTwoToThree.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromTwoToThree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAIxD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,qBAAqB,EAAE,aAAa,0CA+PzE"}
1
+ {"version":3,"file":"upgradeFromTwoToThree.d.ts","sourceRoot":"","sources":["../../src/utils/upgradeFromTwoToThree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAa,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAIxD;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,qBAAqB,EAAE,aAAa,0CAiQzE"}
@@ -25,7 +25,7 @@ function upgradeFromTwoToThree(originalSpecification) {
25
25
  });
26
26
  delete specification.definitions;
27
27
  specification = traverse(specification, (schema) => {
28
- if (schema.$ref?.startsWith("#/definitions/")) {
28
+ if (typeof schema.$ref === "string" && schema.$ref.startsWith("#/definitions/")) {
29
29
  schema.$ref = schema.$ref.replace(/^#\/definitions\//, "#/components/schemas/");
30
30
  }
31
31
  return schema;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/utils/upgradeFromTwoToThree.ts"],
4
- "sourcesContent": ["import type { OpenAPIV2, OpenAPIV3 } from '@scalar/openapi-types'\nimport type { UnknownObject } from '@scalar/types/utils'\n\nimport { traverse } from './traverse'\n\n/**\n * Upgrade Swagger 2.0 to OpenAPI 3.0\n *\n * https://swagger.io/blog/news/whats-new-in-openapi-3-0/\n */\nexport function upgradeFromTwoToThree(originalSpecification: UnknownObject) {\n let specification = originalSpecification\n\n // Version\n if (specification !== null && typeof specification.swagger === 'string' && specification.swagger?.startsWith('2.0')) {\n specification.openapi = '3.0.4'\n delete specification.swagger\n } else {\n // Skip if it\u2019s something else than 3.0.x\n return specification\n }\n\n // Servers\n if (specification.host) {\n const schemes =\n Array.isArray(specification.schemes) && specification.schemes?.length ? specification.schemes : ['http']\n\n specification.servers = schemes.map((scheme: string[]) => ({\n url: `${scheme}://${specification.host}${specification.basePath ?? ''}`,\n }))\n\n delete specification.basePath\n delete specification.schemes\n delete specification.host\n } else if (specification.basePath) {\n specification.servers = [{ url: specification.basePath }]\n delete specification.basePath\n }\n\n // Schemas\n if (specification.definitions) {\n specification.components = Object.assign({}, specification.components, {\n schemas: specification.definitions,\n })\n\n delete specification.definitions\n\n // Rewrite $refs to definitions\n specification = traverse(specification, (schema) => {\n if (schema.$ref?.startsWith('#/definitions/')) {\n schema.$ref = schema.$ref.replace(/^#\\/definitions\\//, '#/components/schemas/')\n }\n\n return schema\n })\n }\n\n specification = traverse(specification, (schema) => {\n if (schema.type === 'file') {\n schema.type = 'string'\n schema.format = 'binary'\n }\n\n return schema\n })\n\n // Paths\n if (typeof specification.paths === 'object') {\n for (const path in specification.paths) {\n if (Object.hasOwn(specification.paths, path)) {\n const pathItem = specification.paths[path]\n\n for (const method in pathItem) {\n if (Object.hasOwn(pathItem, method)) {\n const operationItem = pathItem[method]\n\n // Request bodies\n if (operationItem.parameters) {\n const bodyParameter = structuredClone(\n operationItem.parameters.find((parameter: OpenAPIV3.ParameterObject) => parameter.in === 'body') ?? {},\n )\n\n if (bodyParameter && Object.keys(bodyParameter).length) {\n delete bodyParameter.name\n delete bodyParameter.in\n\n const consumes = specification.consumes ?? operationItem.consumes ?? ['application/json']\n\n if (typeof operationItem.requestBody !== 'object') {\n operationItem.requestBody = {}\n }\n\n if (typeof operationItem.requestBody.content !== 'object') {\n operationItem.requestBody.content = {}\n }\n\n const { schema, ...requestBody } = bodyParameter\n\n operationItem.requestBody = {\n ...operationItem.requestBody,\n ...requestBody,\n }\n\n for (const type of consumes) {\n operationItem.requestBody.content[type] = {\n schema: schema,\n }\n }\n }\n\n // Delete body parameter\n operationItem.parameters = operationItem.parameters.filter(\n (parameter: OpenAPIV2.ParameterObject) => parameter.in !== 'body',\n )\n\n delete operationItem.consumes\n\n // formData parameters\n const formDataParameters = operationItem.parameters.filter(\n (parameter: OpenAPIV2.ParameterObject) => parameter.in === 'formData',\n )\n\n if (formDataParameters.length > 0) {\n if (typeof operationItem.requestBody !== 'object') {\n operationItem.requestBody = {}\n }\n\n if (typeof operationItem.requestBody.content !== 'object') {\n operationItem.requestBody.content = {}\n }\n\n operationItem.requestBody.content['application/x-www-form-urlencoded'] = {\n schema: {\n type: 'object',\n properties: {},\n required: [], // Initialize required array\n },\n }\n\n for (const param of formDataParameters) {\n operationItem.requestBody.content['application/x-www-form-urlencoded'].schema.properties[param.name] =\n {\n type: param.type,\n description: param.description,\n }\n\n // Add to required array if param is required\n if (param.required) {\n operationItem.requestBody.content['application/x-www-form-urlencoded'].schema.required.push(\n param.name,\n )\n }\n }\n\n // Remove formData parameters from the parameters array\n operationItem.parameters = operationItem.parameters.filter(\n (parameter: OpenAPIV2.ParameterObject) => parameter.in !== 'formData',\n )\n }\n\n operationItem.parameters = operationItem.parameters.map((parameter) =>\n transformParameterObject(parameter),\n )\n }\n\n // Responses\n if (operationItem.responses) {\n for (const response in operationItem.responses) {\n if (Object.hasOwn(operationItem.responses, response)) {\n const responseItem = operationItem.responses[response]\n\n if (responseItem.headers) {\n responseItem.headers = Object.entries(responseItem.headers).reduce((acc, [name, header]) => {\n return {\n [name]: transformParameterObject(header),\n ...acc,\n }\n }, {})\n }\n if (responseItem.schema) {\n const produces = specification.produces ?? operationItem.produces ?? ['application/json']\n\n if (typeof responseItem.content !== 'object') {\n responseItem.content = {}\n }\n\n for (const type of produces) {\n responseItem.content[type] = {\n schema: responseItem.schema,\n }\n }\n\n delete responseItem.schema\n }\n }\n }\n }\n\n delete operationItem.produces\n\n // Delete empty parameters\n if (operationItem.parameters?.length === 0) {\n delete operationItem.parameters\n }\n }\n }\n }\n }\n }\n\n // Upgrade securityDefinitions\n if (specification.securityDefinitions) {\n if (typeof specification.components !== 'object') {\n specification.components = {}\n }\n\n // Assert that components is of type OpenAPIV3.ComponentsObject\n specification.components = specification.components as OpenAPIV3.ComponentsObject\n\n Object.assign(specification.components, { securitySchemes: {} })\n\n for (const [key, securityScheme] of Object.entries(specification.securityDefinitions)) {\n if (typeof securityScheme === 'object') {\n if ('type' in securityScheme && securityScheme.type === 'oauth2') {\n const { flow, authorizationUrl, tokenUrl, scopes } = securityScheme as {\n type: 'oauth2'\n flow?: string\n authorizationUrl?: string\n tokenUrl?: string\n scopes?: Record<string, string>\n }\n\n // Assert that securitySchemes is of type OpenAPIV3.SecuritySchemeObject\n Object.assign((specification.components as OpenAPIV3.ComponentsObject).securitySchemes, {\n [key]: {\n type: 'oauth2',\n flows: {\n [flow as string]: Object.assign(\n {},\n authorizationUrl && { authorizationUrl },\n tokenUrl && { tokenUrl },\n scopes && { scopes },\n ),\n },\n },\n })\n } else if ('type' in securityScheme && securityScheme.type === 'basic') {\n Object.assign((specification.components as OpenAPIV3.ComponentsObject).securitySchemes, {\n [key]: {\n type: 'http',\n scheme: 'basic',\n },\n })\n } else {\n Object.assign((specification.components as OpenAPIV3.ComponentsObject).securitySchemes, {\n [key]: securityScheme,\n })\n }\n }\n }\n\n delete specification.securityDefinitions\n }\n\n return specification as OpenAPIV3.Document\n}\n\nfunction transformItemsObject<T extends Record<PropertyKey, unknown>>(obj: T): OpenAPIV3.SchemaObject {\n const schemaProperties = [\n 'type',\n 'format',\n 'items',\n 'maximum',\n 'exclusiveMaximum',\n 'minimum',\n 'exclusiveMinimum',\n 'maxLength',\n 'minLength',\n 'pattern',\n 'maxItems',\n 'minItems',\n 'uniqueItems',\n 'enum',\n 'multipleOf',\n ]\n\n return schemaProperties.reduce((acc, property) => {\n if (Object.hasOwn(obj, property)) {\n acc[property] = obj[property]\n delete obj[property]\n }\n\n return acc\n }, {} as OpenAPIV3.SchemaObject)\n}\n\nfunction transformParameterObject(parameter: OpenAPIV2.ParameterObject): OpenAPIV3.ParameterObject {\n delete parameter.collectionFormat\n delete parameter.default\n\n return {\n schema: transformItemsObject(parameter),\n ...parameter,\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { OpenAPIV2, OpenAPIV3 } from '@scalar/openapi-types'\nimport type { UnknownObject } from '@scalar/types/utils'\n\nimport { traverse } from './traverse'\n\n/**\n * Upgrade Swagger 2.0 to OpenAPI 3.0\n *\n * https://swagger.io/blog/news/whats-new-in-openapi-3-0/\n */\nexport function upgradeFromTwoToThree(originalSpecification: UnknownObject) {\n let specification = originalSpecification\n\n // Version\n if (specification !== null && typeof specification.swagger === 'string' && specification.swagger?.startsWith('2.0')) {\n specification.openapi = '3.0.4'\n delete specification.swagger\n } else {\n // Skip if it\u2019s something else than 3.0.x\n return specification\n }\n\n // Servers\n if (specification.host) {\n const schemes =\n Array.isArray(specification.schemes) && specification.schemes?.length ? specification.schemes : ['http']\n\n specification.servers = schemes.map((scheme: string[]) => ({\n url: `${scheme}://${specification.host}${specification.basePath ?? ''}`,\n }))\n\n delete specification.basePath\n delete specification.schemes\n delete specification.host\n } else if (specification.basePath) {\n specification.servers = [{ url: specification.basePath }]\n delete specification.basePath\n }\n\n // Schemas\n if (specification.definitions) {\n specification.components = Object.assign({}, specification.components, {\n schemas: specification.definitions,\n })\n\n delete specification.definitions\n\n // Rewrite $refs to definitions\n specification = traverse(specification, (schema) => {\n // Rewrite $refs to components\n if (typeof schema.$ref === 'string' && schema.$ref.startsWith('#/definitions/')) {\n schema.$ref = schema.$ref.replace(/^#\\/definitions\\//, '#/components/schemas/')\n }\n\n return schema\n })\n }\n\n // Transform file type to string with binary format\n specification = traverse(specification, (schema) => {\n if (schema.type === 'file') {\n schema.type = 'string'\n schema.format = 'binary'\n }\n\n return schema\n })\n\n // Paths\n if (typeof specification.paths === 'object') {\n for (const path in specification.paths) {\n if (Object.hasOwn(specification.paths, path)) {\n const pathItem = specification.paths[path]\n\n for (const method in pathItem) {\n if (Object.hasOwn(pathItem, method)) {\n const operationItem = pathItem[method]\n\n // Request bodies\n if (operationItem.parameters) {\n const bodyParameter = structuredClone(\n operationItem.parameters.find((parameter: OpenAPIV3.ParameterObject) => parameter.in === 'body') ?? {},\n )\n\n if (bodyParameter && Object.keys(bodyParameter).length) {\n delete bodyParameter.name\n delete bodyParameter.in\n\n const consumes = specification.consumes ?? operationItem.consumes ?? ['application/json']\n\n if (typeof operationItem.requestBody !== 'object') {\n operationItem.requestBody = {}\n }\n\n if (typeof operationItem.requestBody.content !== 'object') {\n operationItem.requestBody.content = {}\n }\n\n const { schema, ...requestBody } = bodyParameter\n\n operationItem.requestBody = {\n ...operationItem.requestBody,\n ...requestBody,\n }\n\n for (const type of consumes) {\n operationItem.requestBody.content[type] = {\n schema: schema,\n }\n }\n }\n\n // Delete body parameter\n operationItem.parameters = operationItem.parameters.filter(\n (parameter: OpenAPIV2.ParameterObject) => parameter.in !== 'body',\n )\n\n delete operationItem.consumes\n\n // formData parameters\n const formDataParameters = operationItem.parameters.filter(\n (parameter: OpenAPIV2.ParameterObject) => parameter.in === 'formData',\n )\n\n if (formDataParameters.length > 0) {\n if (typeof operationItem.requestBody !== 'object') {\n operationItem.requestBody = {}\n }\n\n if (typeof operationItem.requestBody.content !== 'object') {\n operationItem.requestBody.content = {}\n }\n\n operationItem.requestBody.content['application/x-www-form-urlencoded'] = {\n schema: {\n type: 'object',\n properties: {},\n required: [], // Initialize required array\n },\n }\n\n for (const param of formDataParameters) {\n operationItem.requestBody.content['application/x-www-form-urlencoded'].schema.properties[param.name] =\n {\n type: param.type,\n description: param.description,\n }\n\n // Add to required array if param is required\n if (param.required) {\n operationItem.requestBody.content['application/x-www-form-urlencoded'].schema.required.push(\n param.name,\n )\n }\n }\n\n // Remove formData parameters from the parameters array\n operationItem.parameters = operationItem.parameters.filter(\n (parameter: OpenAPIV2.ParameterObject) => parameter.in !== 'formData',\n )\n }\n\n operationItem.parameters = operationItem.parameters.map((parameter) =>\n transformParameterObject(parameter),\n )\n }\n\n // Responses\n if (operationItem.responses) {\n for (const response in operationItem.responses) {\n if (Object.hasOwn(operationItem.responses, response)) {\n const responseItem = operationItem.responses[response]\n\n if (responseItem.headers) {\n responseItem.headers = Object.entries(responseItem.headers).reduce((acc, [name, header]) => {\n return {\n [name]: transformParameterObject(header),\n ...acc,\n }\n }, {})\n }\n if (responseItem.schema) {\n const produces = specification.produces ?? operationItem.produces ?? ['application/json']\n\n if (typeof responseItem.content !== 'object') {\n responseItem.content = {}\n }\n\n for (const type of produces) {\n responseItem.content[type] = {\n schema: responseItem.schema,\n }\n }\n\n delete responseItem.schema\n }\n }\n }\n }\n\n delete operationItem.produces\n\n // Delete empty parameters\n if (operationItem.parameters?.length === 0) {\n delete operationItem.parameters\n }\n }\n }\n }\n }\n }\n\n // Upgrade securityDefinitions\n if (specification.securityDefinitions) {\n if (typeof specification.components !== 'object') {\n specification.components = {}\n }\n\n // Assert that components is of type OpenAPIV3.ComponentsObject\n specification.components = specification.components as OpenAPIV3.ComponentsObject\n\n Object.assign(specification.components, { securitySchemes: {} })\n\n for (const [key, securityScheme] of Object.entries(specification.securityDefinitions)) {\n if (typeof securityScheme === 'object') {\n if ('type' in securityScheme && securityScheme.type === 'oauth2') {\n const { flow, authorizationUrl, tokenUrl, scopes } = securityScheme as {\n type: 'oauth2'\n flow?: string\n authorizationUrl?: string\n tokenUrl?: string\n scopes?: Record<string, string>\n }\n\n // Assert that securitySchemes is of type OpenAPIV3.SecuritySchemeObject\n Object.assign((specification.components as OpenAPIV3.ComponentsObject).securitySchemes, {\n [key]: {\n type: 'oauth2',\n flows: {\n [flow as string]: Object.assign(\n {},\n authorizationUrl && { authorizationUrl },\n tokenUrl && { tokenUrl },\n scopes && { scopes },\n ),\n },\n },\n })\n } else if ('type' in securityScheme && securityScheme.type === 'basic') {\n Object.assign((specification.components as OpenAPIV3.ComponentsObject).securitySchemes, {\n [key]: {\n type: 'http',\n scheme: 'basic',\n },\n })\n } else {\n Object.assign((specification.components as OpenAPIV3.ComponentsObject).securitySchemes, {\n [key]: securityScheme,\n })\n }\n }\n }\n\n delete specification.securityDefinitions\n }\n\n return specification as OpenAPIV3.Document\n}\n\nfunction transformItemsObject<T extends Record<PropertyKey, unknown>>(obj: T): OpenAPIV3.SchemaObject {\n const schemaProperties = [\n 'type',\n 'format',\n 'items',\n 'maximum',\n 'exclusiveMaximum',\n 'minimum',\n 'exclusiveMinimum',\n 'maxLength',\n 'minLength',\n 'pattern',\n 'maxItems',\n 'minItems',\n 'uniqueItems',\n 'enum',\n 'multipleOf',\n ]\n\n return schemaProperties.reduce((acc, property) => {\n if (Object.hasOwn(obj, property)) {\n acc[property] = obj[property]\n delete obj[property]\n }\n\n return acc\n }, {} as OpenAPIV3.SchemaObject)\n}\n\nfunction transformParameterObject(parameter: OpenAPIV2.ParameterObject): OpenAPIV3.ParameterObject {\n delete parameter.collectionFormat\n delete parameter.default\n\n return {\n schema: transformItemsObject(parameter),\n ...parameter,\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -17,9 +17,9 @@
17
17
  "parser",
18
18
  "typescript"
19
19
  ],
20
- "version": "0.10.17",
20
+ "version": "0.11.0",
21
21
  "engines": {
22
- "node": ">=18"
22
+ "node": ">=20"
23
23
  },
24
24
  "type": "module",
25
25
  "main": "./dist/index.js",
@@ -63,9 +63,9 @@
63
63
  "json-to-ast": "^2.1.0",
64
64
  "just-diff": "^6.0.2",
65
65
  "tinybench": "^2.8.0",
66
- "@scalar/openapi-types": "0.2.2",
67
- "@scalar/types": "0.1.14",
68
- "@scalar/build-tooling": "0.1.19"
66
+ "@scalar/build-tooling": "0.2.0",
67
+ "@scalar/types": "0.2.1",
68
+ "@scalar/openapi-types": "0.3.1"
69
69
  },
70
70
  "scripts": {
71
71
  "build": "scalar-build-esbuild",