@mintlify/prebuild 1.0.404 → 1.0.405

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,8 +1,10 @@
1
+ import { AsyncAPIFile } from '@mintlify/common/asyncapi';
1
2
  import { OpenApiFile } from '@mintlify/models';
2
3
  export declare const categorizeFilePaths: (contentDirectoryPath: string) => Promise<{
3
4
  contentFilenames: string[];
4
5
  staticFilenames: string[];
5
6
  openApiFiles: OpenApiFile[];
7
+ asyncApiFiles: AsyncAPIFile[];
6
8
  snippets: string[];
7
9
  snippetsV2: string[];
8
10
  }>;
@@ -1,4 +1,5 @@
1
1
  import { openApiCheck } from '@mintlify/common';
2
+ import { asyncApiCheck } from '@mintlify/common/asyncapi';
2
3
  import { readFile } from 'fs/promises';
3
4
  import yaml from 'js-yaml';
4
5
  import * as path from 'path';
@@ -9,6 +10,7 @@ export const categorizeFilePaths = async (contentDirectoryPath) => {
9
10
  const contentFilenames = [];
10
11
  const staticFilenames = [];
11
12
  const openApiFiles = [];
13
+ const asyncApiFiles = [];
12
14
  const snippets = [];
13
15
  const snippetsV2 = [];
14
16
  for await (const filename of allFilesInCmdExecutionPath) {
@@ -33,20 +35,31 @@ export const categorizeFilePaths = async (contentDirectoryPath) => {
33
35
  // we need to read from the fs so we can store the original spec
34
36
  const str = await readFile(path.join(contentDirectoryPath, filename), 'utf8');
35
37
  const obj = yaml.load(str);
36
- if (!(await openApiCheck(obj)))
38
+ const isOpenApi = await openApiCheck(obj);
39
+ const isAsyncApi = await asyncApiCheck(obj);
40
+ if (!isOpenApi && !isAsyncApi)
37
41
  break;
38
42
  const fileName = path.parse(filename).name;
39
- openApiFiles.push({
40
- filename: fileName,
41
- spec: obj,
42
- originalFileLocation: filename,
43
- });
43
+ if (isOpenApi) {
44
+ openApiFiles.push({
45
+ filename: fileName,
46
+ spec: obj,
47
+ originalFileLocation: filename,
48
+ });
49
+ }
50
+ if (isAsyncApi) {
51
+ asyncApiFiles.push({
52
+ filename: fileName,
53
+ spec: obj,
54
+ originalFileLocation: filename,
55
+ });
56
+ }
44
57
  }
45
- catch { } // not an openapi spec
58
+ catch { }
46
59
  break;
47
60
  default:
48
61
  staticFilenames.push(filename);
49
62
  }
50
63
  }
51
- return { contentFilenames, staticFilenames, openApiFiles, snippets, snippetsV2 };
64
+ return { contentFilenames, staticFilenames, openApiFiles, asyncApiFiles, snippets, snippetsV2 };
52
65
  };
@@ -11,8 +11,17 @@ export const prebuild = async (contentDirectoryPath) => {
11
11
  if (mintConfigPath == null && docsConfigPath == null) {
12
12
  throw Error('Must be run in a directory where a mint.json or docs.json file exists.');
13
13
  }
14
- const { contentFilenames, staticFilenames, openApiFiles, snippets, snippetsV2 } = await categorizeFilePaths(contentDirectoryPath);
15
- await update(contentDirectoryPath, staticFilenames, openApiFiles, contentFilenames, snippets, snippetsV2, docsConfigPath);
14
+ const { contentFilenames, staticFilenames, openApiFiles, asyncApiFiles, snippets, snippetsV2 } = await categorizeFilePaths(contentDirectoryPath);
15
+ await update({
16
+ contentDirectoryPath,
17
+ staticFilenames,
18
+ openApiFiles,
19
+ asyncApiFiles,
20
+ contentFilenames,
21
+ snippets,
22
+ snippetV2Filenames: snippetsV2,
23
+ docsConfigPath,
24
+ });
16
25
  };
