mintlify 2.1.0 → 3.0.4

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.
Files changed (165) hide show
  1. package/CONTRIBUTING.md +2 -16
  2. package/index.js +3 -0
  3. package/package.json +23 -46
  4. package/bin/browser.js +0 -24
  5. package/bin/browser.js.map +0 -1
  6. package/bin/constants.js +0 -32
  7. package/bin/constants.js.map +0 -1
  8. package/bin/downloadImage.js +0 -85
  9. package/bin/downloadImage.js.map +0 -1
  10. package/bin/index.js +0 -49
  11. package/bin/index.js.map +0 -1
  12. package/bin/local-preview/helper-commands/installDepsCommand.js +0 -12
  13. package/bin/local-preview/helper-commands/installDepsCommand.js.map +0 -1
  14. package/bin/local-preview/index.js +0 -154
  15. package/bin/local-preview/index.js.map +0 -1
  16. package/bin/local-preview/listener/categorize.js +0 -95
  17. package/bin/local-preview/listener/categorize.js.map +0 -1
  18. package/bin/local-preview/listener/categorizeFiles.js +0 -47
  19. package/bin/local-preview/listener/categorizeFiles.js.map +0 -1
  20. package/bin/local-preview/listener/generate.js +0 -89
  21. package/bin/local-preview/listener/generate.js.map +0 -1
  22. package/bin/local-preview/listener/index.js +0 -200
  23. package/bin/local-preview/listener/index.js.map +0 -1
  24. package/bin/local-preview/listener/update.js +0 -24
  25. package/bin/local-preview/listener/update.js.map +0 -1
  26. package/bin/local-preview/listener/utils/createPage.js +0 -167
  27. package/bin/local-preview/listener/utils/createPage.js.map +0 -1
  28. package/bin/local-preview/listener/utils/fileIsMdxOrMd.js +0 -12
  29. package/bin/local-preview/listener/utils/fileIsMdxOrMd.js.map +0 -1
  30. package/bin/local-preview/listener/utils/getOpenApiContext.js +0 -57
  31. package/bin/local-preview/listener/utils/getOpenApiContext.js.map +0 -1
  32. package/bin/local-preview/listener/utils/mintConfigFile.js +0 -22
  33. package/bin/local-preview/listener/utils/mintConfigFile.js.map +0 -1
  34. package/bin/local-preview/listener/utils/toTitleCase.js +0 -36
  35. package/bin/local-preview/listener/utils/toTitleCase.js.map +0 -1
  36. package/bin/local-preview/listener/utils/types.js +0 -2
  37. package/bin/local-preview/listener/utils/types.js.map +0 -1
  38. package/bin/local-preview/listener/utils.js +0 -67
  39. package/bin/local-preview/listener/utils.js.map +0 -1
  40. package/bin/local-preview/utils/categorizeFiles.js +0 -63
  41. package/bin/local-preview/utils/categorizeFiles.js.map +0 -1
  42. package/bin/local-preview/utils/getOpenApiContext.js +0 -58
  43. package/bin/local-preview/utils/getOpenApiContext.js.map +0 -1
  44. package/bin/local-preview/utils/injectFavicons.js +0 -72
  45. package/bin/local-preview/utils/injectFavicons.js.map +0 -1
  46. package/bin/local-preview/utils/listener.js +0 -116
  47. package/bin/local-preview/utils/listener.js.map +0 -1
  48. package/bin/local-preview/utils/metadata.js +0 -118
  49. package/bin/local-preview/utils/metadata.js.map +0 -1
  50. package/bin/local-preview/utils/mintConfigFile.js +0 -43
  51. package/bin/local-preview/utils/mintConfigFile.js.map +0 -1
  52. package/bin/local-preview/utils/openApiCheck.js +0 -15
  53. package/bin/local-preview/utils/openApiCheck.js.map +0 -1
  54. package/bin/local-preview/utils/slugToTitle.js +0 -8
  55. package/bin/local-preview/utils/slugToTitle.js.map +0 -1
  56. package/bin/navigation.js +0 -4
  57. package/bin/navigation.js.map +0 -1
  58. package/bin/pageTemplate.js +0 -30
  59. package/bin/pageTemplate.js.map +0 -1
  60. package/bin/scraping/combineNavWithEmptyGroupTitles.js +0 -20
  61. package/bin/scraping/combineNavWithEmptyGroupTitles.js.map +0 -1
  62. package/bin/scraping/detectFramework.js +0 -39
  63. package/bin/scraping/detectFramework.js.map +0 -1
  64. package/bin/scraping/downloadAllImages.js +0 -33
  65. package/bin/scraping/downloadAllImages.js.map +0 -1
  66. package/bin/scraping/downloadLogoImage.js +0 -13
  67. package/bin/scraping/downloadLogoImage.js.map +0 -1
  68. package/bin/scraping/getSitemapLinks.js +0 -18
  69. package/bin/scraping/getSitemapLinks.js.map +0 -1
  70. package/bin/scraping/replaceImagePaths.js +0 -17
  71. package/bin/scraping/replaceImagePaths.js.map +0 -1
  72. package/bin/scraping/scrapeFileGettingFileNameFromUrl.js +0 -43
  73. package/bin/scraping/scrapeFileGettingFileNameFromUrl.js.map +0 -1
  74. package/bin/scraping/scrapeGettingFileNameFromUrl.js +0 -13
  75. package/bin/scraping/scrapeGettingFileNameFromUrl.js.map +0 -1
  76. package/bin/scraping/scrapePage.js +0 -10
  77. package/bin/scraping/scrapePage.js.map +0 -1
  78. package/bin/scraping/scrapePageCommands.js +0 -55
  79. package/bin/scraping/scrapePageCommands.js.map +0 -1
  80. package/bin/scraping/scrapeSection.js +0 -12
  81. package/bin/scraping/scrapeSection.js.map +0 -1
  82. package/bin/scraping/scrapeSectionCommands.js +0 -66
  83. package/bin/scraping/scrapeSectionCommands.js.map +0 -1
  84. package/bin/scraping/site-scrapers/Intercom/scrapeIntercomPage.js +0 -27
  85. package/bin/scraping/site-scrapers/Intercom/scrapeIntercomPage.js.map +0 -1
  86. package/bin/scraping/site-scrapers/Intercom/scrapeIntercomSection.js +0 -32
  87. package/bin/scraping/site-scrapers/Intercom/scrapeIntercomSection.js.map +0 -1
  88. package/bin/scraping/site-scrapers/alternateGroupTitle.js +0 -9
  89. package/bin/scraping/site-scrapers/alternateGroupTitle.js.map +0 -1
  90. package/bin/scraping/site-scrapers/links-per-group/getDocusaurusLinksPerGroup.js +0 -34
  91. package/bin/scraping/site-scrapers/links-per-group/getDocusaurusLinksPerGroup.js.map +0 -1
  92. package/bin/scraping/site-scrapers/links-per-group/getLinksRecursively.js +0 -38
  93. package/bin/scraping/site-scrapers/links-per-group/getLinksRecursively.js.map +0 -1
  94. package/bin/scraping/site-scrapers/links-per-group/getLinksRecursivelyGitBook.js +0 -38
  95. package/bin/scraping/site-scrapers/links-per-group/getLinksRecursivelyGitBook.js.map +0 -1
  96. package/bin/scraping/site-scrapers/openNestedDocusaurusMenus.js +0 -30
  97. package/bin/scraping/site-scrapers/openNestedDocusaurusMenus.js.map +0 -1
  98. package/bin/scraping/site-scrapers/openNestedGitbookMenus.js +0 -17
  99. package/bin/scraping/site-scrapers/openNestedGitbookMenus.js.map +0 -1
  100. package/bin/scraping/site-scrapers/scrapeDocusaurusPage.js +0 -49
  101. package/bin/scraping/site-scrapers/scrapeDocusaurusPage.js.map +0 -1
  102. package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js +0 -30
  103. package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js.map +0 -1
  104. package/bin/scraping/site-scrapers/scrapeGitBookPage.js +0 -47
  105. package/bin/scraping/site-scrapers/scrapeGitBookPage.js.map +0 -1
  106. package/bin/scraping/site-scrapers/scrapeGitBookSection.js +0 -52
  107. package/bin/scraping/site-scrapers/scrapeGitBookSection.js.map +0 -1
  108. package/bin/scraping/site-scrapers/scrapeReadMePage.js +0 -36
  109. package/bin/scraping/site-scrapers/scrapeReadMePage.js.map +0 -1
  110. package/bin/scraping/site-scrapers/scrapeReadMeSection.js +0 -44
  111. package/bin/scraping/site-scrapers/scrapeReadMeSection.js.map +0 -1
  112. package/bin/util.js +0 -129
  113. package/bin/util.js.map +0 -1
  114. package/bin/validation/isValidLink.js +0 -11
  115. package/bin/validation/isValidLink.js.map +0 -1
  116. package/bin/validation/stopIfInvalidLink.js +0 -9
  117. package/bin/validation/stopIfInvalidLink.js.map +0 -1
  118. package/scraper.md +0 -121
  119. package/src/browser.ts +0 -24
  120. package/src/constants.ts +0 -40
  121. package/src/downloadImage.ts +0 -110
  122. package/src/index.ts +0 -112
  123. package/src/local-preview/helper-commands/installDepsCommand.ts +0 -13
  124. package/src/local-preview/index.ts +0 -195
  125. package/src/local-preview/listener/categorize.ts +0 -105
  126. package/src/local-preview/listener/generate.ts +0 -110
  127. package/src/local-preview/listener/index.ts +0 -228
  128. package/src/local-preview/listener/update.ts +0 -27
  129. package/src/local-preview/listener/utils/createPage.ts +0 -211
  130. package/src/local-preview/listener/utils/getOpenApiContext.ts +0 -77
  131. package/src/local-preview/listener/utils/mintConfigFile.ts +0 -28
  132. package/src/local-preview/listener/utils/toTitleCase.ts +0 -40
  133. package/src/local-preview/listener/utils/types.ts +0 -16
  134. package/src/local-preview/listener/utils.ts +0 -78
  135. package/src/scraping/combineNavWithEmptyGroupTitles.ts +0 -21
  136. package/src/scraping/detectFramework.ts +0 -47
  137. package/src/scraping/downloadAllImages.ts +0 -60
  138. package/src/scraping/downloadLogoImage.ts +0 -25
  139. package/src/scraping/getSitemapLinks.ts +0 -18
  140. package/src/scraping/replaceImagePaths.ts +0 -21
  141. package/src/scraping/scrapeFileGettingFileNameFromUrl.ts +0 -86
  142. package/src/scraping/scrapeGettingFileNameFromUrl.ts +0 -54
  143. package/src/scraping/scrapePage.ts +0 -24
  144. package/src/scraping/scrapePageCommands.ts +0 -66
  145. package/src/scraping/scrapeSection.ts +0 -28
  146. package/src/scraping/scrapeSectionCommands.ts +0 -110
  147. package/src/scraping/site-scrapers/Intercom/scrapeIntercomPage.ts +0 -51
  148. package/src/scraping/site-scrapers/Intercom/scrapeIntercomSection.ts +0 -53
  149. package/src/scraping/site-scrapers/alternateGroupTitle.ts +0 -8
  150. package/src/scraping/site-scrapers/links-per-group/getDocusaurusLinksPerGroup.ts +0 -44
  151. package/src/scraping/site-scrapers/links-per-group/getLinksRecursively.ts +0 -45
  152. package/src/scraping/site-scrapers/links-per-group/getLinksRecursivelyGitBook.ts +0 -46
  153. package/src/scraping/site-scrapers/openNestedDocusaurusMenus.ts +0 -42
  154. package/src/scraping/site-scrapers/openNestedGitbookMenus.ts +0 -24
  155. package/src/scraping/site-scrapers/scrapeDocusaurusPage.ts +0 -81
  156. package/src/scraping/site-scrapers/scrapeDocusaurusSection.ts +0 -63
  157. package/src/scraping/site-scrapers/scrapeGitBookPage.ts +0 -74
  158. package/src/scraping/site-scrapers/scrapeGitBookSection.ts +0 -80
  159. package/src/scraping/site-scrapers/scrapeReadMePage.ts +0 -60
  160. package/src/scraping/site-scrapers/scrapeReadMeSection.ts +0 -70
  161. package/src/types.d.ts +0 -29
  162. package/src/util.ts +0 -161
  163. package/src/validation/isValidLink.ts +0 -9
  164. package/src/validation/stopIfInvalidLink.ts +0 -9
  165. package/tsconfig.json +0 -18
