mintlify 2.0.4 → 2.0.6

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 (100) hide show
  1. package/bin/constants.js +17 -0
  2. package/bin/constants.js.map +1 -1
  3. package/bin/downloadImage.js +47 -2
  4. package/bin/downloadImage.js.map +1 -1
  5. package/bin/index.js +5 -3
  6. package/bin/index.js.map +1 -1
  7. package/bin/local-preview/index.js +2 -1
  8. package/bin/local-preview/index.js.map +1 -1
  9. package/bin/local-preview/listener/{categorizeFiles.js → categorize.js} +53 -3
  10. package/bin/local-preview/listener/categorize.js.map +1 -0
  11. package/bin/local-preview/listener/generate.js +1 -1
  12. package/bin/local-preview/listener/generate.js.map +1 -1
  13. package/bin/local-preview/listener/index.js +145 -108
  14. package/bin/local-preview/listener/index.js.map +1 -1
  15. package/bin/local-preview/listener/update.js +1 -1
  16. package/bin/local-preview/listener/update.js.map +1 -1
  17. package/bin/scraping/combineNavWithEmptyGroupTitles.js.map +1 -1
  18. package/bin/scraping/downloadAllImages.js +9 -38
  19. package/bin/scraping/downloadAllImages.js.map +1 -1
  20. package/bin/scraping/downloadLogoImage.js +13 -0
  21. package/bin/scraping/downloadLogoImage.js.map +1 -0
  22. package/bin/scraping/scrapeFileGettingFileNameFromUrl.js +1 -1
  23. package/bin/scraping/scrapeFileGettingFileNameFromUrl.js.map +1 -1
  24. package/bin/scraping/scrapeGettingFileNameFromUrl.js +1 -2
  25. package/bin/scraping/scrapeGettingFileNameFromUrl.js.map +1 -1
  26. package/bin/scraping/scrapePage.js +3 -2
  27. package/bin/scraping/scrapePage.js.map +1 -1
  28. package/bin/scraping/scrapePageCommands.js +1 -1
  29. package/bin/scraping/scrapePageCommands.js.map +1 -1
  30. package/bin/scraping/scrapeSection.js +4 -1
  31. package/bin/scraping/scrapeSection.js.map +1 -1
  32. package/bin/scraping/scrapeSectionCommands.js +2 -2
  33. package/bin/scraping/scrapeSectionCommands.js.map +1 -1
  34. package/bin/scraping/site-scrapers/scrapeDocusaurusPage.js +2 -2
  35. package/bin/scraping/site-scrapers/scrapeDocusaurusPage.js.map +1 -1
  36. package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js +5 -1
  37. package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js.map +1 -1
  38. package/bin/scraping/site-scrapers/scrapeGitBookPage.js +2 -2
  39. package/bin/scraping/site-scrapers/scrapeGitBookPage.js.map +1 -1
  40. package/bin/scraping/site-scrapers/scrapeGitBookSection.js +7 -1
  41. package/bin/scraping/site-scrapers/scrapeGitBookSection.js.map +1 -1
  42. package/bin/scraping/site-scrapers/scrapeReadMePage.js +2 -2
  43. package/bin/scraping/site-scrapers/scrapeReadMePage.js.map +1 -1
  44. package/bin/scraping/site-scrapers/scrapeReadMeSection.js +9 -3
  45. package/bin/scraping/site-scrapers/scrapeReadMeSection.js.map +1 -1
  46. package/bin/util.js +4 -2
  47. package/bin/util.js.map +1 -1
  48. package/package.json +1 -1
  49. package/src/constants.ts +18 -0
  50. package/src/downloadImage.ts +61 -3
  51. package/src/index.ts +10 -3
  52. package/src/local-preview/index.ts +2 -1
  53. package/src/local-preview/listener/{categorizeFiles.ts → categorize.ts} +56 -2
  54. package/src/local-preview/listener/generate.ts +1 -1
  55. package/src/local-preview/listener/index.ts +163 -143
  56. package/src/local-preview/listener/update.ts +1 -1
  57. package/src/local-preview/listener/utils/types.ts +15 -0
  58. package/src/scraping/combineNavWithEmptyGroupTitles.ts +4 -4
  59. package/src/scraping/downloadAllImages.ts +12 -39
  60. package/src/scraping/downloadLogoImage.ts +24 -0
  61. package/src/scraping/scrapeFileGettingFileNameFromUrl.ts +3 -1
  62. package/src/scraping/scrapeGettingFileNameFromUrl.ts +4 -4
  63. package/src/scraping/scrapePage.ts +6 -9
  64. package/src/scraping/scrapePageCommands.ts +2 -2
  65. package/src/scraping/scrapeSection.ts +7 -2
  66. package/src/scraping/scrapeSectionCommands.ts +7 -4
  67. package/src/scraping/site-scrapers/scrapeDocusaurusPage.ts +3 -1
  68. package/src/scraping/site-scrapers/scrapeDocusaurusSection.ts +9 -4
  69. package/src/scraping/site-scrapers/scrapeGitBookPage.ts +2 -0
  70. package/src/scraping/site-scrapers/scrapeGitBookSection.ts +12 -4
  71. package/src/scraping/site-scrapers/scrapeReadMePage.ts +3 -1
  72. package/src/scraping/site-scrapers/scrapeReadMeSection.ts +14 -6
  73. package/src/types.d.ts +29 -0
  74. package/src/util.ts +6 -5
  75. package/bin/local-preview/listener/categorizeFiles.js.map +0 -1
  76. package/bin/local-preview/listener/utils/fileIsMdxOrMd.js +0 -12
  77. package/bin/local-preview/listener/utils/fileIsMdxOrMd.js.map +0 -1
  78. package/bin/local-preview/utils/categorizeFiles.js +0 -63
  79. package/bin/local-preview/utils/categorizeFiles.js.map +0 -1
  80. package/bin/local-preview/utils/getOpenApiContext.js +0 -58
  81. package/bin/local-preview/utils/getOpenApiContext.js.map +0 -1
  82. package/bin/local-preview/utils/injectFavicons.js +0 -72
  83. package/bin/local-preview/utils/injectFavicons.js.map +0 -1
  84. package/bin/local-preview/utils/listener.js +0 -116
  85. package/bin/local-preview/utils/listener.js.map +0 -1
  86. package/bin/local-preview/utils/metadata.js +0 -118
  87. package/bin/local-preview/utils/metadata.js.map +0 -1
  88. package/bin/local-preview/utils/mintConfigFile.js +0 -43
  89. package/bin/local-preview/utils/mintConfigFile.js.map +0 -1
  90. package/bin/local-preview/utils/openApiCheck.js +0 -15
  91. package/bin/local-preview/utils/openApiCheck.js.map +0 -1
  92. package/bin/local-preview/utils/slugToTitle.js +0 -8
  93. package/bin/local-preview/utils/slugToTitle.js.map +0 -1
  94. package/bin/navigation.js +0 -4
  95. package/bin/navigation.js.map +0 -1
  96. package/bin/pageTemplate.js +0 -30
  97. package/bin/pageTemplate.js.map +0 -1
  98. package/src/local-preview/listener/utils/fileIsMdxOrMd.ts +0 -11
  99. package/src/navigation.ts +0 -12
  100. package/src/pageTemplate.ts +0 -32
