mirror of
https://github.com/GitbookIO/gitbook.git
synced 2026-09-12 14:00:28 +00:00
Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 32a73b55d4 | |||
| 0426312d6c | |||
| ede2335fb3 | |||
| 709f1a1ccb | |||
| 24b785cbfb | |||
| acc3f2f418 | |||
| d4a653d6a9 | |||
| 7e74d25447 | |||
| 3445db41ce |
@@ -23,5 +23,8 @@
|
||||
"@changesets/cli": "^2.27.7",
|
||||
"prettier": "^3.0.3",
|
||||
"turbo": "^2.0.9"
|
||||
},
|
||||
"patchedDependencies": {
|
||||
"@vercel/next@4.0.15": "patches/@vercel%2Fnext@4.0.15.patch"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,28 @@
|
||||
# gitbook
|
||||
|
||||
## 0.3.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 24b785c: Update shiki for code block syntax highlighting, with support for more languages and fixes for diffs. It also patches the deployment on Cloudflare to support edge functions larger than 4MB.
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- acc3f2f: Fix error with the "Try it" of OpenAPI block because of the Scalar proxy failing on Cloudflare with the `cache` option
|
||||
- Updated dependencies [709f1a1]
|
||||
- Updated dependencies [ede2335]
|
||||
- Updated dependencies [0426312]
|
||||
- @gitbook/react-openapi@0.6.0
|
||||
|
||||
## 0.2.2
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- Updated dependencies [3445db4]
|
||||
- @gitbook/react-contentkit@0.5.0
|
||||
- @gitbook/react-openapi@0.5.0
|
||||
- @gitbook/react-math@0.5.0
|
||||
|
||||
## 0.2.1
|
||||
|
||||
### Patch Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "gitbook",
|
||||
"version": "0.2.1",
|
||||
"version": "0.3.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -55,7 +55,7 @@
|
||||
"remark-rehype": "^11.1.0",
|
||||
"rison": "^0.1.1",
|
||||
"server-only": "^0.0.1",
|
||||
"shiki": "^1.2.0",
|
||||
"shiki": "^1.11.1",
|
||||
"tailwind-merge": "^2.2.0",
|
||||
"tailwind-shades": "^1.1.2",
|
||||
"unified": "^11.0.4",
|
||||
|
||||
@@ -30,7 +30,7 @@ export async function POST(req: NextRequest) {
|
||||
// no-cors, *cors, same-origin
|
||||
// mode: 'cors', // Not supported on Cloudflare Workers
|
||||
// *default, no-cache, reload, force-cache, only-if-cached
|
||||
cache: 'no-cache',
|
||||
// cache: 'no-cache', // Not supported on Cloudflare Workers
|
||||
// include, *same-origin, omit
|
||||
// credentials: 'include', // Not supported on Cloudflare Workers
|
||||
headers: requestBody.headers,
|
||||
|
||||
@@ -9,6 +9,9 @@
|
||||
--shiki-token-string-expression: #6a4906;
|
||||
--shiki-token-punctuation: theme('colors.pomegranate.700/.92');
|
||||
--shiki-token-link: theme('colors.dark.DEFAULT');
|
||||
--shiki-token-inserted: #22863a;
|
||||
--shiki-token-deleted: #b31d28;
|
||||
--shiki-token-changed: #8250df;
|
||||
}
|
||||
|
||||
html.dark {
|
||||
@@ -22,4 +25,7 @@ html.dark {
|
||||
--shiki-token-string-expression: theme('colors.light.4');
|
||||
--shiki-token-punctuation: #acc6ee;
|
||||
--shiki-token-link: theme('colors.pomegranate.400');
|
||||
--shiki-token-inserted: #85e89d;
|
||||
--shiki-token-deleted: #fdaeb7;
|
||||
--shiki-token-changed: #56b6c2;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ export async function OpenAPI(props: BlockProps<DocumentBlockSwagger>) {
|
||||
|
||||
async function OpenAPIBody(props: BlockProps<DocumentBlockSwagger>) {
|
||||
const { block, context } = props;
|
||||
const { data, error } = await fetchOpenAPIBlock(block, context.resolveContentRef);
|
||||
const { data, specUrl, error } = await fetchOpenAPIBlock(block, context.resolveContentRef);
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
@@ -46,7 +46,7 @@ async function OpenAPIBody(props: BlockProps<DocumentBlockSwagger>) {
|
||||
);
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
if (!data || !specUrl) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ async function OpenAPIBody(props: BlockProps<DocumentBlockSwagger>) {
|
||||
},
|
||||
CodeBlock: PlainCodeBlock,
|
||||
defaultInteractiveOpened: context.mode === 'print',
|
||||
specUrl,
|
||||
}}
|
||||
className="openapi-block"
|
||||
/>
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
@import '@scalar/api-client-react/style.css';
|
||||
|
||||
.light .scalar-modal-layout,
|
||||
.light .scalar-app,
|
||||
.light .scalar {
|
||||
--scalar-color-1: color-mix(
|
||||
in srgb,
|
||||
@@ -50,8 +53,13 @@
|
||||
--scalar-button-1: rgb(49 53 56);
|
||||
--scalar-button-1-color: #fff;
|
||||
--scalar-button-1-hover: rgb(28 31 33);
|
||||
|
||||
--scalar-shadow-1: 0 1px 3px 0 rgba(0, 0, 0, 0.11);
|
||||
--scalar-shadow-2: rgba(0, 0, 0, 0.08) 0px 13px 20px 0px, rgba(0, 0, 0, 0.08) 0px 3px 8px 0px,
|
||||
#eeeeed 0px 0 0 1px;
|
||||
}
|
||||
.dark .scalar-modal-layout,
|
||||
.dark .scalar-app,
|
||||
.dark .scalar {
|
||||
--scalar-color-1: color-mix(
|
||||
in srgb,
|
||||
@@ -102,8 +110,13 @@
|
||||
--scalar-button-1: #f6f6f6;
|
||||
--scalar-button-1-color: #000;
|
||||
--scalar-button-1-hover: #e7e7e7;
|
||||
|
||||
--scalar-shadow-1: 0 1px 3px 0 rgb(0, 0, 0, 0.1);
|
||||
--scalar-shadow-2: rgba(15, 15, 15, 0.2) 0px 3px 6px, rgba(15, 15, 15, 0.4) 0px 9px 24px,
|
||||
0 0 0 1px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
.scalar-modal-layout,
|
||||
.scalar-app,
|
||||
.scalar {
|
||||
--scalar-font: initial;
|
||||
--scalar-font-code: var(--font-mono);
|
||||
@@ -165,7 +178,7 @@
|
||||
.scalar-api-client__close:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.scalar .scalar-app {
|
||||
.scalar .scalar-app-layout {
|
||||
background: var(--scalar-background-3);
|
||||
height: calc(100dvh - 100px);
|
||||
max-width: 1280px;
|
||||
@@ -202,23 +215,6 @@
|
||||
cursor: pointer;
|
||||
animation: scalardrawerexitfadein 0.35s forwards;
|
||||
}
|
||||
.scalar .scalar-app-exit:before {
|
||||
content: '\00d7';
|
||||
font-family: sans-serif;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
font-size: 30px;
|
||||
font-weight: 100;
|
||||
line-height: 50px;
|
||||
right: 12px;
|
||||
text-align: center;
|
||||
color: white;
|
||||
opacity: 0.6;
|
||||
}
|
||||
.scalar .scalar-app-exit:hover:before {
|
||||
opacity: 1;
|
||||
}
|
||||
@keyframes scalardrawerexitfadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
@@ -305,11 +301,6 @@
|
||||
scrollbar-width: thin;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
@supports (-moz-appearance: none) {
|
||||
.scalar .custom-scroll {
|
||||
padding-right: 12px;
|
||||
}
|
||||
}
|
||||
.scalar .custom-scroll:hover {
|
||||
scrollbar-color: rgba(0, 0, 0, 0.24) transparent;
|
||||
}
|
||||
@@ -347,3 +338,18 @@
|
||||
padding-right: 12px;
|
||||
}
|
||||
}
|
||||
.dark .scalar .client-wrapper-bg-color {
|
||||
background: linear-gradient(
|
||||
color-mix(in srgb, var(--tw-bg-base) 6%, transparent) 1%,
|
||||
color-mix(in srgb, var(--scalar-background-1) 30%, black) 9%
|
||||
);
|
||||
}
|
||||
.light .scalar .client-wrapper-bg-color {
|
||||
background-color: var(--scalar-background-2) !important;
|
||||
}
|
||||
.scalar .gitbook-show {
|
||||
display: block !important;
|
||||
}
|
||||
.scalar .gitbook-hidden {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@@ -266,7 +266,7 @@ function transformSectionsAndPage(args: {
|
||||
type: 'page',
|
||||
id: item.id,
|
||||
title: item.title,
|
||||
href: getURL(item.path),
|
||||
href: getURL(item.path, spaceURL),
|
||||
spaceTitle: space?.title,
|
||||
};
|
||||
|
||||
|
||||
@@ -19,12 +19,12 @@ export async function fetchOpenAPIBlock(
|
||||
block: DocumentBlockSwagger,
|
||||
resolveContentRef: (ref: ContentRef) => Promise<ResolvedContentRef | null>,
|
||||
): Promise<
|
||||
| { data: OpenAPIOperationData | null; error?: undefined }
|
||||
| { error: OpenAPIFetchError; data?: undefined }
|
||||
| { data: OpenAPIOperationData | null; specUrl: string | null; error?: undefined }
|
||||
| { error: OpenAPIFetchError; data?: undefined; specUrl?: undefined }
|
||||
> {
|
||||
const resolved = block.data.ref ? await resolveContentRef(block.data.ref) : null;
|
||||
if (!resolved || !block.data.path || !block.data.method) {
|
||||
return { data: null };
|
||||
return { data: null, specUrl: null };
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -37,7 +37,7 @@ export async function fetchOpenAPIBlock(
|
||||
fetcher,
|
||||
);
|
||||
|
||||
return { data };
|
||||
return { data, specUrl: resolved.href };
|
||||
} catch (error) {
|
||||
if (error instanceof OpenAPIFetchError) {
|
||||
return { error };
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @gitbook/react-contentkit
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 3445db4: Fix files published in the NPM packages by defining "files" in "package.json"
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@gitbook/react-contentkit",
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"exports": {
|
||||
".": {
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -23,5 +23,11 @@
|
||||
"build": "tsc",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"dev": "tsc -w"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"README.md",
|
||||
"CHANGELOG.md"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# @gitbook/react-math
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 3445db4: Fix files published in the NPM packages by defining "files" in "package.json"
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"version": "0.4.0",
|
||||
"version": "0.5.0",
|
||||
"dependencies": {
|
||||
"object-hash": "^3.0.0"
|
||||
},
|
||||
@@ -22,5 +22,12 @@
|
||||
"build": "tsc",
|
||||
"typecheck": "tsc --noEmit",
|
||||
"dev": "tsc -w"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"css",
|
||||
"README.md",
|
||||
"CHANGELOG.md"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,22 @@
|
||||
# @gitbook/react-openapi
|
||||
|
||||
## 0.6.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 709f1a1: Update Scalar to the latest version, with faster performances and an improved experience
|
||||
|
||||
### Patch Changes
|
||||
|
||||
- ede2335: Fix x-codeSamples: false not working at the single operation level
|
||||
- 0426312: Fix tabs being empty for code samples when they are updated dynamically
|
||||
|
||||
## 0.5.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
- 3445db4: Fix files published in the NPM packages by defining "files" in "package.json"
|
||||
|
||||
## 0.4.0
|
||||
|
||||
### Minor Changes
|
||||
|
||||
@@ -7,10 +7,9 @@
|
||||
"default": "./dist/index.js"
|
||||
}
|
||||
},
|
||||
"version": "0.4.0",
|
||||
"version": "0.6.0",
|
||||
"dependencies": {
|
||||
"@scalar/api-client-react": "^0.3.7",
|
||||
"@scalar/oas-utils": "0.1.6",
|
||||
"@scalar/api-client-react": "1.0.5",
|
||||
"classnames": "^2.5.1",
|
||||
"flatted": "^3.2.9",
|
||||
"openapi-types": "^12.1.3",
|
||||
@@ -30,5 +29,11 @@
|
||||
"typecheck": "tsc --noEmit",
|
||||
"unit": "bun test",
|
||||
"dev": "tsc -w"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"src",
|
||||
"README.md",
|
||||
"CHANGELOG.md"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
interface InteractiveSectionTab {
|
||||
key: string;
|
||||
label: string;
|
||||
body: React.ReactNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* To optimize rendering, most of the components are server-components,
|
||||
* and the interactiveness is mainly handled by a few key components like this one.
|
||||
@@ -19,11 +25,7 @@ export function InteractiveSection(props: {
|
||||
toggleOpenIcon?: React.ReactNode;
|
||||
toggleCloseIcon?: React.ReactNode;
|
||||
/** Tabs of content to display */
|
||||
tabs?: Array<{
|
||||
key: string;
|
||||
label: string;
|
||||
body: React.ReactNode;
|
||||
}>;
|
||||
tabs?: Array<InteractiveSectionTab>;
|
||||
/** Default tab to have opened */
|
||||
defaultTab?: string;
|
||||
/** Content of the header */
|
||||
@@ -48,9 +50,9 @@ export function InteractiveSection(props: {
|
||||
} = props;
|
||||
|
||||
const [opened, setOpened] = React.useState(defaultOpened);
|
||||
const [selectedTab, setSelectedTab] = React.useState(defaultTab);
|
||||
|
||||
const tabBody = tabs.find((tab) => tab.key === selectedTab)?.body;
|
||||
const [selectedTabKey, setSelectedTab] = React.useState(defaultTab);
|
||||
const selectedTab: InteractiveSectionTab | undefined =
|
||||
tabs.find((tab) => tab.key === selectedTabKey) ?? tabs[0];
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -94,7 +96,7 @@ export function InteractiveSection(props: {
|
||||
'openapi-select',
|
||||
`${className}-tabs-select`,
|
||||
)}
|
||||
value={selectedTab}
|
||||
value={selectedTab.key}
|
||||
onChange={(event) => {
|
||||
setSelectedTab(event.target.value);
|
||||
setOpened(true);
|
||||
@@ -107,7 +109,7 @@ export function InteractiveSection(props: {
|
||||
))}
|
||||
</select>
|
||||
) : null}
|
||||
{(children || tabBody) && toggeable ? (
|
||||
{(children || selectedTab?.body) && toggeable ? (
|
||||
<button
|
||||
className={classNames('openapi-section-toggle', `${className}-toggle`)}
|
||||
onClick={() => setOpened(!opened)}
|
||||
@@ -117,10 +119,10 @@ export function InteractiveSection(props: {
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
{(!toggeable || opened) && (children || tabBody) ? (
|
||||
{(!toggeable || opened) && (children || selectedTab?.body) ? (
|
||||
<div className={classNames('openapi-section-body', `${className}-body`)}>
|
||||
{children}
|
||||
{tabBody}
|
||||
{selectedTab?.body}
|
||||
</div>
|
||||
) : null}
|
||||
{overlay}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import * as React from 'react';
|
||||
|
||||
import { CodeSampleInput, codeSampleGenerators } from './code-samples';
|
||||
import { OpenAPIOperationData, toJSON } from './fetchOpenAPIOperation';
|
||||
import { OpenAPIOperationData } from './fetchOpenAPIOperation';
|
||||
import { generateMediaTypeExample } from './generateSchemaExample';
|
||||
import { InteractiveSection } from './InteractiveSection';
|
||||
import { getServersURL } from './OpenAPIServerURL';
|
||||
@@ -52,7 +52,7 @@ export function OpenAPICodeSample(props: {
|
||||
}> = null;
|
||||
(['x-custom-examples', 'x-code-samples', 'x-codeSamples'] as const).forEach((key) => {
|
||||
const customSamples = data.operation[key];
|
||||
if (customSamples) {
|
||||
if (customSamples && Array.isArray(customSamples)) {
|
||||
customCodeSamples = customSamples.map((sample) => ({
|
||||
key: `redocly-${sample.lang}`,
|
||||
label: sample.label,
|
||||
@@ -61,16 +61,15 @@ export function OpenAPICodeSample(props: {
|
||||
}
|
||||
});
|
||||
|
||||
const samples = customCodeSamples ?? (data['x-codeSamples'] !== false ? autoCodeSamples : []);
|
||||
// Code samples can be disabled at the top-level or at the operation level
|
||||
// If code samples are defined at the operation level, it will override the top-level setting
|
||||
const codeSamplesDisabled =
|
||||
data['x-codeSamples'] === false || data.operation['x-codeSamples'] === false;
|
||||
const samples = customCodeSamples ?? (!codeSamplesDisabled ? autoCodeSamples : []);
|
||||
if (samples.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
async function fetchOperationData() {
|
||||
'use server';
|
||||
return toJSON(data);
|
||||
}
|
||||
|
||||
return (
|
||||
<InteractiveSection
|
||||
header="Request"
|
||||
@@ -78,7 +77,7 @@ export function OpenAPICodeSample(props: {
|
||||
tabs={samples}
|
||||
overlay={
|
||||
data['x-hideTryItPanel'] || data.operation['x-hideTryItPanel'] ? null : (
|
||||
<ScalarApiButton fetchOperationData={fetchOperationData} />
|
||||
<ScalarApiButton />
|
||||
)
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -7,8 +7,8 @@ import { OpenAPICodeSample } from './OpenAPICodeSample';
|
||||
import { OpenAPIResponseExample } from './OpenAPIResponseExample';
|
||||
import { OpenAPIServerURL } from './OpenAPIServerURL';
|
||||
import { OpenAPISpec } from './OpenAPISpec';
|
||||
import { ScalarApiClient } from './ScalarApiButton';
|
||||
import { OpenAPIClientContext, OpenAPIContextProps } from './types';
|
||||
import { ApiClientModalProvider } from '@scalar/api-client-react';
|
||||
|
||||
/**
|
||||
* Display an interactive OpenAPI operation.
|
||||
@@ -23,11 +23,15 @@ export function OpenAPIOperation(props: {
|
||||
|
||||
const clientContext: OpenAPIClientContext = {
|
||||
defaultInteractiveOpened: context.defaultInteractiveOpened,
|
||||
specUrl: context.specUrl,
|
||||
icons: context.icons,
|
||||
};
|
||||
|
||||
return (
|
||||
<ScalarApiClient>
|
||||
<ApiClientModalProvider
|
||||
configuration={{ spec: { url: context.specUrl } }}
|
||||
initialRequest={{ path: data.path, method: data.method }}
|
||||
>
|
||||
<div className={classNames('openapi-operation', className)}>
|
||||
<div className="openapi-intro">
|
||||
<h2 className="openapi-summary">{operation.summary}</h2>
|
||||
@@ -61,6 +65,6 @@ export function OpenAPIOperation(props: {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</ScalarApiClient>
|
||||
</ApiClientModalProvider>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,44 +1,17 @@
|
||||
'use client';
|
||||
import {
|
||||
Cookie,
|
||||
getHarRequest,
|
||||
getParametersFromOperation,
|
||||
type TransformedOperation,
|
||||
getRequestFromOperation,
|
||||
Query,
|
||||
Header,
|
||||
RequestBody,
|
||||
} from '@scalar/oas-utils';
|
||||
|
||||
import { useApiClientModal } from '@scalar/api-client-react';
|
||||
import React from 'react';
|
||||
|
||||
import { OpenAPIOperationData, fromJSON } from './fetchOpenAPIOperation';
|
||||
|
||||
const ApiClientReact = React.lazy(async () => {
|
||||
const mod = await import('@scalar/api-client-react');
|
||||
return { default: mod.ApiClientReact };
|
||||
});
|
||||
|
||||
const ScalarContext = React.createContext<
|
||||
(fetchOperationData: () => Promise<OpenAPIOperationData>) => void
|
||||
>(() => {});
|
||||
|
||||
/**
|
||||
* Button which launches the Scalar API Client
|
||||
*/
|
||||
export function ScalarApiButton(props: {
|
||||
fetchOperationData: () => Promise<OpenAPIOperationData>;
|
||||
}) {
|
||||
const { fetchOperationData } = props;
|
||||
const open = React.useContext(ScalarContext);
|
||||
export function ScalarApiButton() {
|
||||
const client = useApiClientModal();
|
||||
|
||||
return (
|
||||
<div className="scalar scalar-activate">
|
||||
<button
|
||||
className="scalar-activate-button"
|
||||
onClick={() => {
|
||||
open(fetchOperationData);
|
||||
}}
|
||||
>
|
||||
<button className="scalar-activate-button" onClick={() => client?.open()}>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="12" fill="none">
|
||||
<path
|
||||
stroke="currentColor"
|
||||
@@ -51,109 +24,3 @@ export function ScalarApiButton(props: {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap the rendering with a context to open the scalar modal.
|
||||
*/
|
||||
export function ScalarApiClient(props: { children: React.ReactNode }) {
|
||||
const { children } = props;
|
||||
|
||||
const [active, setActive] = React.useState<null | {
|
||||
operationData: OpenAPIOperationData | null;
|
||||
}>(null);
|
||||
|
||||
const proxy = '/~scalar/proxy';
|
||||
|
||||
const open = React.useCallback(
|
||||
async (fetchOperationData: () => Promise<OpenAPIOperationData>) => {
|
||||
setActive({ operationData: null });
|
||||
const operationData = fromJSON(await fetchOperationData());
|
||||
setActive({ operationData });
|
||||
},
|
||||
[],
|
||||
);
|
||||
|
||||
const onClose = React.useCallback(() => {
|
||||
setActive(null);
|
||||
}, []);
|
||||
|
||||
const request = React.useMemo(() => {
|
||||
const operationData = active?.operationData;
|
||||
|
||||
if (!operationData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const operationId =
|
||||
operationData.operation.operationId ?? operationData.method + operationData.path;
|
||||
|
||||
const operation = {
|
||||
...operationData,
|
||||
httpVerb: operationData.method,
|
||||
pathParameters: operationData.operation.parameters,
|
||||
} as TransformedOperation;
|
||||
|
||||
const variables = getParametersFromOperation(operation, 'path', false);
|
||||
|
||||
const request = getHarRequest(
|
||||
{
|
||||
url: operationData.path,
|
||||
},
|
||||
getRequestFromOperation(
|
||||
{
|
||||
...operation,
|
||||
information: {
|
||||
requestBody: operationData.operation.requestBody as RequestBody,
|
||||
},
|
||||
},
|
||||
{ requiredOnly: false },
|
||||
),
|
||||
);
|
||||
|
||||
return {
|
||||
id: operationId,
|
||||
type: operationData.method,
|
||||
path: operationData.path,
|
||||
variables,
|
||||
cookies: request.cookies.map((cookie: Cookie) => {
|
||||
return { ...cookie, enabled: true };
|
||||
}),
|
||||
query: request.queryString.map((queryString: Query) => {
|
||||
const query: typeof queryString & { required?: boolean } = queryString;
|
||||
return { ...queryString, enabled: query.required ?? true };
|
||||
}),
|
||||
headers: request.headers.map((header: Header) => {
|
||||
return { ...header, enabled: true };
|
||||
}),
|
||||
url: operationData.servers[0]?.url,
|
||||
body: request.postData?.text,
|
||||
};
|
||||
}, [active]);
|
||||
|
||||
return (
|
||||
<ScalarContext.Provider value={open}>
|
||||
{children}
|
||||
{active ? (
|
||||
<div className="scalar">
|
||||
<div className="scalar-container">
|
||||
<div className="scalar-app">
|
||||
<React.Suspense fallback={<ScalarLoading />}>
|
||||
<ApiClientReact
|
||||
close={onClose}
|
||||
proxy={proxy}
|
||||
isOpen={true}
|
||||
request={request}
|
||||
/>
|
||||
</React.Suspense>
|
||||
</div>
|
||||
<div onClick={() => onClose()} className="scalar-app-exit"></div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</ScalarContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
function ScalarLoading() {
|
||||
return <div className="scalar-app-loading">Loading...</div>;
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ export interface OpenAPICustomSpecProperties {
|
||||
*/
|
||||
export interface OpenAPICustomOperationProperties {
|
||||
'x-code-samples'?: OpenAPICustomCodeSample[];
|
||||
'x-codeSamples'?: OpenAPICustomCodeSample[];
|
||||
'x-codeSamples'?: OpenAPICustomCodeSample[] | false;
|
||||
'x-custom-examples'?: OpenAPICustomCodeSample[];
|
||||
|
||||
/**
|
||||
|
||||
@@ -10,6 +10,9 @@ export interface OpenAPIClientContext {
|
||||
chevronRight: React.ReactNode;
|
||||
};
|
||||
|
||||
/** Spec url foor the Scalar Api Client */
|
||||
specUrl: string;
|
||||
|
||||
/**
|
||||
* Force all sections to be opened by default.
|
||||
* @default false
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
diff --git a/dist/index.js b/dist/index.js
|
||||
index 7f9eaa2526e5fad42420f590bb733e5670766e63..302274144d28dde2b9ba8f9018281d2867f79299 100644
|
||||
--- a/dist/index.js
|
||||
+++ b/dist/index.js
|
||||
@@ -9484,7 +9484,7 @@ var import_path = require("path");
|
||||
// src/constants.ts
|
||||
var KIB = 1024;
|
||||
var MIB = 1024 * KIB;
|
||||
-var EDGE_FUNCTION_SIZE_LIMIT = 4 * MIB;
|
||||
+var EDGE_FUNCTION_SIZE_LIMIT = 10 * MIB;
|
||||
var MAX_UNCOMPRESSED_LAMBDA_SIZE = 250 * MIB;
|
||||
var LAMBDA_RESERVED_UNCOMPRESSED_SIZE = 2.5 * MIB;
|
||||
var LAMBDA_RESERVED_COMPRESSED_SIZE = 250 * KIB;
|
||||
Reference in New Issue
Block a user