mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-16 23:55:20 +00:00
Upgrade @scalar/openapi-parser (#3442)
This commit is contained in:
@@ -0,0 +1,5 @@
|
|||||||
|
---
|
||||||
|
"@gitbook/openapi-parser": patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Upgrade Scalar parser
|
||||||
@@ -169,7 +169,7 @@
|
|||||||
"name": "@gitbook/openapi-parser",
|
"name": "@gitbook/openapi-parser",
|
||||||
"version": "2.1.4",
|
"version": "2.1.4",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@scalar/openapi-parser": "^0.10.10",
|
"@scalar/openapi-parser": "^0.18.0",
|
||||||
"@scalar/openapi-types": "^0.1.9",
|
"@scalar/openapi-types": "^0.1.9",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1100,7 +1100,7 @@
|
|||||||
|
|
||||||
"@scalar/object-utils": ["@scalar/object-utils@1.1.13", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1" } }, "sha512-311eTykIXgOtjCs4VTELj9UMT97jHTWc5qkGNoIzZ5nxjCcvOVe7kDQobIkE8dGT+ybOgHz5qly02Eu7nVHeZQ=="],
|
"@scalar/object-utils": ["@scalar/object-utils@1.1.13", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1" } }, "sha512-311eTykIXgOtjCs4VTELj9UMT97jHTWc5qkGNoIzZ5nxjCcvOVe7kDQobIkE8dGT+ybOgHz5qly02Eu7nVHeZQ=="],
|
||||||
|
|
||||||
"@scalar/openapi-parser": ["@scalar/openapi-parser@0.10.14", "", { "dependencies": { "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "^2.4.5" } }, "sha512-VXr979NMx6wZ+kpFKor2eyCJZOjyMwcBRc6c4Gc92ZMOC7ZNYqjwbw+Ubh2ELJyP5cWAjOFSrNwtylema0pw5w=="],
|
"@scalar/openapi-parser": ["@scalar/openapi-parser@0.18.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "^2.4.5" } }, "sha512-qAWEfJR5f/LwSFULFeSkD56LHgU9ovyj+e1uqy9XaW9Hb9P0ewIGKi+Gd4wTyxfFkdPLXTFYXApjviP6jV+new=="],
|
||||||
|
|
||||||
"@scalar/openapi-types": ["@scalar/openapi-types@0.1.9", "", {}, "sha512-HQQudOSQBU7ewzfnBW9LhDmBE2XOJgSfwrh5PlUB7zJup/kaRkBGNgV2wMjNz9Af/uztiU/xNrO179FysmUT+g=="],
|
"@scalar/openapi-types": ["@scalar/openapi-types@0.1.9", "", {}, "sha512-HQQudOSQBU7ewzfnBW9LhDmBE2XOJgSfwrh5PlUB7zJup/kaRkBGNgV2wMjNz9Af/uztiU/xNrO179FysmUT+g=="],
|
||||||
|
|
||||||
@@ -3768,8 +3768,6 @@
|
|||||||
|
|
||||||
"@scalar/api-client/@scalar/object-utils": ["@scalar/object-utils@1.2.1", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1", "type-fest": "^4.20.0" } }, "sha512-2P/0In6XSrV1Ye8yU3LyOWJKWkzXpxf0thHmTfJriqGBZz41s06td2KKqoqHSEEi+FAsl3O1ngmOOzLM3QUkkw=="],
|
"@scalar/api-client/@scalar/object-utils": ["@scalar/object-utils@1.2.1", "", { "dependencies": { "flatted": "^3.3.1", "just-clone": "^6.2.0", "ts-deepmerge": "^7.0.1", "type-fest": "^4.20.0" } }, "sha512-2P/0In6XSrV1Ye8yU3LyOWJKWkzXpxf0thHmTfJriqGBZz41s06td2KKqoqHSEEi+FAsl3O1ngmOOzLM3QUkkw=="],
|
||||||
|
|
||||||
"@scalar/api-client/@scalar/openapi-parser": ["@scalar/openapi-parser@0.18.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "^2.4.5" } }, "sha512-qAWEfJR5f/LwSFULFeSkD56LHgU9ovyj+e1uqy9XaW9Hb9P0ewIGKi+Gd4wTyxfFkdPLXTFYXApjviP6jV+new=="],
|
|
||||||
|
|
||||||
"@scalar/api-client/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
"@scalar/api-client/@scalar/openapi-types": ["@scalar/openapi-types@0.3.3", "", { "dependencies": { "zod": "3.24.1" } }, "sha512-mr3OvbCyvuzSDgv9gR9D3pJAsl82BRNBp1P8ldgRgKF4Wiswfa7nQeKibpX0kHSGXLgiyvxWJULUFwgdWMXNNA=="],
|
||||||
|
|
||||||
"@scalar/api-client/@scalar/themes": ["@scalar/themes@0.13.4", "", { "dependencies": { "@scalar/types": "0.2.3", "nanoid": "^5.1.5" } }, "sha512-PMiSqX+MZF29u32ogEjTVA5c/LBd5cE/QPF7lK0EJeemXRy2r/nWbvrXtqD9Y7Sw54g1caVNjK8yJcCYJdB6hw=="],
|
"@scalar/api-client/@scalar/themes": ["@scalar/themes@0.13.4", "", { "dependencies": { "@scalar/types": "0.2.3", "nanoid": "^5.1.5" } }, "sha512-PMiSqX+MZF29u32ogEjTVA5c/LBd5cE/QPF7lK0EJeemXRy2r/nWbvrXtqD9Y7Sw54g1caVNjK8yJcCYJdB6hw=="],
|
||||||
@@ -3782,8 +3780,6 @@
|
|||||||
|
|
||||||
"@scalar/components/@scalar/themes": ["@scalar/themes@0.13.4", "", { "dependencies": { "@scalar/types": "0.2.3", "nanoid": "^5.1.5" } }, "sha512-PMiSqX+MZF29u32ogEjTVA5c/LBd5cE/QPF7lK0EJeemXRy2r/nWbvrXtqD9Y7Sw54g1caVNjK8yJcCYJdB6hw=="],
|
"@scalar/components/@scalar/themes": ["@scalar/themes@0.13.4", "", { "dependencies": { "@scalar/types": "0.2.3", "nanoid": "^5.1.5" } }, "sha512-PMiSqX+MZF29u32ogEjTVA5c/LBd5cE/QPF7lK0EJeemXRy2r/nWbvrXtqD9Y7Sw54g1caVNjK8yJcCYJdB6hw=="],
|
||||||
|
|
||||||
"@scalar/import/@scalar/openapi-parser": ["@scalar/openapi-parser@0.18.0", "", { "dependencies": { "ajv": "^8.17.1", "ajv-draft-04": "^1.0.0", "ajv-formats": "^3.0.1", "jsonpointer": "^5.0.1", "leven": "^4.0.0", "yaml": "^2.4.5" } }, "sha512-qAWEfJR5f/LwSFULFeSkD56LHgU9ovyj+e1uqy9XaW9Hb9P0ewIGKi+Gd4wTyxfFkdPLXTFYXApjviP6jV+new=="],
|
|
||||||
|
|
||||||
"@scalar/oas-utils/@scalar/openapi-types": ["@scalar/openapi-types@0.2.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-waiKk12cRCqyUCWTOX0K1WEVX46+hVUK+zRPzAahDJ7G0TApvbNkuy5wx7aoUyEk++HHde0XuQnshXnt8jsddA=="],
|
"@scalar/oas-utils/@scalar/openapi-types": ["@scalar/openapi-types@0.2.0", "", { "dependencies": { "zod": "^3.23.8" } }, "sha512-waiKk12cRCqyUCWTOX0K1WEVX46+hVUK+zRPzAahDJ7G0TApvbNkuy5wx7aoUyEk++HHde0XuQnshXnt8jsddA=="],
|
||||||
|
|
||||||
"@scalar/oas-utils/@scalar/types": ["@scalar/types@0.1.7", "", { "dependencies": { "@scalar/openapi-types": "0.2.0", "@unhead/schema": "^1.11.11", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "zod": "^3.23.8" } }, "sha512-irIDYzTQG2KLvFbuTI8k2Pz/R4JR+zUUSykVTbEMatkzMmVFnn1VzNSMlODbadycwZunbnL2tA27AXed9URVjw=="],
|
"@scalar/oas-utils/@scalar/types": ["@scalar/types@0.1.7", "", { "dependencies": { "@scalar/openapi-types": "0.2.0", "@unhead/schema": "^1.11.11", "nanoid": "^5.1.5", "type-fest": "^4.20.0", "zod": "^3.23.8" } }, "sha512-irIDYzTQG2KLvFbuTI8k2Pz/R4JR+zUUSykVTbEMatkzMmVFnn1VzNSMlODbadycwZunbnL2tA27AXed9URVjw=="],
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
"version": "2.1.4",
|
"version": "2.1.4",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@scalar/openapi-parser": "^0.10.10",
|
"@scalar/openapi-parser": "^0.18.0",
|
||||||
"@scalar/openapi-types": "^0.1.9"
|
"@scalar/openapi-types": "^0.1.9"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
@@ -39,11 +39,8 @@ describe('#createFileSystem', () => {
|
|||||||
value: url,
|
value: url,
|
||||||
rootURL: url,
|
rootURL: url,
|
||||||
});
|
});
|
||||||
expect(filesystem).toHaveLength(4);
|
expect(filesystem).toHaveLength(1);
|
||||||
expect(filesystem[0]?.isEntrypoint).toBe(true);
|
expect(filesystem[0]?.isEntrypoint).toBe(true);
|
||||||
expect(filesystem[1]?.isEntrypoint).toBe(false);
|
expect(filesystem[0]?.filename).toBe('openapi.json');
|
||||||
expect(filesystem[1]?.filename).toBe('user.yaml');
|
|
||||||
expect(filesystem[2]?.filename).toBe('../tag.yaml');
|
|
||||||
expect(filesystem[3]?.filename).toBe('http://localhost:3020/root/pet.yaml');
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
import { load } from '@scalar/openapi-parser';
|
import { bundle } from '@scalar/openapi-parser';
|
||||||
|
import { parseJson, parseYaml } from '@scalar/openapi-parser/plugins-browser';
|
||||||
import type { ParseOpenAPIInput } from './parse';
|
import type { ParseOpenAPIInput } from './parse';
|
||||||
|
import { fetchURL } from './scalar-plugins/fetchURL';
|
||||||
import { fetchURLs } from './scalar-plugins/fetchURLs';
|
import { fetchURLs } from './scalar-plugins/fetchURLs';
|
||||||
import type { Filesystem } from './types';
|
import type { Filesystem } from './types';
|
||||||
|
|
||||||
@@ -12,9 +14,24 @@ export async function createFileSystem(
|
|||||||
): Promise<Filesystem> {
|
): Promise<Filesystem> {
|
||||||
const { value, rootURL, options } = input;
|
const { value, rootURL, options } = input;
|
||||||
|
|
||||||
const { filesystem } = await load(value, {
|
const result = await bundle(value, {
|
||||||
plugins: [fetchURLs({ rootURL }), ...(options?.plugins || [])],
|
treeShake: false,
|
||||||
|
plugins: [
|
||||||
|
fetchURL(),
|
||||||
|
parseYaml(),
|
||||||
|
parseJson(),
|
||||||
|
fetchURLs({ rootURL }),
|
||||||
|
...(options?.plugins || []),
|
||||||
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
return filesystem;
|
return [
|
||||||
|
{
|
||||||
|
dir: '.',
|
||||||
|
isEntrypoint: true,
|
||||||
|
references: [],
|
||||||
|
filename: 'openapi.json',
|
||||||
|
specification: result,
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import type { AnyApiDefinitionFormat, LoadPlugin } from '@scalar/openapi-parser';
|
import type { AnyObject, bundle } from '@scalar/openapi-parser';
|
||||||
import { OpenAPIParseError } from './error';
|
import { OpenAPIParseError } from './error';
|
||||||
import { convertOpenAPIV2ToOpenAPIV3 } from './v2';
|
import { convertOpenAPIV2ToOpenAPIV3 } from './v2';
|
||||||
import { parseOpenAPIV3 } from './v3';
|
import { parseOpenAPIV3 } from './v3';
|
||||||
|
|
||||||
|
export type ParsePlugin = Parameters<typeof bundle>[1]['plugins'][number];
|
||||||
|
|
||||||
export interface ParseOpenAPIInput {
|
export interface ParseOpenAPIInput {
|
||||||
/**
|
/**
|
||||||
* The API definition to parse.
|
* The API definition to parse.
|
||||||
*/
|
*/
|
||||||
value: AnyApiDefinitionFormat;
|
value: string | AnyObject;
|
||||||
/**
|
/**
|
||||||
* The root URL of the specified OpenAPI document.
|
* The root URL of the specified OpenAPI document.
|
||||||
*/
|
*/
|
||||||
@@ -20,7 +22,7 @@ export interface ParseOpenAPIInput {
|
|||||||
* Options for the parser.
|
* Options for the parser.
|
||||||
*/
|
*/
|
||||||
options?: {
|
options?: {
|
||||||
plugins?: LoadPlugin[];
|
plugins?: ParsePlugin[];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { normalize } from '@scalar/openapi-parser';
|
||||||
|
import type { ParsePlugin } from '../parse';
|
||||||
|
|
||||||
|
export const fetchUrlsDefaultConfiguration = {
|
||||||
|
limit: 40,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const fetchURL = (): ParsePlugin => ({
|
||||||
|
validate(value) {
|
||||||
|
return URL.canParse(value);
|
||||||
|
},
|
||||||
|
async exec(value) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(value);
|
||||||
|
if (!response.ok) {
|
||||||
|
return { ok: false };
|
||||||
|
}
|
||||||
|
const text = await response.text();
|
||||||
|
return {
|
||||||
|
ok: true,
|
||||||
|
data: normalize(text),
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return { ok: false };
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
import { type LoadPlugin, normalize } from '@scalar/openapi-parser';
|
import { normalize } from '@scalar/openapi-parser';
|
||||||
|
import type { ParsePlugin } from '../parse';
|
||||||
|
|
||||||
export const fetchUrlsDefaultConfiguration = {
|
export const fetchUrlsDefaultConfiguration = {
|
||||||
limit: 40,
|
limit: 40,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchURLs: (customConfiguration: {
|
export const fetchURLs = (customConfiguration: {
|
||||||
/**
|
/**
|
||||||
* Root URL to resolve relative URLs.
|
* Root URL to resolve relative URLs.
|
||||||
*/
|
*/
|
||||||
@@ -14,7 +15,7 @@ export const fetchURLs: (customConfiguration: {
|
|||||||
* Limit the number of requests. Set to `false` to disable the limit.
|
* Limit the number of requests. Set to `false` to disable the limit.
|
||||||
*/
|
*/
|
||||||
limit?: number | false;
|
limit?: number | false;
|
||||||
}) => LoadPlugin = (customConfiguration) => {
|
}): ParsePlugin => {
|
||||||
// State
|
// State
|
||||||
let numberOfRequests = 0;
|
let numberOfRequests = 0;
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ export const fetchURLs: (customConfiguration: {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
check(value?: any) {
|
validate(value) {
|
||||||
// Not a string
|
// Not a string
|
||||||
if (typeof value !== 'string') {
|
if (typeof value !== 'string') {
|
||||||
return false;
|
return false;
|
||||||
@@ -42,10 +43,10 @@ export const fetchURLs: (customConfiguration: {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
async get(value?: any) {
|
async exec(value) {
|
||||||
// Limit the number of requests
|
// Limit the number of requests
|
||||||
if (configuration?.limit !== false && numberOfRequests >= configuration?.limit) {
|
if (configuration?.limit !== false && numberOfRequests >= configuration?.limit) {
|
||||||
return undefined;
|
return { ok: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -53,14 +54,17 @@ export const fetchURLs: (customConfiguration: {
|
|||||||
const url = getReferenceUrl({ value, rootURL: configuration.rootURL });
|
const url = getReferenceUrl({ value, rootURL: configuration.rootURL });
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
return undefined;
|
return { ok: false };
|
||||||
}
|
}
|
||||||
const text = await response.text();
|
const text = await response.text();
|
||||||
// Try to normalize the text to be sure it's a valid JSON or YAML.
|
// Try to normalize the text to be sure it's a valid JSON or YAML.
|
||||||
await normalize(text);
|
await normalize(text);
|
||||||
return text;
|
return {
|
||||||
} catch (_error: any) {
|
ok: true,
|
||||||
return undefined;
|
data: text,
|
||||||
|
};
|
||||||
|
} catch {
|
||||||
|
return { ok: false };
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user