17
26
  export * from './categorizeFilePaths.js';
18
27
  export * from '../createPage/index.js';
@@ -1,15 +1,7 @@
1
1
  import type { OpenApiFile, DecoratedNavigationPage } from '@mintlify/models';
2
- import { DocsConfig, NavigationConfig } from '@mintlify/validation';
2
+ import { DocsConfig } from '@mintlify/validation';
3
3
  export declare const generateOpenApiDivisions: (docsConfig: DocsConfig, openApiFiles: OpenApiFile[], targetDir?: string) => Promise<{
4
4
  newDocsConfig: DocsConfig;
5
5
  pagesAcc: Record<string, DecoratedNavigationPage>;
6
6
  openApiFiles: OpenApiFile[];
7
7
  }>;
8
- export declare const generateOpenApiFromDocsConfig: (navigation: NavigationConfig, openApiFiles: OpenApiFile[], pagesAcc: Record<string, DecoratedNavigationPage>, opts: {
9
- overwrite?: boolean;
10
- writeFiles: boolean;
11
- targetDir?: string;
12
- }) => Promise<{
13
- newNav: NavigationConfig;
14
- newOpenApiFiles: OpenApiFile[];
15
- }>;
@@ -1,9 +1,5 @@
1
- import { getOpenApiDocumentFromUrl, optionallyAddLeadingSlash } from '@mintlify/common';
2
- import { generateOpenApiPagesForDocsConfig } from '@mintlify/scraping';
3
- import { divisions, } from '@mintlify/validation';
4
- import * as path from 'path';
5
1
  import { getOpenApiFilesFromConfig } from '../read/getOpenApiFilesFromConfig.js';
6
- const DEFAULT_OUTPUT_DIR = 'api-reference';
2
+ import { generateOpenApiFromDocsConfig } from './generateOpenApiFromDocsConfig.js';
7
3
  export const generateOpenApiDivisions = async (docsConfig, openApiFiles, targetDir) => {
8
4
  const openapiFilesFromDocsConfig = await getOpenApiFilesFromConfig('docs', docsConfig);
9
5
  openApiFiles.push(...openapiFilesFromDocsConfig);
@@ -19,125 +15,3 @@ export const generateOpenApiDivisions = async (docsConfig, openApiFiles, targetD
19
15
  openApiFiles: [...openApiFiles, ...newOpenApiFiles],
20
16
  };
21
17
  };
