Files
gitbook/src/lib/references.ts
T
Samy Pessé 85ec1884e6 OpenAPI blocks (#74)
* Start methods to resolve refs

* bun

* Start package

* Add code to resolve ref

* Continue

* Deref

* Start monorepo

* Continue

* Fix ref resolver

* Style a bit more

* Start toggling section

* Continue

* Start displaying query/path/headers params

* Hide respo se if empty

* Fix recursive refs

* Simplify interactive and styling

* Display enums

* Format

* Improve type name being displayed

* Improve naming

* Render oneOf/anyOf/allOf

* Handle circular references

* Start variable in server url

* Use client component for the spec part

* Improve CSS sizing

* Display open api blocks in aside

* Make aside an overlay

* Improve stickiness of openapi

* Align document on the left when api page

* Improve general layout

* Better align

* Fix padding in aside

* Use syntax highlighting

* Show sample of response

* Improve code generation

* Improve code generated

* Format

* Format

* Rename to OpenAPI

* Skip deprecated properties and handle additionalProperties

* Use discriminator for naming

* Better name enum

* Make entire header toggeable

* Format and lint

* Add curl example

* Improve curl

* style pass

* Start securities

* Bun

* Fix TS

* Improve label

* Start markdown

* Improve code samples

* Test

* Use custom skeleton for api block

* Format

* Add support for redocly code samples

* Fix api blocks in aside

* Use typography for markdown

* Format

* Fix spacing in markdown

* Render headers

* Format

* Format

---------

Co-authored-by: Sebastian Graz <graz@live.se>
2024-01-30 10:15:58 +01:00

124 lines
3.7 KiB
TypeScript

import { ContentRef, Revision, RevisionPageDocument, Space } from '@gitbook/api';
import assertNever from 'assert-never';
import { ContentPointer, getRevisionFile, getUserById } from './api';
import { gitbookAppHref, pageHref, PageHrefContext } from './links';
import { resolvePageId } from './pages';
export interface ResolvedContentRef {
/** Text to render in the content ref */
text: string;
/** URL to open for the content ref */
href: string;
/** True if the content ref is active */
active: boolean;
/** Image size, if the reference is a image file */
fileDimensions?: { width: number; height: number };
}
export interface ContentRefContext extends PageHrefContext {
content: ContentPointer;
space: Space;
pages: Revision['pages'];
page?: RevisionPageDocument;
}
/**
* Resolve a content reference to be rendered.
*/
export async function resolveContentRef(
contentRef: ContentRef,
{ content, space, pages, page: activePage, ...linksContext }: ContentRefContext,
): Promise<ResolvedContentRef | null> {
// Try to resolve a local ref in the current space
if (contentRef.kind === 'url') {
return {
href: contentRef.url,
text: contentRef.url,
active: false,
};
} else if (contentRef.kind === 'file') {
const file = await getRevisionFile(content, contentRef.file);
if (file) {
return {
href: file.downloadURL,
text: file.name,
active: false,
fileDimensions: file.dimensions,
};
} else {
return null;
}
} else if (
(contentRef.kind === 'page' || contentRef.kind === 'anchor') &&
(contentRef.space ?? space.id) === space.id
) {
const page =
!contentRef.page || contentRef.page === activePage?.id
? activePage
: resolvePageId(pages, contentRef.page)?.page;
if (!page) {
return null;
}
if (contentRef.kind === 'page') {
return {
href: pageHref(pages, page, linksContext),
text: page.title,
active: page.id === activePage?.id,
};
}
return {
href: pageHref(pages, page, linksContext, contentRef.anchor),
text: page.title + '#' + contentRef.anchor,
active: false,
};
} else if (contentRef.kind === 'space' && contentRef.space === space.id) {
return {
href: space.urls.published ?? space.urls.app,
text: space.title,
active: true,
};
}
if (contentRef.kind === 'user') {
const user = await getUserById(contentRef.user);
if (user) {
return {
href: `mailto:${user.email}`,
text: user.displayName ?? user.email,
active: false,
};
} else {
return null;
}
}
// For absolute content outside the current space, we mock GitBook URLs.
if (contentRef.kind === 'space' || contentRef.kind === 'anchor' || contentRef.kind === 'page') {
return {
href: gitbookAppHref(`/s/${contentRef.space!}`),
text: 'space',
active: false,
};
}
if (contentRef.kind === 'collection') {
return {
href: gitbookAppHref(`/c/${contentRef.collection}`),
text: 'collection',
active: false,
};
}
if (contentRef.kind === 'snippet') {
return {
href: gitbookAppHref(`/o/${contentRef.organization}/snippet/${contentRef.snippet}`),
text: 'snippet',
active: false,
};
}
assertNever(contentRef);
}