mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-22 02:23:30 +00:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f2766f3fdc |
@@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
'@gitbook/openapi-parser': patch
|
|
||||||
'gitbook': patch
|
|
||||||
---
|
|
||||||
|
|
||||||
Implement a trusted mode to speed up OpenAPI spec validation
|
|
||||||
@@ -82,13 +82,7 @@ const fetchFilesystem = cache({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const text = await response.text();
|
const text = await response.text();
|
||||||
const filesystem = await parseOpenAPI({
|
const filesystem = await parseOpenAPI({ value: text, rootURL: url });
|
||||||
value: text,
|
|
||||||
rootURL: url,
|
|
||||||
// If we fetch the OpenAPI specification
|
|
||||||
// it's the legacy system, it means the spec can be trusted here.
|
|
||||||
trust: true,
|
|
||||||
});
|
|
||||||
const richFilesystem = await enrichFilesystem(filesystem);
|
const richFilesystem = await enrichFilesystem(filesystem);
|
||||||
return {
|
return {
|
||||||
// Cache for 4 hours
|
// Cache for 4 hours
|
||||||
|
|||||||
@@ -3,7 +3,12 @@ import { OpenAPIParseError } from './error';
|
|||||||
import { convertOpenAPIV2ToOpenAPIV3 } from './v2';
|
import { convertOpenAPIV2ToOpenAPIV3 } from './v2';
|
||||||
import { parseOpenAPIV3 } from './v3';
|
import { parseOpenAPIV3 } from './v3';
|
||||||
|
|
||||||
export interface ParseOpenAPIInput {
|
/**
|
||||||
|
* Parse a raw string into an OpenAPI document.
|
||||||
|
* It will also convert Swagger 2.0 to OpenAPI 3.0.
|
||||||
|
* It can throw an `OpenAPIParseError` if the document is invalid.
|
||||||
|
*/
|
||||||
|
export async function parseOpenAPI(input: {
|
||||||
/**
|
/**
|
||||||
* The API definition to parse.
|
* The API definition to parse.
|
||||||
*/
|
*/
|
||||||
@@ -12,18 +17,7 @@ export interface ParseOpenAPIInput {
|
|||||||
* The root URL of the specified OpenAPI document.
|
* The root URL of the specified OpenAPI document.
|
||||||
*/
|
*/
|
||||||
rootURL: string | null;
|
rootURL: string | null;
|
||||||
/**
|
}) {
|
||||||
* Trust the input. This will skip advanced validation.
|
|
||||||
*/
|
|
||||||
trust?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a raw string into an OpenAPI document.
|
|
||||||
* It will also convert Swagger 2.0 to OpenAPI 3.0.
|
|
||||||
* It can throw an `OpenAPIParseError` if the document is invalid.
|
|
||||||
*/
|
|
||||||
export async function parseOpenAPI(input: ParseOpenAPIInput) {
|
|
||||||
try {
|
try {
|
||||||
return await parseOpenAPIV3(input);
|
return await parseOpenAPIV3(input);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export const fetchURLs: (customConfiguration: {
|
|||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
async get(value?: any) {
|
async get(value?: any) {
|
||||||
// Limit the number of requests
|
// Limit ht enumber of requests
|
||||||
if (configuration?.limit !== false && numberOfRequests >= configuration?.limit) {
|
if (configuration?.limit !== false && numberOfRequests >= configuration?.limit) {
|
||||||
console.warn(
|
console.warn(
|
||||||
`[fetchUrls] Maximum number of requests reeached (${configuration?.limit}), skipping request`,
|
`[fetchUrls] Maximum number of requests reeached (${configuration?.limit}), skipping request`,
|
||||||
|
|||||||
@@ -1,15 +1,22 @@
|
|||||||
import { OpenAPIParseError } from './error';
|
import { OpenAPIParseError } from './error';
|
||||||
import { parseOpenAPIV3 } from './v3';
|
import { parseOpenAPIV3 } from './v3';
|
||||||
|
import type { AnyApiDefinitionFormat } from '@scalar/openapi-parser';
|
||||||
import type { Filesystem, OpenAPIV3xDocument } from './types';
|
import type { Filesystem, OpenAPIV3xDocument } from './types';
|
||||||
import type { ParseOpenAPIInput } from './parse';
|
|
||||||
import { upgrade } from '@scalar/openapi-parser';
|
import { upgrade } from '@scalar/openapi-parser';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a Swagger 2.0 schema to an OpenAPI 3.0 schema.
|
* Convert a Swagger 2.0 schema to an OpenAPI 3.0 schema.
|
||||||
*/
|
*/
|
||||||
export async function convertOpenAPIV2ToOpenAPIV3(
|
export async function convertOpenAPIV2ToOpenAPIV3(input: {
|
||||||
input: ParseOpenAPIInput,
|
/**
|
||||||
): Promise<Filesystem<OpenAPIV3xDocument>> {
|
* The API definition to parse.
|
||||||
|
*/
|
||||||
|
value: AnyApiDefinitionFormat;
|
||||||
|
/**
|
||||||
|
* The root URL of the specified OpenAPI document.
|
||||||
|
*/
|
||||||
|
rootURL: string | null;
|
||||||
|
}): Promise<Filesystem<OpenAPIV3xDocument>> {
|
||||||
const { value, rootURL } = input;
|
const { value, rootURL } = input;
|
||||||
|
|
||||||
const upgradeResult = (() => {
|
const upgradeResult = (() => {
|
||||||
|
|||||||
@@ -1,33 +1,23 @@
|
|||||||
import { validate } from '@scalar/openapi-parser';
|
import { type AnyApiDefinitionFormat, validate } from '@scalar/openapi-parser';
|
||||||
import { OpenAPIParseError } from './error';
|
import { OpenAPIParseError } from './error';
|
||||||
import { createFileSystem } from './filesystem';
|
import { createFileSystem } from './filesystem';
|
||||||
import type { Filesystem, OpenAPIV3xDocument } from './types';
|
import type { Filesystem, OpenAPIV3xDocument } from './types';
|
||||||
import type { ParseOpenAPIInput } from './parse';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse a raw string into an OpenAPI document.
|
* Parse a raw string into an OpenAPI document.
|
||||||
* It will also convert Swagger 2.0 to OpenAPI 3.0.
|
* It will also convert Swagger 2.0 to OpenAPI 3.0.
|
||||||
* It can throw an `OpenAPIFetchError` if the document is invalid.
|
* It can throw an `OpenAPIFetchError` if the document is invalid.
|
||||||
*/
|
*/
|
||||||
export async function parseOpenAPIV3(
|
export async function parseOpenAPIV3(input: {
|
||||||
input: ParseOpenAPIInput,
|
/**
|
||||||
): Promise<Filesystem<OpenAPIV3xDocument>> {
|
* The API definition to parse.
|
||||||
const { value, rootURL, trust } = input;
|
*/
|
||||||
const specification = trust
|
value: AnyApiDefinitionFormat;
|
||||||
? trustedValidate({ value, rootURL })
|
/**
|
||||||
: await untrustedValidate({ value, rootURL });
|
* The root URL of the specified OpenAPI document.
|
||||||
|
*/
|
||||||
const filesystem = await createFileSystem({ value: specification, rootURL });
|
rootURL: string | null;
|
||||||
|
}): Promise<Filesystem<OpenAPIV3xDocument>> {
|
||||||
return filesystem;
|
|
||||||
}
|
|
||||||
|
|
||||||
type ValidateOpenAPIV3Input = Pick<ParseOpenAPIInput, 'value' | 'rootURL'>;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Validate an untrusted OpenAPI v3 document.
|
|
||||||
*/
|
|
||||||
async function untrustedValidate(input: ValidateOpenAPIV3Input) {
|
|
||||||
const { value, rootURL } = input;
|
const { value, rootURL } = input;
|
||||||
const result = await validate(value);
|
const result = await validate(value);
|
||||||
|
|
||||||
@@ -46,36 +36,7 @@ async function untrustedValidate(input: ValidateOpenAPIV3Input) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return result.specification;
|
const filesystem = await createFileSystem({ value: result.specification, rootURL });
|
||||||
}
|
|
||||||
|
return filesystem;
|
||||||
/**
|
|
||||||
* Validate a trusted OpenAPI v3 document.
|
|
||||||
* It assumes the specification is already a valid specification.
|
|
||||||
* It's faster than `untrustedValidate`.
|
|
||||||
*/
|
|
||||||
function trustedValidate(input: ValidateOpenAPIV3Input) {
|
|
||||||
const { value, rootURL } = input;
|
|
||||||
const result = (() => {
|
|
||||||
if (typeof value === 'string') {
|
|
||||||
try {
|
|
||||||
return JSON.parse(value);
|
|
||||||
} catch (error) {
|
|
||||||
throw new OpenAPIParseError('Invalid JSON', {
|
|
||||||
code: 'invalid',
|
|
||||||
rootURL,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
})();
|
|
||||||
|
|
||||||
if ('swagger' in result && result.swagger) {
|
|
||||||
throw new OpenAPIParseError('Only OpenAPI v3 is supported', {
|
|
||||||
code: 'parse-v2-in-v3',
|
|
||||||
rootURL,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user