22
- export const generateOpenApiFromDocsConfig = async (navigation, openApiFiles, pagesAcc, opts) => {
23
- const { overwrite, writeFiles, targetDir } = opts;
24
- const newOpenApiFiles = [];
25
- async function processOpenApiInNav(nav) {
26
- let outputDir = DEFAULT_OUTPUT_DIR;
27
- let openapi;
28
- if ('openapi' in nav) {
29
- if (typeof nav.openapi === 'string') {
30
- openapi = nav.openapi;
31
- }
32
- else if (Array.isArray(nav.openapi) && nav.openapi.length > 0) {
33
- // TODO: handle multiple openapi files
34
- openapi = nav.openapi[0];
35
- }
36
- else if (typeof nav.openapi === 'object' && 'source' in nav.openapi) {
37
- openapi = nav.openapi.source;
38
- outputDir = nav.openapi.directory ?? DEFAULT_OUTPUT_DIR;
39
- }
40
- }
41
- if (openapi) {
42
- let openApiFile = undefined;
43
- if (openapi.startsWith('https')) {
44
- openApiFile = await createOpenApiFile(openapi, getDivisionNav(nav)?.division ?? 'unknown');
45
- openApiFile.filename = `${openApiFile.filename}-${newOpenApiFiles.length}`;
46
- newOpenApiFiles.push(openApiFile);
47
- }
48
- else {
49
- openApiFile = openApiFiles.find((file) => file.originalFileLocation != undefined &&
50
- file.originalFileLocation === optionallyAddLeadingSlash(openapi));
51
- }
52
- if (!openApiFile) {
53
- throw new Error(`Openapi file ${openapi} defined in ${getDivisionNav(nav)
54
- ?.division} in your docs.json does not exist`);
55
- }
56
- const { pagesAcc: pagesAccFromGeneratedOpenApiPages, nav: navFromGeneratedOpenApiPages } = await generateOpenApiPagesForDocsConfig(openApiFile.spec, {
57
- openApiFilePath: openApiFile.originalFileLocation,
58
- writeFiles,
59
- outDir: outputDir,
60
- outDirBasePath: path.join(targetDir ?? '', 'src', '_props'),
61
- overwrite,
62
- });
63
- Object.entries(pagesAccFromGeneratedOpenApiPages).forEach(([key, value]) => {
64
- pagesAcc[key] = value;
65
- });
66
- const divisionNav = getDivisionNav(nav);
67
- if (divisionNav?.division) {
68
- return {
69
- [divisionNav.division]: divisionNav.name,
70
- ...divisionNav.nav,
71
- ...(divisionNav.division === 'group'
72
- ? {
73
- pages: 'pages' in nav
74
- ? [...nav.pages, ...navFromGeneratedOpenApiPages]
75
- : navFromGeneratedOpenApiPages,
76
- }
77
- : {
78
- groups: 'groups' in nav
79
- ? [...nav.groups, ...navFromGeneratedOpenApiPages]
80
- : navFromGeneratedOpenApiPages,
81
- }),
82
- };
83
- }
84
- }
85
- return null;
86
- }
87
- async function processNav(nav) {
88
- const processedNav = await processOpenApiInNav(nav);
89
- if (processedNav) {
90
- return processedNav;
91
- }
92
- let newNav = { ...nav };
93
- for (const division of ['groups', ...divisions]) {
94
- if (division in newNav) {
95
- const items = newNav[division];
96
- newNav = {
97
- ...newNav,
98
- [division]: await Promise.all(items.map((item) => processNav(item))),
99
- };
100
- }
101
- }
102
- return newNav;
103
- }
104
- const processedNavigation = await processNav(navigation);
105
- navigation = processedNavigation;
106
- return {
107
- newNav: processedNavigation,
108
- newOpenApiFiles,
109
- };
110
- };
111
- function getDivisionNav(nav) {
112
- if ('openapi' in nav) {
113
- const { openapi: _, ...updatedNav } = nav;
114
- const divisionMap = {
115
- group: 'group',
116
- anchor: 'anchor',
117
- tab: 'tab',
118
- version: 'version',
119
- language: 'language',
120
- dropdown: 'dropdown',
121
- };
122
- const divisionType = Object.keys(divisionMap).find((key) => key in updatedNav);
123
- return {
124
- division: divisionMap[divisionType],
125
- name: updatedNav[divisionType],
126
- nav: updatedNav,
127
- };
128
- }
129
- return undefined;
130
- }
131
- async function createOpenApiFile(openApiUrl, division) {
132
- try {
133
- const document = await getOpenApiDocumentFromUrl(openApiUrl);
134
- return {
135
- filename: `openapi-from-${division}`,
136
- spec: document,
137
- };
138
- }
139
- catch (err) {
140
- console.error(err);
141
- throw err;
142
- }
143
- }
@@ -0,0 +1,10 @@
1
+ import type { OpenApiFile, DecoratedNavigationPage } from '@mintlify/models';
2
+ import { NavigationConfig } from '@mintlify/validation';
3
+ export declare const generateOpenApiFromDocsConfig: (navigation: NavigationConfig, openApiFiles: OpenApiFile[], pagesAcc: Record<string, DecoratedNavigationPage>, opts: {
4
+ overwrite?: boolean;
5
+ writeFiles: boolean;
6
+ targetDir?: string;
7
+ }) => Promise<{
8
+ newNav: NavigationConfig;
9
+ newOpenApiFiles: OpenApiFile[];
10
+ }>;
@@ -0,0 +1,127 @@
1
+ import { getOpenApiDocumentFromUrl, optionallyAddLeadingSlash } from '@mintlify/common';
2
+ import { generateOpenApiPagesForDocsConfig } from '@mintlify/scraping';
3
+ import { divisions } from '@mintlify/validation';
4
+ import * as path from 'path';
5
+ const DEFAULT_OUTPUT_DIR = 'api-reference';
6
+ export const generateOpenApiFromDocsConfig = async (navigation, openApiFiles, pagesAcc, opts) => {
7
+ const { overwrite, writeFiles, targetDir } = opts;
8
+ const newOpenApiFiles = [];
9
+ async function processOpenApiInNav(nav) {
10
+ let outputDir = DEFAULT_OUTPUT_DIR;
11
+ let openapi;
12
+ if ('openapi' in nav) {
13
+ if (typeof nav.openapi === 'string') {
14
+ openapi = nav.openapi;
15
+ }
16
+ else if (Array.isArray(nav.openapi) && nav.openapi.length > 0) {
17
+ // TODO: handle multiple openapi files
18
+ openapi = nav.openapi[0];
19
+ }
20
+ else if (typeof nav.openapi === 'object' && 'source' in nav.openapi) {
21
+ openapi = nav.openapi.source;
22
+ outputDir = nav.openapi.directory ?? DEFAULT_OUTPUT_DIR;
23
+ }
24
+ }
25
+ if (openapi) {
26
+ let openApiFile = undefined;
27
+ if (openapi.startsWith('https')) {
28
+ openApiFile = await createOpenApiFile(openapi, getDivisionNav(nav)?.division ?? 'unknown');
29
+ openApiFile.filename = `${openApiFile.filename}-${newOpenApiFiles.length}`;
30
+ newOpenApiFiles.push(openApiFile);
31
+ }
32
+ else {
33
+ openApiFile = openApiFiles.find((file) => file.originalFileLocation != undefined &&
34
+ file.originalFileLocation === optionallyAddLeadingSlash(openapi));
35
+ }
36
+ if (!openApiFile) {
37
+ throw new Error(`Openapi file ${openapi} defined in ${getDivisionNav(nav)
38
+ ?.division} in your docs.json does not exist`);
39
+ }
40
+ const { pagesAcc: pagesAccFromGeneratedOpenApiPages, nav: navFromGeneratedOpenApiPages } = await generateOpenApiPagesForDocsConfig(openApiFile.spec, {
41
+ openApiFilePath: openApiFile.originalFileLocation,
42
+ writeFiles,
43
+ outDir: outputDir,
44
+ outDirBasePath: path.join(targetDir ?? '', 'src', '_props'),
45
+ overwrite,
46
+ });
47
+ Object.entries(pagesAccFromGeneratedOpenApiPages).forEach(([key, value]) => {
48
+ pagesAcc[key] = value;
49
+ });
50
+ const divisionNav = getDivisionNav(nav);
51
+ if (divisionNav?.division) {
52
+ return {
53
+ [divisionNav.division]: divisionNav.name,
54
+ ...divisionNav.nav,
55
+ ...(divisionNav.division === 'group'
56
+ ? {
57
+ pages: 'pages' in nav
58
+ ? [...nav.pages, ...navFromGeneratedOpenApiPages]
59
+ : navFromGeneratedOpenApiPages,
60
+ }
61
+ : {
62
+ groups: 'groups' in nav
63
+ ? [...nav.groups, ...navFromGeneratedOpenApiPages]
64
+ : navFromGeneratedOpenApiPages,
65
+ }),
66
+ };
67
+ }
68
+ }
69
+ return null;
70
+ }
71
+ async function processNav(nav) {
72
+ const processedNav = await processOpenApiInNav(nav);
73
+ if (processedNav) {
74
+ return processedNav;
75
+ }
76
+ let newNav = { ...nav };
77
+ for (const division of ['groups', ...divisions]) {
78
+ if (division in newNav) {
79
+ const items = newNav[division];
80
+ newNav = {
81
+ ...newNav,
82
+ [division]: await Promise.all(items.map((item) => processNav(item))),
83
+ };
84
+ }
85
+ }
86
+ return newNav;
87
+ }
88
+ const processedNavigation = await processNav(navigation);
89
+ navigation = processedNavigation;
90
+ return {
91
+ newNav: processedNavigation,
92
+ newOpenApiFiles,
93
+ };
94
+ };
95
+ function getDivisionNav(nav) {
96
+ if ('openapi' in nav) {
97
+ const { openapi: _, ...updatedNav } = nav;
98
+ const divisionMap = {
99
+ group: 'group',
100
+ anchor: 'anchor',
101
+ tab: 'tab',
102
+ version: 'version',
103
+ language: 'language',
104
+ dropdown: 'dropdown',
105
+ };
106
+ const divisionType = Object.keys(divisionMap).find((key) => key in updatedNav);
107
+ return {
108
+ division: divisionMap[divisionType],
109
+ name: updatedNav[divisionType],
110
+ nav: updatedNav,
111
+ };
112
+ }
113
+ return undefined;
114
+ }
115
+ async function createOpenApiFile(openApiUrl, division) {
116
+ try {
117
+ const document = await getOpenApiDocumentFromUrl(openApiUrl);
118
+ return {
119
+ filename: `openapi-from-${division}`,
120
+ spec: document,
121
+ };
122
+ }
123
+ catch (err) {
124
+ console.error(err);
125
+ throw err;
126
+ }
127
+ }
@@ -1,8 +1,10 @@
1
+ import { AsyncAPIFile } from '@mintlify/common/asyncapi';
1
2
  import { OpenApiFile, DecoratedNavigationPage } from '@mintlify/models';
