@mintlify/common 1.0.824 → 1.0.825

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
1
  import type { Root } from 'mdast';
2
- export declare const remarkMdxRemoveUnknownJsx: () => (tree: Root) => Root | import("mdast").Link | import("mdast").Delete | import("mdast").Blockquote | import("mdast").Break | import("mdast").Code | import("mdast").Definition | import("mdast").Emphasis | import("mdast").FootnoteDefinition | import("mdast").FootnoteReference | import("mdast").Heading | import("mdast").Html | import("mdast").Image | import("mdast").ImageReference | import("mdast").InlineCode | import("mdast").LinkReference | import("mdast").List | import("mdast").ListItem | import("mdast").Paragraph | import("mdast").Strong | import("mdast").Table | import("mdast").TableCell | import("mdast").TableRow | import("mdast").Text | import("mdast").ThematicBreak | import("mdast").Yaml | import("mdast-util-math").InlineMath | import("mdast-util-math").Math | import("mdast-util-mdx-expression").MdxTextExpression | import("mdast-util-mdx-expression").MdxFlowExpression | import("mdast-util-mdx").MdxJsxFlowElement | import("mdast-util-mdx").MdxJsxTextElement | import("mdast-util-mdxjs-esm").MdxjsEsm;
2
+ export declare const remarkMdxRemoveUnknownJsx: () => (tree: Root) => Root | import("mdast").Link | import("mdast").Delete | import("mdast").Code | import("mdast").Blockquote | import("mdast").Break | import("mdast").Definition | import("mdast").Emphasis | import("mdast").FootnoteDefinition | import("mdast").FootnoteReference | import("mdast").Heading | import("mdast").Html | import("mdast").Image | import("mdast").ImageReference | import("mdast").InlineCode | import("mdast").LinkReference | import("mdast").List | import("mdast").ListItem | import("mdast").Paragraph | import("mdast").Strong | import("mdast").Table | import("mdast").TableCell | import("mdast").TableRow | import("mdast").Text | import("mdast").ThematicBreak | import("mdast").Yaml | import("mdast-util-math").InlineMath | import("mdast-util-math").Math | import("mdast-util-mdx-expression").MdxTextExpression | import("mdast-util-mdx-expression").MdxFlowExpression | import("mdast-util-mdx").MdxJsxFlowElement | import("mdast-util-mdx").MdxJsxTextElement | import("mdast-util-mdxjs-esm").MdxjsEsm;
@@ -0,0 +1 @@
1
+ export declare function openApiMetaTagToEndpointRef(metaTag: string): string | undefined;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Converts an OpenAPI meta tag to a docs.json endpoint reference string.
3
+ *
4
+ * Meta tag format: "/openapi.json GET /plants" (leading slash on file path)
5
+ * Endpoint ref: "openapi.json GET /plants" (no leading slash)
6
+ *
7
+ * The full format includes the spec file path so it's self-contained —
8
+ * endpoints from different spec files can coexist in the same group.
9
+ */
10
+ import { optionallyRemoveLeadingSlash } from '../optionallyRemoveLeadingSlash.js';
11
+ import { potentiallyParseOpenApiString } from './parseOpenApiString.js';
12
+ export function openApiMetaTagToEndpointRef(metaTag) {
13
+ const parsed = potentiallyParseOpenApiString(metaTag);
14
+ if (!parsed)
15
+ return undefined;
16
+ const method = parsed.method.toUpperCase();
17
+ const filename = parsed.filename ? optionallyRemoveLeadingSlash(parsed.filename) : undefined;
18
+ return filename ? `${filename} ${method} ${parsed.endpoint}` : `${method} ${parsed.endpoint}`;
19
+ }
@@ -0,0 +1,3 @@
1
+ import { NavigationEntry } from '@mintlify/models';
2
+ export declare const prepareStringToBeValidFilename: (str?: string) => string | undefined;
3
+ export declare const generateUniqueFilenameWithoutExtension: (pages: NavigationEntry[], base: string) => string;
@@ -0,0 +1,23 @@
1
+ export const prepareStringToBeValidFilename = (str) => str
2
+ ? str
3
+ .replaceAll(' ', '-')
4
+ .replace(/\{.*?\}/g, '-') // remove path parameters
5
+ .replace(/^-/, '')
6
+ .replace(/-$/, '')
7
+ .replace(/[{}(),.'\n\/]/g, '') // remove special characters
8
+ .replaceAll(/--/g, '-') // replace double hyphens
9
+ .toLowerCase()
10
+ : undefined;
11
+ // returns a filename that is unique within the given array of pages
12
+ export const generateUniqueFilenameWithoutExtension = (pages, base) => {
13
+ let filename = base;
14
+ if (pages.includes(filename)) {
15
+ let extension = 1;
16
+ filename = `${base}-${extension}`;
17
+ while (pages.includes(filename)) {
18
+ extension += 1;
19
+ filename = `${base}-${extension}`;
20
+ }
21
+ }
22
+ return filename.toLowerCase();
23
+ };
@@ -0,0 +1,5 @@
1
+ import { DecoratedGroupsConfig, DecoratedPagesConfig, GroupsConfig, PagesConfig } from '@mintlify/validation';
2
+ export declare const DEFAULT_API_GROUP_NAME = "API Reference";
3
+ export declare const DEFAULT_WEBSOCKETS_GROUP_NAME = "Websockets";
4
+ export declare function findNavGroup(nav: GroupsConfig, groupName?: string): PagesConfig;
5
+ export declare function findNavGroup(nav: DecoratedGroupsConfig, groupName?: string): DecoratedPagesConfig;
@@ -0,0 +1,17 @@
1
+ export const DEFAULT_API_GROUP_NAME = 'API Reference';
2
+ export const DEFAULT_WEBSOCKETS_GROUP_NAME = 'Websockets';
3
+ export function findNavGroup(nav, groupName = DEFAULT_API_GROUP_NAME) {
4
+ const group = nav.find((fileOrGroup) => typeof fileOrGroup === 'object' && 'group' in fileOrGroup && fileOrGroup.group === groupName);
5
+ if (group === undefined || !('pages' in group)) {
6
+ const newGroup = {
7
+ group: groupName,
8
+ pages: [],
9
+ };
10
+ nav.push(newGroup);
11
+ return newGroup.pages;
12
+ }
13
+ if (Array.isArray(group.pages)) {
14
+ return group.pages;
15
+ }
16
+ return [];
17
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Browser-safe utility to generate API page metadata from an OpenAPI spec.
3
+ * Mirrors the logic in @mintlify/scraping's processOpenApiPath/processOpenApiWebhook
4
+ * but without Node.js dependencies (fs, path, etc.).
5
+ */
6
+ import type { PageMetaTags } from '@mintlify/models';
7
+ import { OpenAPIV3 } from 'openapi-types';
8
+ /**
9
+ * Build MDX content string matching what createOpenApiFrontmatter produces in prebuild.
10
+ * Includes title, description, openapi tag, version, deprecated, and all x-mint metadata
11
+ * as proper YAML frontmatter. Browser-safe (no filesystem access).
12
+ */
13
+ export declare function buildGeneratedMdxContent(page: GeneratedApiPage): string;
14
+ export type GeneratedApiPage = {
15
+ /** Display title for the page */
16
+ title: string;
17
+ /** Operation description */
18
+ description?: string;
19
+ /** Whether the operation is deprecated */
20
+ deprecated?: boolean;
21
+ /** OpenAPI meta tag, e.g. "/api-reference/openapi.json GET /users" */
22
+ openapi: string;
23
+ /** Generated page slug, e.g. "/api-reference/endpoints/get-users" */
24
+ href: string;
25
+ /** HTTP method, e.g. "get", "post" */
26
+ method: string;
27
+ /** API path, e.g. "/users" */
28
+ path: string;
29
+ /** Operation tag (used for sub-grouping) */
30
+ tag?: string;
31
+ /** Whether the operation is x-hidden */
32
+ hidden?: boolean;
33
+ /** Whether this is a webhook */
34
+ isWebhook?: boolean;
35
+ /** Any x-mint metadata */
36
+ xMintMetadata?: PageMetaTags;
37
+ /** Extra MDX content from x-mint.content */
38
+ xMintContent?: string;
39
+ /** API version */
40
+ version?: string;
41
+ };
42
+ export type GenerateOpenApiPagesOptions = {
43
+ /** Parsed OpenAPI v3 document */
44
+ spec: OpenAPIV3.Document;
45
+ /** File path of the spec, e.g. "api-reference/openapi.json" */
46
+ specFilePath: string;
47
+ /** Output directory for slug generation, defaults to "api-reference" */
48
+ outputDirectory?: string;
49
+ /** Optional API version string */
50
+ version?: string;
51
+ };
52
+ export declare function generateOpenApiPages(opts: GenerateOpenApiPagesOptions): GeneratedApiPage[];
@@ -0,0 +1,208 @@
1
+ import jsYaml from 'js-yaml';
2
+ import { OpenAPIV3 } from 'openapi-types';
3
+ import { optionallyAddLeadingSlash } from '../fs/optionallySlash.js';
4
+ import { slugToTitle } from '../slug/slugToTitle.js';
5
+ import { buildOpenApiMetaTag } from './buildOpenApiMetaTag.js';
6
+ import { prepareStringToBeValidFilename, generateUniqueFilenameWithoutExtension, } from './filenameUtils.js';
7
+ import { getOpenApiTitleAndDescription } from './getOpenApiTitleAndDescription.js';
8
+ /**
9
+ * Build MDX content string matching what createOpenApiFrontmatter produces in prebuild.
10
+ * Includes title, description, openapi tag, version, deprecated, and all x-mint metadata
11
+ * as proper YAML frontmatter. Browser-safe (no filesystem access).
12
+ */
13
+ export function buildGeneratedMdxContent(page) {
14
+ var _a, _b;
15
+ // Build frontmatter object with fields in a consistent order
16
+ const fm = {};
17
+ const metadata = page.xMintMetadata;
18
+ // title: x-mint metadata takes priority, then page-level
19
+ fm.title = (_a = (metadata && 'title' in metadata ? metadata.title : undefined)) !== null && _a !== void 0 ? _a : page.title;
20
+ // description: x-mint metadata takes priority, then page-level
21
+ const effectiveDescription = (_b = (metadata && 'description' in metadata ? metadata.description : undefined)) !== null && _b !== void 0 ? _b : page.description;
22
+ if (effectiveDescription) {
23
+ fm.description = effectiveDescription;
24
+ }
25
+ fm.openapi = page.openapi;
26
+ // version: x-mint metadata takes priority, then page-level
27
+ if (metadata && 'version' in metadata) {
28
+ fm.version = metadata.version;
29
+ }
30
+ else if (page.version) {
31
+ fm.version = page.version;
32
+ }
33
+ // deprecated: x-mint metadata takes priority, then page-level
34
+ if (metadata && 'deprecated' in metadata) {
35
+ fm.deprecated = metadata.deprecated;
36
+ }
37
+ else if (page.deprecated) {
38
+ fm.deprecated = page.deprecated;
39
+ }
40
+ // All remaining x-mint metadata fields
41
+ if (metadata) {
42
+ const reserved = new Set(['openapi', 'version', 'deprecated', 'title', 'description']);
43
+ for (const [key, value] of Object.entries(metadata)) {
44
+ if (!reserved.has(key) && value !== undefined) {
45
+ fm[key] = value;
46
+ }
47
+ }
48
+ }
49
+ const yamlStr = jsYaml
50
+ .dump(fm, { lineWidth: -1, quotingType: "'", forceQuotes: false })
51
+ .trimEnd();
52
+ const frontmatter = `---\n${yamlStr}\n---`;
53
+ return page.xMintContent ? `${frontmatter}\n\n${page.xMintContent}` : frontmatter;
54
+ }
55
+ const posixJoin = (...segments) => segments.join('/').replace(/\/+/g, '/').replace(/\/$/, '') || '/';
56
+ const posixResolve = (base, path) => {
57
+ if (path.startsWith('/'))
58
+ return path;
59
+ return posixJoin(base, path);
60
+ };
61
+ const DEFAULT_OUTPUT_DIR = 'api-reference';
62
+ function getXMintGroups(pathObject, operationObject) {
63
+ var _a, _b;
64
+ const groups = [];
65
+ if (((_a = pathObject['x-mint']) === null || _a === void 0 ? void 0 : _a.groups) && Array.isArray(pathObject['x-mint'].groups)) {
66
+ groups.push(...pathObject['x-mint'].groups);
67
+ }
68
+ if (((_b = operationObject === null || operationObject === void 0 ? void 0 : operationObject['x-mint']) === null || _b === void 0 ? void 0 : _b.groups) && Array.isArray(operationObject['x-mint'].groups)) {
69
+ groups.push(...operationObject['x-mint'].groups);
70
+ }
71
+ return groups;
72
+ }
73
+ export function generateOpenApiPages(opts) {
74
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
75
+ const { spec, specFilePath, outputDirectory } = opts;
76
+ const outDir = outputDirectory !== null && outputDirectory !== void 0 ? outputDirectory : DEFAULT_OUTPUT_DIR;
77
+ const openApiFilePathFromRoot = optionallyAddLeadingSlash(specFilePath);
78
+ const pages = [];
79
+ // Track used filenames for uniqueness (mirrors the nav array in processOpenApiPath)
80
+ const usedFilenames = [];
81
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
82
+ const openApiFiles = [
83
+ {
84
+ filename: (_a = specFilePath.split('/').pop()) !== null && _a !== void 0 ? _a : 'spec',
85
+ spec: spec,
86
+ originalFileLocation: specFilePath,
87
+ },
88
+ ];
89
+ // Process paths
90
+ for (const [apiPath, pathItemObject] of Object.entries(spec.paths)) {
91
+ if (!pathItemObject || typeof pathItemObject !== 'object')
92
+ continue;
93
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
94
+ const pathItem = pathItemObject;
95
+ for (const method of Object.values(OpenAPIV3.HttpMethods)) {
96
+ if (!(method in pathItem))
97
+ continue;
98
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
99
+ const operation = pathItem[method];
100
+ if (!operation)
101
+ continue;
102
+ if (operation['x-excluded'])
103
+ continue;
104
+ const xMint = operation['x-mint'];
105
+ const xMintGroups = getXMintGroups(pathItem, operation);
106
+ const groupName = (_b = operation.tags) === null || _b === void 0 ? void 0 : _b[0];
107
+ let title = (_c = prepareStringToBeValidFilename(operation.summary)) !== null && _c !== void 0 ? _c : `${method}-${prepareStringToBeValidFilename(apiPath)}`;
108
+ let folder = (_d = prepareStringToBeValidFilename(groupName)) !== null && _d !== void 0 ? _d : '';
109
+ let base = posixJoin(outDir, folder, title);
110
+ if (xMint === null || xMint === void 0 ? void 0 : xMint.href) {
111
+ const href = xMint.href.startsWith('/') ? xMint.href.slice(1) : xMint.href;
112
+ const lastSlash = href.lastIndexOf('/');
113
+ title = lastSlash >= 0 ? href.slice(lastSlash + 1) : href;
114
+ folder = lastSlash >= 0 ? href.slice(0, lastSlash) : '';
115
+ base = posixJoin(folder, title);
116
+ }
117
+ const filenameWithoutExtension = generateUniqueFilenameWithoutExtension(usedFilenames, base);
118
+ usedFilenames.push(filenameWithoutExtension);
119
+ const openapiMetaTag = buildOpenApiMetaTag({
120
+ filePath: openApiFilePathFromRoot,
121
+ method,
122
+ path: apiPath,
123
+ });
124
+ const { title: titleTag, description } = getOpenApiTitleAndDescription(openApiFiles, openapiMetaTag);
125
+ let xMintMetadata = xMint === null || xMint === void 0 ? void 0 : xMint.metadata;
126
+ if (xMintGroups.length > 0) {
127
+ xMintMetadata = Object.assign(Object.assign({}, xMintMetadata), { groups: [
128
+ ...(Array.isArray(xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.groups) ? xMintMetadata.groups : []),
129
+ ...xMintGroups,
130
+ ] });
131
+ }
132
+ const page = {
133
+ title: (_f = (_e = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.title) !== null && _e !== void 0 ? _e : titleTag) !== null && _f !== void 0 ? _f : slugToTitle(filenameWithoutExtension),
134
+ description: (_g = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.description) !== null && _g !== void 0 ? _g : description,
135
+ deprecated: (_h = xMintMetadata === null || xMintMetadata === void 0 ? void 0 : xMintMetadata.deprecated) !== null && _h !== void 0 ? _h : operation.deprecated,
136
+ openapi: openapiMetaTag,
137
+ href: posixResolve('/', filenameWithoutExtension),
138
+ method,
139
+ path: apiPath,
140
+ tag: groupName,
141
+ hidden: operation['x-hidden'] === true,
142
+ xMintMetadata,
143
+ xMintContent: xMint === null || xMint === void 0 ? void 0 : xMint.content,
144
+ version: opts.version,
145
+ };
146
+ pages.push(page);
147
+ }
148
+ }
149
+ // Process webhooks (OpenAPI 3.1)
150
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
151
+ const specWithWebhooks = spec;
152
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- webhooks exists in OpenAPI 3.1 but not in the v3 types
153
+ if (specWithWebhooks.webhooks) {
154
+ for (const [webhook, webhookObject] of Object.entries(specWithWebhooks.webhooks)) {
155
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- defensive check for malformed specs
156
+ if (!webhookObject || typeof webhookObject !== 'object')
157
+ continue;
158
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
159
+ const pathItem = webhookObject;
160
+ for (const method of Object.values(OpenAPIV3.HttpMethods)) {
161
+ if (!(method in pathItem))
162
+ continue;
163
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
164
+ const operation = pathItem[method];
165
+ if (!operation)
166
+ continue;
167
+ if (operation['x-excluded'])
168
+ continue;
169
+ const xMint = operation['x-mint'];
170
+ const groupName = (_j = operation.tags) === null || _j === void 0 ? void 0 : _j[0];
171
+ let title = (_k = prepareStringToBeValidFilename(operation.summary)) !== null && _k !== void 0 ? _k : `${prepareStringToBeValidFilename(webhook)}`;
172
+ let folder = (_l = prepareStringToBeValidFilename(groupName)) !== null && _l !== void 0 ? _l : '';
173
+ let base = posixJoin(outDir, folder, title);
174
+ if (xMint === null || xMint === void 0 ? void 0 : xMint.href) {
175
+ const href = xMint.href.startsWith('/') ? xMint.href.slice(1) : xMint.href;
176
+ const lastSlash = href.lastIndexOf('/');
177
+ title = lastSlash >= 0 ? href.slice(lastSlash + 1) : href;
178
+ folder = lastSlash >= 0 ? href.slice(0, lastSlash) : '';
179
+ base = posixJoin(folder, title);
180
+ }
181
+ const filenameWithoutExtension = generateUniqueFilenameWithoutExtension(usedFilenames, base);
182
+ usedFilenames.push(filenameWithoutExtension);
183
+ const openapiMetaTag = buildOpenApiMetaTag({
184
+ filePath: openApiFilePathFromRoot,
185
+ method: 'webhook',
186
+ path: webhook,
187
+ });
188
+ const page = {
189
+ title: (_o = (_m = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _m === void 0 ? void 0 : _m.title) !== null && _o !== void 0 ? _o : slugToTitle(filenameWithoutExtension),
190
+ description: (_q = (_p = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _p === void 0 ? void 0 : _p.description) !== null && _q !== void 0 ? _q : operation.description,
191
+ deprecated: (_s = (_r = xMint === null || xMint === void 0 ? void 0 : xMint.metadata) === null || _r === void 0 ? void 0 : _r.deprecated) !== null && _s !== void 0 ? _s : operation.deprecated,
192
+ openapi: openapiMetaTag,
193
+ href: posixResolve('/', filenameWithoutExtension),
194
+ method: 'webhook',
195
+ path: webhook,
196
+ tag: groupName,
197
+ hidden: operation['x-hidden'] === true,
198
+ isWebhook: true,
199
+ xMintMetadata: xMint === null || xMint === void 0 ? void 0 : xMint.metadata,
200
+ xMintContent: xMint === null || xMint === void 0 ? void 0 : xMint.content,
201
+ version: opts.version,
202
+ };
203
+ pages.push(page);
204
+ }
205
+ }
206
+ }
207
+ return pages;
208
+ }
@@ -8,3 +8,7 @@ export { buildOpenApiMetaTag } from './buildOpenApiMetaTag.js';
8
8
  export { registerXMintContent, getXMintContent, getAllXMintContent } from './contentRegistry.js';
9
9
  export { getMatchingOpenApiFile, type ApiReferenceMapping, type FileToUuidMap, type UuidToRefsMap, } from './getMatchingOpenApiFile.js';
10
10
  export { parseApiString } from './parseApiString.js';
11
+ export { openApiMetaTagToEndpointRef } from './endpointRef.js';
12
+ export { prepareStringToBeValidFilename, generateUniqueFilenameWithoutExtension, } from './filenameUtils.js';
13
+ export { findNavGroup, DEFAULT_API_GROUP_NAME, DEFAULT_WEBSOCKETS_GROUP_NAME, } from './findNavGroup.js';
14
+ export { generateOpenApiPages, buildGeneratedMdxContent, type GeneratedApiPage, type GenerateOpenApiPagesOptions, } from './generateOpenApiPages.js';
@@ -8,3 +8,7 @@ export { buildOpenApiMetaTag } from './buildOpenApiMetaTag.js';
8
8
  export { registerXMintContent, getXMintContent, getAllXMintContent } from './contentRegistry.js';
9
9
  export { getMatchingOpenApiFile, } from './getMatchingOpenApiFile.js';
10
10
  export { parseApiString } from './parseApiString.js';
11
+ export { openApiMetaTagToEndpointRef } from './endpointRef.js';
12
+ export { prepareStringToBeValidFilename, generateUniqueFilenameWithoutExtension, } from './filenameUtils.js';
13
+ export { findNavGroup, DEFAULT_API_GROUP_NAME, DEFAULT_WEBSOCKETS_GROUP_NAME, } from './findNavGroup.js';
14
+ export { generateOpenApiPages, buildGeneratedMdxContent, } from './generateOpenApiPages.js';