@@ -120,7 +120,8 @@ const dev = async () => {
120
120
  `);
121
121
  process.exit(1);
122
122
  }
123
- shellExec(`yarn preconfigure ../../../../..${CMD_EXEC_PATH}`);
123
+ const relativePath = path.relative(CLIENT_PATH, CMD_EXEC_PATH);
124
+ shellExec(`yarn preconfigure ${relativePath}`);
124
125
  logger.succeed("Local Mintlify instance initialized");
125
126
  run();
126
127
  };
@@ -2,8 +2,9 @@
2
2
  import path from "path";
3
3
 
4
4
  import { getFileExtension, openApiCheck, getFileList } from "./utils.js";
5
+ import { PotentialFileCategory } from "./utils/types.js";
5
6
 
6
- const categorizeFiles = async (contentDirectoryPath: string) => {
7
+ export const categorizeFiles = async (contentDirectoryPath: string) => {
7
8
  const allFilesInCmdExecutionPath = await getFileList(contentDirectoryPath);
8
9
  const contentFilenames = [];
9
10
  const staticFilenames = [];
@@ -52,4 +53,57 @@ const categorizeFiles = async (contentDirectoryPath: string) => {
52
53
  return { contentFilenames, staticFilenames, openApiFiles, snippets };
53
54
  };
54
55
 
55
- export default categorizeFiles;
56
+ const excludedMdFiles = ["readme", "license", "contributing", "contribute"];
57
+
58
+ const supportedStaticFileExtensions = [
59
+ ".jpeg",
60
+ ".jpg",
61
+ ".jfif",
62
+ ".pjpeg",
63
+ ".pjp",
64
+ ".png",
65
+ ".svg",
66
+ ".svgz",
67
+ ".ico",
68
+ ".webp",
69
+ ".gif",
70
+ ".apng",
71
+ ".avif",
72
+ ".bmp",
73
+ ".mp4",
74
+ ];
75
+
76
+ export const getCategory = (filePath: string): PotentialFileCategory => {
77
+ filePath = filePath.toLowerCase();
78
+
79
+ const parsed = path.parse(filePath);
80
+
81
+ if (parsed.base === "mint.json") {
82
+ return "mintConfig";
83
+ }
84
+
85
+ const fileName = parsed.name;
86
+ const extension = parsed.ext;
87
+ if (
88
+ filePath.startsWith("_snippets") &&
89
+ (extension === ".mdx" || extension === ".md")
90
+ ) {
91
+ return "snippet";
92
+ } else if (extension === ".mdx") {
93
+ return "page";
94
+ } else if (extension === ".md") {
95
+ // Exclude common markdown files people don't want on their docs website
96
+ if (excludedMdFiles.includes(fileName)) {
97
+ throw new Error("Excluded Md File");
98
+ }
99
+ return "page";
100
+ } else if (extension === ".yaml" || extension === ".yml") {
101
+ return "potentialYamlOpenApiSpec";
102
+ } else if (extension === ".json") {
103
+ return "potentialJsonOpenApiSpec";
104
+ } else if (supportedStaticFileExtensions.includes(extension)) {
105
+ return "staticFile";
106
+ }
107
+
108
+ throw new Error("Unsupported File Type, No change enacted");
109
+ };
@@ -4,7 +4,7 @@ import { outputFile } from "fs-extra";
4
4
  import path from "path";
5
5
  import createPage from "./utils/createPage.js";
6
6
  import { OpenApiFile } from "./utils/types.js";
7
- import categorizeFiles from "./categorizeFiles.js";
7
+ import { categorizeFiles } from "./categorize.js";
8
8
  import { CMD_EXEC_PATH } from "../../constants.js";
9
9
  import { getConfigObj } from "./utils/mintConfigFile.js";
10
10
  const { readFile } = _promises;
@@ -1,12 +1,13 @@
1
1
  import chokidar from "chokidar";
2
2
  import fse from "fs-extra";
3
3
  import pathUtil from "path";
4
- import { fileIsMdxOrMd } from "./utils/fileIsMdxOrMd.js";
5
4
  import { openApiCheck } from "./utils.js";
6
5
  import { updateGeneratedNav, updateOpenApiFiles } from "./update.js";
7
6
  import { CLIENT_PATH, CMD_EXEC_PATH } from "../../constants.js";
8
7
  import { promises as _promises } from "fs";
9
8
  import createPage from "./utils/createPage.js";
9
+ import { getCategory } from "./categorize.js";
10
+ import { PotentialFileCategory, FileCategory } from "./utils/types.js";
10
11
 
11
12
  const { readFile } = _promises;
12
13
 
@@ -14,156 +15,175 @@ const listener = () => {
14
15
  chokidar
15
16
  .watch(CMD_EXEC_PATH, {
16
17
  ignoreInitial: true,
17
- ignored: ["node_modules", ".git"],
18
+ ignored: ["node_modules", ".git", ".idea"],
18
19
  cwd: CMD_EXEC_PATH,
19
20
  })
20
- .on("all", async (event, filename) => {
21
- if (event === "unlink" || event === "unlinkDir") {
22
- if (fileIsMdxOrMd(filename)) {
23
- const targetPath = pathUtil.join(
24
- CLIENT_PATH,
25
- "src",
26
- "_props",
27
- filename
28
- );
29
- await fse.remove(targetPath);
30
- console.log(
31
- `${
32
- filename.startsWith("_snippets") ? "Snippet" : "Page"
33
- } deleted: `,
34
- filename
35
- );
36
- } else if (filename === "mint.json") {
37
- const targetPath = pathUtil.join(
38
- CLIENT_PATH,
39
- "src",
40
- "_props",
41
- "mint.json"
42
- );
43
- await fse.remove(targetPath);
44
- console.log(
45
- "⚠️ mint.json deleted. Please create a new mint.json file as it is mandatory."
46
- );
47
- process.exit(1);
48
- } else {
49
- const extension = pathUtil.parse(filename).ext.slice(1);
50
- if (
51
- extension &&
52
- (extension === "json" ||
53
- extension === "yaml" ||
54
- extension === "yml")
55
- ) {
56
- await updateOpenApiFiles();
57
- await updateGeneratedNav();
58
- return;
59
- }
60
- // all other files
61
- const targetPath = pathUtil.join(CLIENT_PATH, "public", filename);
21
+ .on("add", async (filename: string) => {
22
+ try {
23
+ const category = await onUpdateEvent(filename);
24
+ switch (category) {
25
+ case "page":
26
+ console.log("New page detected: ", filename);
27
+ break;
28
+ case "snippet":
29
+ console.log("New snippet detected: ", filename);
30
+ break;
31
+ case "mintConfig":
32
+ console.log("Config added");
33
+ break;
34
+ case "openApi":
35
+ console.log("OpenApi spec added: ", filename);
36
+ break;
37
+ case "staticFile":
38
+ console.log("Static file added: ", filename);
39
+ break;
40
+ }
41
+ } catch (error) {
42
+ console.error(error.message);
43
+ }
44
+ })
45
+ .on("change", async (filename: string) => {
46
+ try {
47
+ const category = await onUpdateEvent(filename);
48
+ switch (category) {
49
+ case "page":
50
+ console.log("Page edited: ", filename);
51
+ break;
52
+ case "snippet":
53
+ console.log("Snippet edited: ", filename);
54
+ break;
55
+ case "mintConfig":
56
+ console.log("Config edited");
57
+ break;
58
+ case "openApi":
59
+ console.log("OpenApi spec edited: ", filename);
60
+ break;
61
+ case "staticFile":
62
+ console.log("Static file edited: ", filename);
63
+ break;
64
+ }
65
+ } catch (error) {
66
+ console.error(error.message);
67
+ }
68
+ })
69
+ .on("unlink", async (filename: string) => {
70
+ try {
71
+ const potentialCategory = getCategory(filename);
72
+ const targetPath = getTargetPath(potentialCategory, filename);
73
+ if (
74
+ potentialCategory === "page" ||
75
+ potentialCategory === "snippet" ||
76
+ potentialCategory === "mintConfig" ||
77
+ potentialCategory === "staticFile"
78
+ ) {
62
79
  await fse.remove(targetPath);
63
- console.log("Static file deleted: ", filename);
64
80
  }
65
- } else {
66
- const filePath = pathUtil.join(CMD_EXEC_PATH, filename);
67
- let regenerateNav = false;
68
- if (fileIsMdxOrMd(filename)) {
69
- const targetPath = pathUtil.join(
70
- CLIENT_PATH,
71
- "src",
72
- "_props",
73
- filename
74
- );
75
- if (filename.startsWith("_snippets")) {
76
- const sourcePath = pathUtil.join(CMD_EXEC_PATH, filename);
77
- await fse.remove(targetPath);
78
- await fse.copy(sourcePath, targetPath);
79
- return;
80
- }
81
- regenerateNav = true;
82
-
83
- const contentStr = (await readFile(filePath)).toString();
84
- const { pageContent } = await createPage(
85
- filename,
86
- contentStr,
87
- CMD_EXEC_PATH,
88
- []
89
- );
90
- await fse.outputFile(targetPath, pageContent, {
91
- flag: "w",
92
- });
93
- switch (event) {
94
- case "add":
95
- case "addDir":
96
- console.log("New page detected: ", filename);
97
- break;
98
- default:
99
- console.log("Page edited: ", filename);
100
- break;
101
- }
102
- } else if (filename === "mint.json") {
103
- regenerateNav = true;
104
- const targetPath = pathUtil.join(
105
- CLIENT_PATH,
106
- "src",
107
- "_props",
108
- "mint.json"
109
- );
110
- await fse.copy(filePath, targetPath);
111
- switch (event) {
112
- case "add":
113
- case "addDir":
114
- console.log("Config added");
115
- break;
116
- default:
117
- console.log("Config edited");
118
- break;
119
- }
120
- } else {
121
- const extension = pathUtil.parse(filename).ext.slice(1);
122
- let isOpenApi = false;
123
- if (
124
- extension &&
125
- (extension === "json" ||
126
- extension === "yaml" ||
127
- extension === "yml")
128
- ) {
129
- const openApiInfo = await openApiCheck(
130
- pathUtil.join(CMD_EXEC_PATH, filename)
81
+ switch (potentialCategory) {
82
+ case "page":
83
+ console.log(`Page deleted: ${filename}`);
84
+ break;
85
+ case "snippet":
86
+ console.log(`Snippet deleted: ${filename}`);
87
+ break;
88
+ case "mintConfig":
89
+ console.log(
90
+ "⚠️ mint.json deleted. Please create a new mint.json file as it is mandatory."
131
91
  );
132
- isOpenApi = openApiInfo.isOpenApi;
133
- if (isOpenApi) {
134
- await updateOpenApiFiles();
135
- regenerateNav = true;
136
- }
137
- }
138
- if (!isOpenApi) {
139
- // all other files
140
- const targetPath = pathUtil.join(CLIENT_PATH, "public", filename);
141
- await fse.copy(filePath, targetPath);
142
- }
143
- switch (event) {
144
- case "add":
145
- case "addDir":
146
- if (isOpenApi) {
147
- console.log("OpenApi file added: ", filename);
148
- } else {
149
- console.log("Static file added: ", filename);
150
- }
151
- break;
152
- default:
153
- if (isOpenApi) {
154
- console.log("OpenApi file edited: ", filename);
155
- } else {
156
- console.log("Static file edited: ", filename);
157
- }
158
- break;
159
- }
160
- }
161
- if (regenerateNav) {
162
- // TODO: Instead of re-generating the entire nav, optimize by just updating the specific page that changed.
163
- await updateGeneratedNav();
92
+ process.exit(1);
93
+ case "potentialJsonOpenApiSpec":
94
+ case "potentialYamlOpenApiSpec":
95
+ await updateOpenApiFiles();
96
+ await updateGeneratedNav();
97
+ break;
98
+ case "staticFile":
99
+ console.log("Static file deleted: ", filename);
100
+ break;
164
101
  }
102
+ } catch (error) {
103
+ console.error(error.message);
165
104
  }
166
105
  });
167
106
  };
168
107
 
108
+ const getTargetPath = (
109
+ potentialCategory: PotentialFileCategory,
110
+ filePath: string
111
+ ): string => {
112
+ switch (potentialCategory) {
113
+ case "page":
114
+ case "snippet":
115
+ return pathUtil.join(CLIENT_PATH, "src", "_props", filePath);
116
+ case "mintConfig":
117
+ return pathUtil.join(CLIENT_PATH, "src", "_props", "mint.json");
118
+ case "potentialYamlOpenApiSpec":
119
+ case "potentialJsonOpenApiSpec":
120
+ return pathUtil.join(CLIENT_PATH, "src", "_props", "openApiFiles.json");
121
+ case "staticFile":
122
+ return pathUtil.join(CLIENT_PATH, "public", filePath);
123
+ default:
124
+ throw new Error("Invalid category");
125
+ }
126
+ };
127
+
128
+ /**
129
+ * This function is called when a file is added or changed
130
+ * @param filename
131
+ * @returns FileCategory
132
+ */
133
+ const onUpdateEvent = async (filename: string): Promise<FileCategory> => {
134
+ const filePath = pathUtil.join(CMD_EXEC_PATH, filename);
135
+ const potentialCategory = getCategory(filename);
136
+ const targetPath = getTargetPath(potentialCategory, filename);
137
+ let regenerateNav = false;
138
+ let category: FileCategory =
139
+ potentialCategory === "potentialYamlOpenApiSpec" ||
140
+ potentialCategory === "potentialJsonOpenApiSpec"
141
+ ? "staticFile"
142
+ : potentialCategory;
143
+ switch (potentialCategory) {
144
+ case "page":
145
+ regenerateNav = true;
146
+ const contentStr = (await readFile(filePath)).toString();
147
+ const { pageContent } = await createPage(
148
+ filename,
149
+ contentStr,
150
+ CMD_EXEC_PATH,
151
+ []
152
+ );
153
+ await fse.outputFile(targetPath, pageContent, {
154
+ flag: "w",
155
+ });
156
+ break;
157
+ case "snippet":
158
+ await fse.copy(filePath, targetPath);
159
+ break;
160
+ case "mintConfig":
161
+ regenerateNav = true;
162
+ await fse.copy(filePath, targetPath);
163
+ break;
164
+ case "potentialYamlOpenApiSpec":
165
+ case "potentialJsonOpenApiSpec":
166
+ let isOpenApi = false;
167
+ const openApiInfo = await openApiCheck(
168
+ pathUtil.join(CMD_EXEC_PATH, filename)
169
+ );
170
+ isOpenApi = openApiInfo.isOpenApi;
171
+ if (isOpenApi) {
172
+ // TODO: Instead of re-generating all openApi files, optimize by just updating the specific file that changed.
173
+ await updateOpenApiFiles();
174
+ regenerateNav = true;
175
+ category = "openApi";
176
+ }
177
+ break;
178
+ case "staticFile":
179
+ await fse.copy(filePath, targetPath);
180
+ break;
181
+ }
182
+ if (regenerateNav) {
183
+ // TODO: Instead of re-generating the entire nav, optimize by just updating the specific page that changed.
184
+ await updateGeneratedNav();
185
+ }
186
+ return category;
187
+ };
188
+
169
189
  export default listener;
@@ -5,7 +5,7 @@ import { getConfigPath } from "./utils/mintConfigFile.js";
5
5
  import { CLIENT_PATH, CMD_EXEC_PATH } from "../../constants.js";
6
6
  import { join } from "path";
7
7
  import { generateNav } from "./generate.js";
8
- import categorizeFiles from "./categorizeFiles.js";
8
+ import { categorizeFiles } from "./categorize.js";
9
9
 
10
10
  const { readFile } = _promises;
11
11
 
@@ -1 +1,16 @@
1
1
  export type OpenApiFile = { name: string; spec: any };
2
+
3
+ export type PotentialFileCategory =
4
+ | "page"
5
+ | "snippet"
6
+ | "mintConfig"
7
+ | "potentialYamlOpenApiSpec"
8
+ | "potentialJsonOpenApiSpec"
9
+ | "staticFile";
10
+
11
+ export type FileCategory =
12
+ | "page"
13
+ | "snippet"
14
+ | "mintConfig"
15
+ | "openApi"
16
+ | "staticFile";
@@ -1,9 +1,9 @@
1
- import { Navigation } from "../navigation.js";
2
-
3
- export default function combineNavWithEmptyGroupTitles(navArray: Navigation[]) {
1
+ export default function combineNavWithEmptyGroupTitles(
2
+ navArray: MintNavigation[]
3
+ ): MintNavigation[] {
4
4
  let newNavArray = [];
5
5
 
6
- navArray.forEach((nav: Navigation) => {
6
+ navArray.forEach((nav: MintNavigation) => {
7
7
  // The first run through the loop will always have -1 as the index.
8
8
  // JavaScript returns undefined when we look for an index outside the size of the array.
9
9
  const prev = newNavArray[newNavArray.length - 1];
@@ -1,5 +1,9 @@
1
1
  import path from "path";
2
- import downloadImage from "../downloadImage.js";
2
+ import downloadImage, {
3
+ cleanImageSrc,
4
+ isValidImageSrc,
5
+ removeMetadataFromImageSrc,
6
+ } from "../downloadImage.js";
3
7
 
4
8
  // To Do: Use CheerioElement instead of any when we bump the cheerio version
5
9
  export default async function downloadAllImages(
@@ -7,6 +11,7 @@ export default async function downloadAllImages(
7
11
  content: any,
8
12
  origin: string,
9
13
  baseDir: string,
14
+ overwrite: boolean,
10
15
  modifyFileName?: any
11
16
  ) {
12
17
  if (!baseDir) {
@@ -27,42 +32,21 @@ export default async function downloadAllImages(
27
32
 
28
33
  // Wait to all images to download before continuing
29
34
  const origToNewArray = await Promise.all(
30
- imageSrcs.map(async (origImageSrc: string) => {
31
- // We do not support downloading base64 in-line images.
32
- if (origImageSrc.startsWith("data:")) {
33
- return undefined;
34
- }
35
+ imageSrcs.map(async (imageSrc: string) => {
36
+ if (!isValidImageSrc(imageSrc)) return;
35
37
 
36
- // Add origin if the image tags are using relative sources
37
- const imageHref = origImageSrc.startsWith("http")
38
- ? origImageSrc
39
- : new URL(origImageSrc, origin).href;
38
+ const imageHref = cleanImageSrc(imageSrc, origin);
40
39
 
41
- let fileName = removeMetadataFromExtension(path.basename(imageHref));
40
+ let fileName = removeMetadataFromImageSrc(path.basename(imageHref));
42
41
  if (modifyFileName) {
43
42
  fileName = modifyFileName(fileName);
44
43
  }
45
44
 
46
- if (!fileName) {
47
- console.error("Invalid image path " + imageHref);
48
- return;
49
- }
50
-
51
45
  const writePath = path.join(baseDir, fileName);
52
46
 
53
- await downloadImage(imageHref, writePath)
54
- .then(() => {
55
- console.log("🖼️ - " + writePath);
56
- })
57
- .catch((e) => {
58
- if (e.code === "EEXIST") {
59
- console.log(`❌ Skipping existing image ${writePath}`);
60
- } else {
61
- console.error(e);
62
- }
63
- });
47
+ await downloadImage(imageHref, writePath, overwrite);
64
48
 
65
- return { [origImageSrc]: writePath };
49
+ return { [imageSrc]: writePath };
66
50
  })
67
51
  );
68
52
 
@@ -71,14 +55,3 @@ export default async function downloadAllImages(
71
55
  {}
72
56
  );
73
57
  }
74
-
75
- function removeMetadataFromExtension(src: string) {
76
- // Part of the URL standard
77
- const metadataSymbols = ["?", "#"];
78
-
79
- metadataSymbols.forEach((dividerSymbol) => {
80
- // Some frameworks add metadata after the file extension, we need to remove that.
81
- src = src.split(dividerSymbol)[0];
82
- });
83
- return src;
84
- }
@@ -0,0 +1,24 @@
1
+ import path from "path";
2
+ import downloadImage, {
3
+ cleanImageSrc,
4
+ isValidImageSrc,
5
+ removeMetadataFromImageSrc,
6
+ } from "../downloadImage.js";
7
+ import { getFileExtension } from "../util.js";
8
+
9
+ // To Do: Use CheerioElement instead of any when we bump the cheerio version
10
+ export default async function downloadLogoImage(
11
+ imageSrc: string,
12
+ imageBaseDir: string,
13
+ origin: string,
14
+ overwrite: boolean
15
+ ) {
16
+ if (!isValidImageSrc(imageSrc)) return;
17
+
18
+ const imageHref = cleanImageSrc(imageSrc, origin);
19
+
20
+ const ext = getFileExtension(removeMetadataFromImageSrc(imageSrc));
21
+ const imagePath = path.join(imageBaseDir, "logo", "logo-light-mode." + ext);
22
+
23
+ await downloadImage(imageHref, imagePath, overwrite);
24
+ }
@@ -13,6 +13,7 @@ export async function scrapeFileGettingFileNameFromUrl(
13
13
  origin: string,
14
14
  cliDir: string,
15
15
  imageBaseDir: string,
16
+ overwrite: boolean,
16
17
  version: string | undefined
17
18
  ) => Promise<{
18
19
  title?: string;
@@ -22,7 +23,7 @@ export async function scrapeFileGettingFileNameFromUrl(
22
23
  puppeteer = false,
23
24
  version: string | undefined,
24
25
  baseToRemove?: string
25
- ) {
26
+ ): Promise<MintNavigationEntry> {
26
27
  // Skip scraping external links
27
28
  if (pathname.startsWith("https://") || pathname.startsWith("http://")) {
28
29
  return pathname;
@@ -56,6 +57,7 @@ export async function scrapeFileGettingFileNameFromUrl(
56
57
  origin,
57
58
  cliDir,
58
59
  imageBaseDir,
60
+ overwrite,
59
61
  version
60
62
  );
61
63
 
@@ -1,8 +1,7 @@
1
- import { NavigationEntry, isNavigation } from "../navigation.js";
2
1
  import { scrapeFileGettingFileNameFromUrl } from "./scrapeFileGettingFileNameFromUrl.js";
3
2
 
4
3
  export async function scrapeGettingFileNameFromUrl(
5
- navEntry: NavigationEntry,
4
+ navEntry: MintNavigationEntry,
6
5
  cliDir: string,
7
6
  origin: string,
8
7
  overwrite: boolean,
@@ -11,6 +10,7 @@ export async function scrapeGettingFileNameFromUrl(
11
10
  origin: string,
12
11
  cliDir: string,
13
12
  imageBaseDir: string,
13
+ overwrite: boolean,
14
14
  version: string | undefined
15
15
  ) => Promise<{
16
16
  title?: string;
@@ -20,8 +20,8 @@ export async function scrapeGettingFileNameFromUrl(
20
20
  puppeteer = false,
21
21
  version: string | undefined,
22
22
  baseToRemove?: string
23
- ): Promise<NavigationEntry> {
24
- if (isNavigation(navEntry)) {
23
+ ): Promise<MintNavigationEntry> {
24
+ if (typeof navEntry !== "string") {
25
25
  const newPages = [];
26
26
  for (const nestedNavEntry of navEntry.pages) {
27
27
  newPages.push(
@@ -2,25 +2,22 @@ import path from "path";
2
2
  import { createPage, getOrigin } from "../util.js";
3
3
 
4
4
  export async function scrapePage(
5
- scrapeFunc: (
6
- html: string,
7
- origin: string,
8
- cliDir: string,
9
- imageBaseDir: string,
10
- version: string | undefined
11
- ) => Promise<any>,
5
+ scrapeFunc: ScrapePageFn,
12
6
  href: string,
13
7
  html: string,
14
8
  overwrite: boolean,
15
9
  version: string | undefined
16
10
  ) {
17
11
  const origin = getOrigin(href);
18
- const imageBaseDir = path.join(process.cwd(), "images");
12
+ const cwd = process.cwd();
13
+ const imageBaseDir = path.join(cwd, "images");
14
+
19
15
  const { title, description, markdown } = await scrapeFunc(
20
16
  html,
21
17
  origin,
22
- process.cwd(),
18
+ cwd,
23
19
  imageBaseDir,
20
+ overwrite,
24
21
  version
25
22
  );
26
23
  createPage(title, description, markdown, overwrite, process.cwd());
@@ -21,7 +21,7 @@ function validateFramework(framework) {
21
21
 
22
22
  export async function scrapePageWrapper(
23
23
  argv: any,
24
- scrapeFunc: any,
24
+ scrapeFunc: ScrapePageFn,
25
25
  options?: { version?: string; puppeteer?: boolean }
26
26
  ) {
27
27
  const href = getHrefFromArgs(argv);
@@ -32,7 +32,7 @@ export async function scrapePageWrapper(
32
32
  const res = await axios.get(href);
33
33
  html = res.data;
34
34
  }
35
- await scrapePage(scrapeFunc, href, html, argv.overwrite, options?.version);
35
+ await scrapePage(scrapeFunc, href, html, !!argv.overwrite, options?.version);
36
36
  process.exit(0);
37
37
  }
38
38