@@ -1,105 +0,0 @@
1
- // TODO - put in prebuild package
2
- import path from "path";
3
-
4
- import { getFileExtension, openApiCheck, getFileList } from "./utils.js";
5
- import { PotentialFileCategory } from "./utils/types.js";
6
-
7
- export const categorizeFiles = async (contentDirectoryPath: string) => {
8
- const allFilesInCmdExecutionPath = await getFileList(contentDirectoryPath);
9
- const contentFilenames = [];
10
- const staticFilenames = [];
11
- const promises = [];
12
- const openApiFiles = [];
13
- const snippets = [];
14
- allFilesInCmdExecutionPath.forEach((filename) => {
15
- promises.push(
16
- (async () => {
17
- const extension = getFileExtension(filename);
18
- let isOpenApi = false;
19
- if (extension && (extension === "mdx" || extension === "md")) {
20
- if (filename.startsWith("/_snippets")) {
21
- snippets.push(filename);
22
- } else {
23
- contentFilenames.push(filename);
24
- }
25
- } else if (
26
- extension &&
27
- (extension === "json" || extension === "yaml" || extension === "yml")
28
- ) {
29
- const openApiInfo = await openApiCheck(
30
- path.join(contentDirectoryPath, filename)
31
- );
32
- isOpenApi = openApiInfo.isOpenApi;
33
- if (isOpenApi) {
34
- const fileName = path.parse(filename).base;
35
- openApiFiles.push({
36
- filename: fileName.substring(0, fileName.lastIndexOf(".")),
37
- spec: openApiInfo.spec,
38
- });
39
- }
40
- } else if (!filename.endsWith("mint.json") && !isOpenApi) {
41
- // all other files
42
- staticFilenames.push(filename);
43
- }
44
- })()
45
- );
46
- });
47
- await Promise.all(promises);
48
-
49
- return { contentFilenames, staticFilenames, openApiFiles, snippets };
50
- };
51
-
52
- const excludedMdFiles = ["readme", "license", "contributing", "contribute"];
53
-
54
- const supportedStaticFileExtensions = [
55
- ".jpeg",
56
- ".jpg",
57
- ".jfif",
58
- ".pjpeg",
59
- ".pjp",
60
- ".png",
61
- ".svg",
62
- ".svgz",
63
- ".ico",
64
- ".webp",
65
- ".gif",
66
- ".apng",
67
- ".avif",
68
- ".bmp",
69
- ".mp4",
70
- ];
71
-
72
- export const getCategory = (filePath: string): PotentialFileCategory => {
73
- filePath = filePath.toLowerCase();
74
-
75
- const parsed = path.parse(filePath);
76
-
77
- if (parsed.base === "mint.json") {
78
- return "mintConfig";
79
- }
80
-
81
- const fileName = parsed.name;
82
- const extension = parsed.ext;
83
- if (
84
- filePath.startsWith("_snippets") &&
85
- (extension === ".mdx" || extension === ".md")
86
- ) {
87
- return "snippet";
88
- } else if (extension === ".mdx") {
89
- return "page";
90
- } else if (extension === ".md") {
91
- // Exclude common markdown files people don't want on their docs website
92
- if (excludedMdFiles.includes(fileName)) {
93
- throw new Error("Excluded Md File");
94
- }
95
- return "page";
96
- } else if (extension === ".yaml" || extension === ".yml") {
97
- return "potentialYamlOpenApiSpec";
98
- } else if (extension === ".json") {
99
- return "potentialJsonOpenApiSpec";
100
- } else if (supportedStaticFileExtensions.includes(extension)) {
101
- return "staticFile";
102
- }
103
-
104
- throw new Error("Unsupported File Type, No change enacted");
105
- };
@@ -1,110 +0,0 @@
1
- // TODO - add types
2
- import { promises as _promises } from "fs";
3
- import { outputFile } from "fs-extra";
4
- import path from "path";
5
- import createPage from "./utils/createPage.js";
6
- import { OpenApiFile } from "./utils/types.js";
7
- import { categorizeFiles } from "./categorize.js";
8
- import { CMD_EXEC_PATH } from "../../constants.js";
9
- import { getConfigObj } from "./utils/mintConfigFile.js";
10
- const { readFile } = _promises;
11
-
12
- // TODO: Put in prebuild package
13
- const generateNavFromPages = (pages, mintConfigNav) => {
14
- const createNav = (nav) => {
15
- return {
16
- group: nav.group,
17
- version: nav.version,
18
- pages: nav.pages.map((page) => {
19
- if (typeof page === "string") {
20
- return pages[page];
21
- }
22
- return createNav(page);
23
- }),
24
- };
25
- };
26
-
27
- if (mintConfigNav == null) {
28
- return;
29
- }
30
-
31
- let navFile = mintConfigNav.map((nav) => createNav(nav));
32
- const filterOutNullInPages = (pages) => {
33
- const newPages = [];
34
- pages.forEach((page) => {
35
- if (page == null) {
36
- return;
37
- }
38
- if (page?.pages) {
39
- const newGroup = filterOutNullInGroup(page);
40
- newPages.push(newGroup);
41
- } else {
42
- newPages.push(page);
43
- }
44
- });
45
-
46
- return newPages;
47
- };
48
- const filterOutNullInGroup = (group) => {
49
- const newPages = filterOutNullInPages(group.pages);
50
- const newGroup = {
51
- ...group,
52
- pages: newPages,
53
- };
54
- return newGroup;
55
- };
56
- const newNavFile = navFile.map((group) => {
57
- return filterOutNullInGroup(group);
58
- });
59
- return newNavFile;
60
- };
61
-
62
- // TODO: Put in prebuild package
63
- const createPagesAcc = async (
64
- contentDirectoryPath: string,
65
- contentFilenames: string[],
66
- openApiFiles: OpenApiFile[],
67
- clientPath?: string,
68
- writeFiles = false
69
- ) => {
70
- let pagesAcc = {};
71
- const contentPromises = [];
72
- contentFilenames.forEach((filename) => {
73
- contentPromises.push(
74
- (async () => {
75
- const sourcePath = path.join(contentDirectoryPath, filename);
76
-
77
- const contentStr = (await readFile(sourcePath)).toString();
78
- const { slug, pageMetadata, pageContent } = await createPage(
79
- filename,
80
- contentStr,
81
- contentDirectoryPath,
82
- openApiFiles
83
- );
84
- if (clientPath && writeFiles) {
85
- const targetPath = path.join(clientPath, "src", "_props", filename);
86
- await outputFile(targetPath, pageContent, {
87
- flag: "w",
88
- });
89
- }
90
- pagesAcc = {
91
- ...pagesAcc,
92
- [slug]: pageMetadata,
93
- };
94
- })()
95
- );
96
- });
97
- await Promise.all(contentPromises);
98
- return pagesAcc;
99
- };
100
-
101
- export const generateNav = async () => {
102
- const { contentFilenames, openApiFiles } = await categorizeFiles(
103
- CMD_EXEC_PATH
104
- );
105
- const [pageAcc, configObj] = await Promise.all([
106
- createPagesAcc(CMD_EXEC_PATH, contentFilenames, openApiFiles),
107
- getConfigObj(CMD_EXEC_PATH),
108
- ]);
109
- return generateNavFromPages(pageAcc, configObj?.navigation);
110
- };
@@ -1,228 +0,0 @@
1
- import chokidar from "chokidar";
2
- import fse from "fs-extra";
3
- import pathUtil from "path";
4
- import Chalk from "chalk";
5
- import mintValidation from "@mintlify/validation";
6
- import { isFileSizeValid, openApiCheck } from "./utils.js";
7
- import { updateGeneratedNav, updateOpenApiFiles } from "./update.js";
8
- import { CLIENT_PATH, CMD_EXEC_PATH } from "../../constants.js";
9
- import { promises as _promises } from "fs";
10
- import createPage from "./utils/createPage.js";
11
- import { getCategory } from "./categorize.js";
12
- import { PotentialFileCategory, FileCategory } from "./utils/types.js";
13
-
14
- const { readFile } = _promises;
15
-
16
- const listener = () => {
17
- chokidar
18
- .watch(CMD_EXEC_PATH, {
19
- ignoreInitial: true,
20
- ignored: ["node_modules", ".git", ".idea"],
21
- cwd: CMD_EXEC_PATH,
22
- })
23
- .on("add", async (filename: string) => {
24
- try {
25
- const category = await onUpdateEvent(filename);
26
- switch (category) {
27
- case "page":
28
- console.log("New page detected: ", filename);
29
- break;
30
- case "snippet":
31
- console.log("New snippet detected: ", filename);
32
- break;
33
- case "mintConfig":
34
- console.log("Config added");
35
- break;
36
- case "openApi":
37
- console.log("OpenApi spec added: ", filename);
38
- break;
39
- case "staticFile":
40
- console.log("Static file added: ", filename);
41
- break;
42
- }
43
- } catch (error) {
44
- console.error(error.message);
45
- }
46
- })
47
- .on("change", async (filename: string) => {
48
- try {
49
- const category = await onUpdateEvent(filename);
50
- switch (category) {
51
- case "page":
52
- console.log("Page edited: ", filename);
53
- break;
54
- case "snippet":
55
- console.log("Snippet edited: ", filename);
56
- break;
57
- case "mintConfig":
58
- console.log("Config edited");
59
- break;
60
- case "openApi":
61
- console.log("OpenApi spec edited: ", filename);
62
- break;
63
- case "staticFile":
64
- console.log("Static file edited: ", filename);
65
- break;
66
- }
67
- } catch (error) {
68
- console.error(error.message);
69
- }
70
- })
71
- .on("unlink", async (filename: string) => {
72
- try {
73
- const potentialCategory = getCategory(filename);
74
- const targetPath = getTargetPath(potentialCategory, filename);
75
- if (
76
- potentialCategory === "page" ||
77
- potentialCategory === "snippet" ||
78
- potentialCategory === "mintConfig" ||
79
- potentialCategory === "staticFile"
80
- ) {
81
- await fse.remove(targetPath);
82
- }
83
- switch (potentialCategory) {
84
- case "page":
85
- console.log(`Page deleted: ${filename}`);
86
- break;
87
- case "snippet":
88
- console.log(`Snippet deleted: ${filename}`);
89
- break;
90
- case "mintConfig":
91
- console.log(
92
- "⚠️ mint.json deleted. Please create a new mint.json file as it is mandatory."
93
- );
94
- process.exit(1);
95
- case "potentialJsonOpenApiSpec":
96
- case "potentialYamlOpenApiSpec":
97
- await updateOpenApiFiles();
98
- await updateGeneratedNav();
99
- break;
100
- case "staticFile":
101
- console.log("Static file deleted: ", filename);
102
- break;
103
- }
104
- } catch (error) {
105
- console.error(error.message);
106
- }
107
- });
108
- };
109
-
110
- const getTargetPath = (
111
- potentialCategory: PotentialFileCategory,
112
- filePath: string
113
- ): string => {
114
- switch (potentialCategory) {
115
- case "page":
116
- case "snippet":
117
- return pathUtil.join(CLIENT_PATH, "src", "_props", filePath);
118
- case "mintConfig":
119
- return pathUtil.join(CLIENT_PATH, "src", "_props", "mint.json");
120
- case "potentialYamlOpenApiSpec":
121
- case "potentialJsonOpenApiSpec":
122
- return pathUtil.join(CLIENT_PATH, "src", "_props", "openApiFiles.json");
123
- case "staticFile":
124
- return pathUtil.join(CLIENT_PATH, "public", filePath);
125
- default:
126
- throw new Error("Invalid category");
127
- }
128
- };
129
-
130
- /**
131
- * This function is called when a file is added or changed
132
- * @param filename
133
- * @returns FileCategory
134
- */
135
- const onUpdateEvent = async (filename: string): Promise<FileCategory> => {
136
- const filePath = pathUtil.join(CMD_EXEC_PATH, filename);
137
- const potentialCategory = getCategory(filename);
138
- const targetPath = getTargetPath(potentialCategory, filename);
139
- let regenerateNav = false;
140
- let category: FileCategory =
141
- potentialCategory === "potentialYamlOpenApiSpec" ||
142
- potentialCategory === "potentialJsonOpenApiSpec"
143
- ? "staticFile"
144
- : potentialCategory;
145
-
146
- switch (potentialCategory) {
147
- case "page":
148
- regenerateNav = true;
149
-
150
- const contentStr = (await readFile(filePath)).toString();
151
- const { pageContent } = await createPage(
152
- filename,
153
- contentStr,
154
- CMD_EXEC_PATH,
155
- []
156
- );
157
- await fse.outputFile(targetPath, pageContent, {
158
- flag: "w",
159
- });
160
- break;
161
- case "snippet":
162
- await fse.copy(filePath, targetPath);
163
- break;
164
- case "mintConfig":
165
- regenerateNav = true;
166
-
167
- const mintJsonFileContent = (await readFile(filePath)).toString();
168
- try {
169
- const mintConfig = JSON.parse(mintJsonFileContent);
170
- const { status, errors, warnings } =
171
- mintValidation.validateMintConfig(mintConfig);
172
-
173
- errors.forEach((error) => {
174
- console.error(`🚨 ${Chalk.red(error)}`);
175
- });
176
-
177
- warnings.forEach((warning) => {
178
- console.warn(`⚠️ ${Chalk.yellow(warning)}`);
179
- });
180
-
181
- if (status === "success") {
182
- await fse.copy(filePath, targetPath);
183
- }
184
- } catch (error) {
185
- if (error.name === "SyntaxError") {
186
- console.error(
187
- `🚨 ${Chalk.red(
188
- "mint.json has invalid JSON. You are likely missing a comma or a bracket. You can paste your mint.json file into https://jsonlint.com/ to get a more specific error message."
189
- )}`
190
- );
191
- } else {
192
- console.error(`🚨 ${Chalk.red(error.message)}`);
193
- }
194
- }
195
-
196
- break;
197
- case "potentialYamlOpenApiSpec":
198
- case "potentialJsonOpenApiSpec":
199
- let isOpenApi = false;
200
- const openApiInfo = await openApiCheck(filePath);
201
- isOpenApi = openApiInfo.isOpenApi;
202
- if (isOpenApi) {
203
- // TODO: Instead of re-generating all openApi files, optimize by just updating the specific file that changed.
204
- await updateOpenApiFiles();
205
- regenerateNav = true;
206
- category = "openApi";
207
- }
208
- break;
209
- case "staticFile":
210
- if (await isFileSizeValid(filePath, 5)) {
211
- await fse.copy(filePath, targetPath);
212
- } else {
213
- console.error(
214
- Chalk.red(
215
- `🚨 The file at ${filename} is too big. The maximum file size is 5 mb.`
216
- )
217
- );
218
- }
219
- break;
220
- }
221
- if (regenerateNav) {
222
- // TODO: Instead of re-generating the entire nav, optimize by just updating the specific page that changed.
223
- await updateGeneratedNav();
224
- }
225
- return category;
226
- };
227
-
228
- export default listener;
@@ -1,27 +0,0 @@
1
- // TODO: Add Types
2
- import fse from "fs-extra";
3
- import { promises as _promises } from "fs";
4
- import { CLIENT_PATH, CMD_EXEC_PATH } from "../../constants.js";
5
- import { join } from "path";
6
- import { generateNav } from "./generate.js";
7
- import { categorizeFiles } from "./categorize.js";
8
-
9
- const { readFile } = _promises;
10
-
11
- // TODO: Put in prebuild package
12
-
13
- export const updateGeneratedNav = async () => {
14
- const generatedNav = await generateNav();
15
- const targetPath = join(CLIENT_PATH, "src", "_props", "generatedNav.json");
16
- await fse.outputFile(targetPath, JSON.stringify(generatedNav, null, 2), {
17
- flag: "w",
18
- });
19
- };
20
-
21
- export const updateOpenApiFiles = async () => {
22
- const { openApiFiles } = await categorizeFiles(CMD_EXEC_PATH);
23
- const targetPath = join(CLIENT_PATH, "src", "_props", "openApiFiles.json");
24
- await fse.outputFile(targetPath, JSON.stringify(openApiFiles, null, 2), {
25
- flag: "w",
26
- });
27
- };
@@ -1,211 +0,0 @@
1
- // TODO: Put in the prebuild package
2
- import matter from "gray-matter";
3
- import isAbsoluteUrl from "is-absolute-url";
4
- import { remark } from "remark";
5
- import remarkFrontmatter from "remark-frontmatter";
6
- import remarkGfm from "remark-gfm";
7
- import remarkMdx from "remark-mdx";
8
- import { visit } from "unist-util-visit";
9
- import type { OpenApiFile } from "./types.js";
10
-
11
- const createPage = async (
12
- pagePath: string,
13
- pageContent: string,
14
- contentDirectoryPath: string,
15
- openApiFiles: OpenApiFile[]
16
- ) => {
17
- let { data: metadata } = matter(pageContent);
18
- try {
19
- const parsedContent = await preParseMdx(pageContent, contentDirectoryPath);
20
- pageContent = parsedContent;
21
- } catch (error) {
22
- pageContent = `🚧 A parsing error occured. Please contact the owner of this website.`;
23
- }
24
-
25
- // Replace .mdx so we can pass file paths into this function
26
- const slug = pagePath.replace(/\.mdx?$/, "");
27
- let defaultTitle = slugToTitle(slug);
28
- // Append data from OpenAPI if it exists
29
- const { title, description } = getOpenApiTitleAndDescription(
30
- openApiFiles,
31
- metadata?.openapi
32
- );
33
-
34
- if (title) {
35
- defaultTitle = title;
36
- }
37
-
38
- const pageMetadata = {
39
- title: defaultTitle,
40
- description,
41
- ...metadata,
42
- href: optionallyAddLeadingSlash(slug),
43
- };
44
-
45
- return {
46
- pageMetadata,
47
- pageContent,
48
- slug: removeLeadingSlash(slug),
49
- };
50
- };
51
-
52
- const preParseMdx = async (fileContent, contentDirectoryPath) => {
53
- const removeContentDirectoryPath = (filePath) => {
54
- const pathArr = createPathArr(filePath);
55
- const contentDirectoryPathArr = createPathArr(contentDirectoryPath);
56
- contentDirectoryPathArr.reverse().forEach((dir, index) => {
57
- if (pathArr[index] === dir) {
58
- pathArr.pop();
59
- }
60
- });
61
- return "/" + pathArr.join("/");
62
- };
63
-
64
- const removeContentDirectoryPaths = () => {
65
- return (tree) => {
66
- visit(tree, (node) => {
67
- if (node == null) {
68
- return;
69
- }
70
- if (node.name === "img" || node.name === "source") {
71
- const srcAttrIndex = node.attributes.findIndex(
72
- (attr) => attr?.name === "src"
73
- );
74
- const nodeUrl = node.attributes[srcAttrIndex].value;
75
- if (
76
- // <img/> component
77
- srcAttrIndex !== -1 &&
78
- !isAbsoluteUrl(nodeUrl) &&
79
- !isDataString(nodeUrl)
80
- ) {
81
- node.attributes[srcAttrIndex].value =
82
- removeContentDirectoryPath(nodeUrl);
83
- }
84
- } else if (
85
- // ![]() format
86
- node.type === "image" &&
87
- node.url &&
88
- !isAbsoluteUrl(node.url) &&
89
- !isDataString(node.url)
90
- ) {
91
- node.url = removeContentDirectoryPath(node.url);
92
- }
93
- });
94
- return tree;
95
- };
96
- };
97
-
98
- const file = await remark()
99
- .use(remarkMdx)
100
- .use(remarkGfm)
101
- .use(remarkFrontmatter, ["yaml", "toml"])
102
- .use(removeContentDirectoryPaths)
103
- .process(fileContent);
104
- return String(file);
105
- };
106
-
107
- const removeLeadingSlash = (str) => {
108
- const path = createPathArr(str);
109
- return path.join("/");
110
- };
111
-
112
- const createPathArr = (path) => {
113
- return path.split("/").filter((dir) => dir !== "");
114
- };
115
-
116
- const isDataString = (str) => str.startsWith("data:");
117
-
118
- const getOpenApiTitleAndDescription = (openApiFiles, openApiMetaField) => {
119
- if (openApiFiles == null || !openApiMetaField || openApiMetaField == null) {
120
- return {};
121
- }
122
-
123
- const { operation } = getOpenApiOperationMethodAndEndpoint(
124
- openApiFiles,
125
- openApiMetaField
126
- );
127
-
128
- if (operation == null) {
129
- return {};
130
- }
131
-
132
- return {
133
- title: operation.summary,
134
- description: operation.description,
135
- };
136
- };
137
-
138
- const getOpenApiOperationMethodAndEndpoint = (
139
- openApiFiles,
140
- openApiMetaField
141
- ) => {
142
- const { endpoint, method, filename } =
143
- extractMethodAndEndpoint(openApiMetaField);
144
-
145
- let path;
146
-
147
- openApiFiles?.forEach((file) => {
148
- const openApiFile = file.spec;
149
- const openApiPath = openApiFile.paths && openApiFile.paths[endpoint];
150
- const isFilenameOrNone = !filename || filename === file.filename;
151
- if (openApiPath && isFilenameOrNone) {
152
- path = openApiPath;
153
- }
154
- });
155
-
156
- if (path == null) {
157
- return {};
158
- }
159
-
160
- let operation;
161
- if (method) {
162
- operation = path[method.toLowerCase()];
163
- } else {
164
- const firstOperationKey = Object.keys(path)[0];
165
- operation = path[firstOperationKey];
166
- }
167
-
168
- return {
169
- operation,
170
- method,
171
- endpoint,
172
- };
173
- };
174
-
175
- const extractMethodAndEndpoint = (openApiMetaField) => {
176
- const methodRegex = /(get|post|put|delete|patch)\s/i;
177
- const trimmed = openApiMetaField.trim();
178
- const foundMethod = trimmed.match(methodRegex);
179
-
180
- const startIndexOfMethod = foundMethod
181
- ? openApiMetaField.indexOf(foundMethod[0])
182
- : 0;
183
- const endIndexOfMethod = foundMethod
184
- ? startIndexOfMethod + foundMethod[0].length - 1
185
- : 0;
186
-
187
- const filename = openApiMetaField.substring(0, startIndexOfMethod).trim();
188
-
189
- return {
190
- method: foundMethod ? foundMethod[0].slice(0, -1).toUpperCase() : undefined,
191
- endpoint: openApiMetaField.substring(endIndexOfMethod).trim(),
192
- filename: filename ? filename : undefined,
193
- };
194
- };
195
-
196
- function optionallyAddLeadingSlash(path) {
197
- if (!path || path.startsWith("/")) {
198
- return path;
199
- }
200
- return "/" + path;
201
- }
202
-
203
- export const slugToTitle = (slug) => {
204
- const slugArr = slug.split("/");
205
- let defaultTitle = slugArr[slugArr.length - 1].split("-").join(" "); //replace all dashes
206
- defaultTitle = defaultTitle.split("_").join(" "); //replace all underscores
207
- defaultTitle = defaultTitle.charAt(0).toUpperCase() + defaultTitle.slice(1); //capitalize first letter
208
- return defaultTitle;
209
- };
210
-
211
- export default createPage;