@scalar/api-reference
Version:
Generate beautiful API references from OpenAPI documents
165 lines (164 loc) • 4.76 kB
JavaScript
import { extractParameters, extractRequestBody } from "../../../helpers/openapi.js";
import { combineParams } from "@scalar/workspace-store/request-example";
import { getResolvedRef } from "@scalar/workspace-store/helpers/get-resolved-ref";
//#region src/features/Search/helpers/create-search-index.ts
function responseExampleValueToString(value) {
if (typeof value === "string") return value;
try {
return JSON.stringify(value);
} catch (_error) {
return "";
}
}
function mediaTypeExamplesToStrings(mediaType) {
const examplesFromNamedMap = Object.values(mediaType.examples ?? {}).flatMap((example) => {
const resolvedExample = getResolvedRef(example);
if (!resolvedExample || !("value" in resolvedExample)) return [];
return responseExampleValueToString(resolvedExample.value);
}).filter((value) => value.length > 0);
const mediaTypeExample = "example" in mediaType && mediaType.example !== void 0 ? responseExampleValueToString(mediaType.example) : "";
return mediaTypeExample ? [mediaTypeExample, ...examplesFromNamedMap] : examplesFromNamedMap;
}
function extractResponseExamples(responses) {
if (!responses) return [];
return Object.values(responses).flatMap((response) => {
const resolvedResponse = getResolvedRef(response);
if (!resolvedResponse?.content) return [];
return Object.values(resolvedResponse.content).flatMap((mediaType) => {
const resolvedMediaType = getResolvedRef(mediaType);
if (!resolvedMediaType) return [];
return mediaTypeExamplesToStrings(resolvedMediaType);
});
}).filter((value) => value.length > 0);
}
/**
* Create a search index from a list of entries.
*/
function createSearchIndex(document) {
const index = [];
/**
* Recursively processes entries and their children to build the search index.
*/
function processEntries(entriesToProcess) {
entriesToProcess.forEach((entry) => {
addEntryToIndex(entry, index, document);
if ("children" in entry && entry.children) processEntries(entry.children);
});
}
processEntries(document?.["x-scalar-navigation"]?.children ?? []);
return index;
}
/**
* Adds a single entry to the search index, handling all entry types recursively.
*/
function addEntryToIndex(entry, index, document) {
if (entry.type === "operation") {
const pathItem = getResolvedRef(document?.paths?.[entry.path]);
const operation = getResolvedRef(pathItem?.[entry.method]) ?? {};
const operationWithPathParams = {
...operation,
parameters: combineParams(pathItem?.parameters, operation.parameters)
};
const parameters = extractParameters(operationWithPathParams.parameters ?? []);
const body = extractRequestBody(operationWithPathParams);
const responseExamples = extractResponseExamples(operationWithPathParams.responses);
index.push({
type: "operation",
title: entry.title,
id: entry.id,
description: operationWithPathParams.description || "",
method: entry.method,
path: entry.path,
body: body || "",
parameters: parameters ?? "",
responseExamples,
operationId: operationWithPathParams.operationId,
entry
});
return;
}
if (entry.type === "webhook") {
const webhook = getResolvedRef(document?.webhooks?.[entry.name]?.[entry.method]) ?? {};
index.push({
id: entry.id,
type: "webhook",
title: entry.title,
description: "Webhook",
method: entry.method,
body: webhook.description || "",
operationId: webhook.operationId,
entry
});
return;
}
if (entry.type === "model") {
const description = getResolvedRef(document?.components?.schemas?.[entry.name])?.description ?? "";
index.push({
type: "model",
title: entry.title,
description: "Model",
id: entry.id,
body: description,
entry
});
return;
}
if (entry.type === "models") {
index.push({
id: entry.id,
type: "heading",
title: "Models",
description: "Heading",
body: "",
entry
});
return;
}
if (entry.type === "tag" && entry.isWebhooks === true) {
index.push({
id: entry.id,
type: "heading",
title: "Webhooks",
description: "Heading",
body: "",
entry
});
return;
}
if (entry.type === "tag" && entry.isGroup === false) {
index.push({
id: entry.id,
title: entry.title,
description: entry.description || "",
type: "tag",
body: "",
entry
});
return;
}
if (entry.type === "tag" && entry.isGroup === true) {
index.push({
id: entry.id,
title: entry.title,
description: "Tag Group",
type: "tag",
body: "",
entry
});
return;
}
if (entry.type === "text") {
index.push({
id: entry.id,
type: "heading",
title: entry.title ?? "",
description: "Heading",
body: "",
entry
});
return;
}
}
//#endregion
export { createSearchIndex };
//# sourceMappingURL=create-search-index.js.map