2
3
  import { DocsConfig } from '@mintlify/validation';
3
- export declare function updateDocsConfigFile(contentDirectoryPath: string, openApiFiles: OpenApiFile[], docsConfig?: DocsConfig): Promise<{
4
+ export declare function updateDocsConfigFile(contentDirectoryPath: string, openApiFiles: OpenApiFile[], _asyncApiFiles: AsyncAPIFile[], docsConfig?: DocsConfig): Promise<{
4
5
  docsConfig: DocsConfig;
5
6
  pagesAcc: Record<string, DecoratedNavigationPage>;
6
7
  newOpenApiFiles: OpenApiFile[];
7
8
  }>;
8
- export { generateOpenApiDivisions, generateOpenApiFromDocsConfig, } from './generateOpenApiDivisions.js';
9
+ export { generateOpenApiDivisions } from './generateOpenApiDivisions.js';
10
+ export { generateOpenApiFromDocsConfig } from './generateOpenApiFromDocsConfig.js';
@@ -1,7 +1,7 @@
1
1
  import { getConfigPath } from '../../../utils.js';
2
2
  import { DocsConfigUpdater } from '../ConfigUpdater.js';
3
3
  import { generateOpenApiDivisions } from './generateOpenApiDivisions.js';
4
- export async function updateDocsConfigFile(contentDirectoryPath, openApiFiles, docsConfig) {
4
+ export async function updateDocsConfigFile(contentDirectoryPath, openApiFiles, _asyncApiFiles, docsConfig) {
5
5
  const configPath = await getConfigPath(contentDirectoryPath, 'docs');
6
6
  if (configPath == null && docsConfig == null) {
7
7
  throw Error('Must be run in a directory where a docs.json file exists.');
@@ -16,4 +16,5 @@ export async function updateDocsConfigFile(contentDirectoryPath, openApiFiles, d
16
16
  await DocsConfigUpdater.writeConfigFile(newDocsConfig);
17
17
  return { docsConfig: newDocsConfig, pagesAcc, newOpenApiFiles };
18
18
  }
19
- export { generateOpenApiDivisions, generateOpenApiFromDocsConfig, } from './generateOpenApiDivisions.js';
19
+ export { generateOpenApiDivisions } from './generateOpenApiDivisions.js';
20
+ export { generateOpenApiFromDocsConfig } from './generateOpenApiFromDocsConfig.js';
@@ -1,5 +1,16 @@
1
+ import { AsyncAPIFile } from '@mintlify/common/asyncapi';
1
2
  import type { OpenApiFile } from '@mintlify/models';
2
- export declare const update: (contentDirectoryPath: string, staticFilenames: string[], openApiFiles: OpenApiFile[], contentFilenames: string[], snippets: string[], snippetV2Filenames: string[], docsConfigPath?: string | null) => Promise<{
3
+ type UpdateArgs = {
4
+ contentDirectoryPath: string;
5
+ staticFilenames: string[];
6
+ openApiFiles: OpenApiFile[];
7
+ asyncApiFiles: AsyncAPIFile[];
8
+ contentFilenames: string[];
9
+ snippets: string[];
10
+ snippetV2Filenames: string[];
11
+ docsConfigPath?: string | null;
12
+ };
13
+ export declare const update: ({ contentDirectoryPath, staticFilenames, openApiFiles, asyncApiFiles, contentFilenames, snippets, snippetV2Filenames, docsConfigPath, }: UpdateArgs) => Promise<{
3
14
  name: string;
4
15
  $schema: string;
5
16
  theme: "mint";
@@ -8,12 +8,12 @@ import { updateFavicons } from './updateFavicons.js';
8
8
  import { updateGeneratedDocsNav, updateGeneratedNav } from './updateGeneratedNav.js';
9
9
  import { writeFiles } from './write/writeFiles.js';
10
10
  import { writeOpenApiFiles } from './write/writeOpenApiFiles.js';
11
- export const update = async (contentDirectoryPath, staticFilenames, openApiFiles, contentFilenames, snippets, snippetV2Filenames, docsConfigPath) => {
11
+ export const update = async ({ contentDirectoryPath, staticFilenames, openApiFiles, asyncApiFiles, contentFilenames, snippets, snippetV2Filenames, docsConfigPath, }) => {
12
12
  const mintConfigResult = await updateMintConfigFile(contentDirectoryPath, openApiFiles);
13
13
  // we used the original mint config without openapi pages injected
14
14
  // because we will do it in `updateDocsConfigFile`, this will avoid duplicated openapi pages
15
15
  const docsConfig = mintConfigResult != null ? upgradeToDocsConfig(mintConfigResult.originalMintConfig) : undefined;
16
- const { docsConfig: newDocsConfig, pagesAcc, newOpenApiFiles, } = await updateDocsConfigFile(contentDirectoryPath, openApiFiles, docsConfigPath ? undefined : docsConfig);
16
+ const { docsConfig: newDocsConfig, pagesAcc, newOpenApiFiles, } = await updateDocsConfigFile(contentDirectoryPath, openApiFiles, asyncApiFiles, docsConfigPath ? undefined : docsConfig);
17
17
  const pagePromises = readPageContents(contentDirectoryPath, newOpenApiFiles, contentFilenames, pagesAcc);
18
18
  const snippetV2Promises = readSnippetsV2Contents(contentDirectoryPath, snippetV2Filenames);
19
19
  const [snippetV2Contents, { mdxFilesWithNoImports, filesWithImports }] = await Promise.all([