@mintlify/previewing 3.0.2 → 3.0.3

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 (57) hide show
  1. package/{bin → dist}/constants.js +0 -0
  2. package/{bin → dist}/constants.js.map +0 -0
  3. package/{bin → dist}/downloadImage.js +0 -0
  4. package/{bin → dist}/downloadImage.js.map +0 -0
  5. package/dist/index.js +4 -0
  6. package/dist/index.js.map +1 -0
  7. package/{bin → dist}/local-preview/helper-commands/installDepsCommand.js +0 -0
  8. package/{bin → dist}/local-preview/helper-commands/installDepsCommand.js.map +0 -0
  9. package/{bin → dist}/local-preview/index.js +0 -0
  10. package/{bin → dist}/local-preview/index.js.map +0 -0
  11. package/{bin → dist}/local-preview/listener/categorize.js +0 -0
  12. package/{bin → dist}/local-preview/listener/categorize.js.map +0 -0
  13. package/{bin → dist}/local-preview/listener/generate.js +0 -0
  14. package/{bin → dist}/local-preview/listener/generate.js.map +0 -0
  15. package/{bin → dist}/local-preview/listener/index.js +0 -0
  16. package/{bin → dist}/local-preview/listener/index.js.map +0 -0
  17. package/{bin → dist}/local-preview/listener/update.js +0 -0
  18. package/{bin → dist}/local-preview/listener/update.js.map +0 -0
  19. package/{bin → dist}/local-preview/listener/utils/createPage.js +0 -0
  20. package/{bin → dist}/local-preview/listener/utils/createPage.js.map +0 -0
  21. package/{bin → dist}/local-preview/listener/utils/getOpenApiContext.js +0 -0
  22. package/{bin → dist}/local-preview/listener/utils/getOpenApiContext.js.map +0 -0
  23. package/{bin → dist}/local-preview/listener/utils/mintConfigFile.js +0 -0
  24. package/{bin → dist}/local-preview/listener/utils/mintConfigFile.js.map +0 -0
  25. package/{bin → dist}/local-preview/listener/utils/toTitleCase.js +0 -0
  26. package/{bin → dist}/local-preview/listener/utils/toTitleCase.js.map +0 -0
  27. package/{bin → dist}/local-preview/listener/utils/types.js +0 -0
  28. package/{bin → dist}/local-preview/listener/utils/types.js.map +0 -0
  29. package/{bin → dist}/local-preview/listener/utils.js +0 -0
  30. package/{bin → dist}/local-preview/listener/utils.js.map +0 -0
  31. package/{bin → dist}/util.js +0 -0
  32. package/{bin → dist}/util.js.map +0 -0
  33. package/package.json +21 -12
  34. package/.eslintignore +0 -1
  35. package/.eslintrc.json +0 -3
  36. package/CONTRIBUTING.md +0 -17
  37. package/bin/index.js +0 -19
  38. package/bin/index.js.map +0 -1
  39. package/scraper.md +0 -121
  40. package/src/constants.ts +0 -40
  41. package/src/downloadImage.ts +0 -102
  42. package/src/index.ts +0 -35
  43. package/src/local-preview/helper-commands/installDepsCommand.ts +0 -13
  44. package/src/local-preview/index.ts +0 -196
  45. package/src/local-preview/listener/categorize.ts +0 -107
  46. package/src/local-preview/listener/generate.ts +0 -121
  47. package/src/local-preview/listener/index.ts +0 -228
  48. package/src/local-preview/listener/update.ts +0 -27
  49. package/src/local-preview/listener/utils/createPage.ts +0 -215
  50. package/src/local-preview/listener/utils/getOpenApiContext.ts +0 -77
  51. package/src/local-preview/listener/utils/mintConfigFile.ts +0 -28
  52. package/src/local-preview/listener/utils/toTitleCase.ts +0 -40
  53. package/src/local-preview/listener/utils/types.ts +0 -14
  54. package/src/local-preview/listener/utils.ts +0 -87
  55. package/src/types.d.ts +0 -35
  56. package/src/util.ts +0 -119
  57. package/tsconfig.json +0 -19
@@ -1,215 +0,0 @@
1
- import matter from "gray-matter";
2
- import isAbsoluteUrl from "is-absolute-url";
3
- import { remark } from "remark";
4
- import remarkFrontmatter from "remark-frontmatter";
5
- import remarkGfm from "remark-gfm";
6
- import remarkMdx from "remark-mdx";
7
- import { visit } from "unist-util-visit";
8
-
9
- const createPage = async (
10
- pagePath: string,
11
- pageContent: string,
12
- contentDirectoryPath: string,
13
- openApiFiles: OpenApiFile[]
14
- ) => {
15
- const { data: metadata } = matter(pageContent);
16
- try {
17
- const parsedContent = await preParseMdx(pageContent, contentDirectoryPath);
18
- pageContent = parsedContent;
19
- } catch (error) {
20
- pageContent = `🚧 A parsing error occured. Please contact the owner of this website.`;
21
- }
22
-
23
- // Replace .mdx so we can pass file paths into this function
24
- const slug = pagePath.replace(/\.mdx?$/, "");
25
- let defaultTitle = slugToTitle(slug);
26
- let description: string;
27
- // Append data from OpenAPI if it exists
28
- if (metadata?.openapi) {
29
- const { title, description: openApiDescription } =
30
- getOpenApiTitleAndDescription(openApiFiles, metadata?.openapi);
31
-
32
- if (title) {
33
- defaultTitle = title;
34
- }
35
- if (openApiDescription) {
36
- description = openApiDescription;
37
- }
38
- }
39
-
40
- const pageMetadata = {
41
- title: defaultTitle,
42
- description,
43
- ...metadata,
44
- href: optionallyAddLeadingSlash(slug),
45
- };
46
-
47
- return {
48
- pageMetadata,
49
- pageContent,
50
- slug: removeLeadingSlash(slug),
51
- };
52
- };
53
-
54
- const preParseMdx = async (
55
- fileContent: string,
56
- contentDirectoryPath: string
57
- ) => {
58
- const removeContentDirectoryPath = (filePath: string) => {
59
- const pathArr = createPathArr(filePath);
60
- const contentDirectoryPathArr = createPathArr(contentDirectoryPath);
61
- contentDirectoryPathArr.reverse().forEach((dir: string, index: number) => {
62
- if (pathArr[index] === dir) {
63
- pathArr.pop();
64
- }
65
- });
66
- return "/" + pathArr.join("/");
67
- };
68
-
69
- const removeContentDirectoryPaths = () => {
70
- return (tree) => {
71
- visit(tree, (node) => {
72
- if (node == null) {
73
- return;
74
- }
75
- if (node.name === "img" || node.name === "source") {
76
- const srcAttrIndex = node.attributes.findIndex(
77
- (attr) => attr?.name === "src"
78
- );
79
- const nodeUrl = node.attributes[srcAttrIndex].value;
80
- if (
81
- // <img/> component
82
- srcAttrIndex !== -1 &&
83
- !isAbsoluteUrl(nodeUrl) &&
84
- !isDataString(nodeUrl)
85
- ) {
86
- node.attributes[srcAttrIndex].value =
87
- removeContentDirectoryPath(nodeUrl);
88
- }
89
- } else if (
90
- // ![]() format
91
- node.type === "image" &&
92
- node.url &&
93
- !isAbsoluteUrl(node.url) &&
94
- !isDataString(node.url)
95
- ) {
96
- node.url = removeContentDirectoryPath(node.url);
97
- }
98
- });
99
- return tree;
100
- };
101
- };
102
-
103
- const file = await remark()
104
- .use(remarkMdx)
105
- .use(remarkGfm)
106
- .use(remarkFrontmatter, ["yaml", "toml"])
107
- .use(removeContentDirectoryPaths)
108
- .process(fileContent);
109
- return String(file);
110
- };
111
-
112
- const removeLeadingSlash = (str: string) => {
113
- const path = createPathArr(str);
114
- return path.join("/");
115
- };
116
-
117
- const createPathArr = (path: string) => {
118
- return path.split("/").filter((dir) => dir !== "");
119
- };
120
-
121
- const isDataString = (str: string) => str.startsWith("data:");
122
-
123
- const getOpenApiTitleAndDescription = (
124
- openApiFiles: OpenApiFile[],
125
- openApiMetaField: string
126
- ) => {
127
- const { operation } = getOpenApiOperationMethodAndEndpoint(
128
- openApiFiles,
129
- openApiMetaField
130
- );
131
-
132
- if (operation == null) {
133
- return {};
134
- }
135
-
136
- return {
137
- title: operation.summary,
138
- description: operation.description,
139
- };
140
- };
141
-
142
- const getOpenApiOperationMethodAndEndpoint = (
143
- openApiFiles: OpenApiFile[],
144
- openApiMetaField: string
145
- ) => {
146
- const { endpoint, method, filename } =
147
- extractMethodAndEndpoint(openApiMetaField);
148
-
149
- let path;
150
-
151
- openApiFiles?.forEach((file) => {
152
- const openApiFile = file.spec;
153
- const openApiPath = openApiFile.paths && openApiFile.paths[endpoint];
154
- const isFilenameOrNone = !filename || filename === file.filename;
155
- if (openApiPath && isFilenameOrNone) {
156
- path = openApiPath;
157
- }
158
- });
159
-
160
- if (path == null) {
161
- return {};
162
- }
163
-
164
- let operation;
165
- if (method) {
166
- operation = path[method.toLowerCase()];
167
- } else {
168
- const firstOperationKey = Object.keys(path)[0];
169
- operation = path[firstOperationKey];
170
- }
171
-
172
- return {
173
- operation,
174
- method,
175
- endpoint,
176
- };
177
- };
178
-
179
- const extractMethodAndEndpoint = (openApiMetaField: string) => {
180
- const methodRegex = /(get|post|put|delete|patch)\s/i;
181
- const trimmed = openApiMetaField.trim();
182
- const foundMethod = trimmed.match(methodRegex);
183
-
184
- const startIndexOfMethod = foundMethod
185
- ? openApiMetaField.indexOf(foundMethod[0])
186
- : 0;
187
- const endIndexOfMethod = foundMethod
188
- ? startIndexOfMethod + foundMethod[0].length - 1
189
- : 0;
190
-
191
- const filename = openApiMetaField.substring(0, startIndexOfMethod).trim();
192
-
193
- return {
194
- method: foundMethod ? foundMethod[0].slice(0, -1).toUpperCase() : undefined,
195
- endpoint: openApiMetaField.substring(endIndexOfMethod).trim(),
196
- filename: filename ? filename : undefined,
197
- };
198
- };
199
-
200
- function optionallyAddLeadingSlash(path: string) {
201
- if (path.startsWith("/")) {
202
- return path;
203
- }
204
- return "/" + path;
205
- }
206
-
207
- export const slugToTitle = (slug: string) => {
208
- const slugArr = slug.split("/");
209
- let defaultTitle = slugArr[slugArr.length - 1].split("-").join(" "); //replace all dashes
210
- defaultTitle = defaultTitle.split("_").join(" "); //replace all underscores
211
- defaultTitle = defaultTitle.charAt(0).toUpperCase() + defaultTitle.slice(1); //capitalize first letter
212
- return defaultTitle;
213
- };
214
-
215
- export default createPage;
@@ -1,77 +0,0 @@
1
- export const extractMethodAndEndpoint = (
2
- api: string
3
- ): { method?: string; endpoint: string; filename?: string } => {
4
- const methodRegex = /(get|post|put|delete|patch)\s/i;
5
- const trimmed = api.trim();
6
- const foundMethod = trimmed.match(methodRegex);
7
-
8
- const startIndexOfMethod = foundMethod ? api.indexOf(foundMethod[0]) : 0;
9
- const endIndexOfMethod = foundMethod
10
- ? startIndexOfMethod + foundMethod[0].length - 1
11
- : 0;
12
-
13
- const filename = api.substring(0, startIndexOfMethod).trim();
14
-
15
- return {
16
- method: foundMethod ? foundMethod[0].slice(0, -1).toUpperCase() : undefined,
17
- endpoint: api.substring(endIndexOfMethod).trim(),
18
- filename: filename ? filename : undefined,
19
- };
20
- };
21
-
22
- export const getOpenApiOperationMethodAndEndpoint = (
23
- openApi: any,
24
- openApiMetaField: string
25
- ) => {
26
- const { endpoint, method, filename } =
27
- extractMethodAndEndpoint(openApiMetaField);
28
-
29
- let path: any;
30
-
31
- openApi.files?.forEach((file: any) => {
32
- const openApiFile = file.openapi;
33
- const openApiPath = openApiFile.paths && openApiFile.paths[endpoint];
34
- const isFilenameOrNone = !filename || filename === file.name;
35
- if (openApiPath && isFilenameOrNone) {
36
- path = openApiPath;
37
- }
38
- });
39
-
40
- if (path == null) {
41
- return {};
42
- }
43
-
44
- let operation;
45
- if (method) {
46
- operation = path[method.toLowerCase()];
47
- } else {
48
- const firstOperationKey = Object.keys(path)[0];
49
- operation = path[firstOperationKey];
50
- }
51
-
52
- return {
53
- operation,
54
- method,
55
- endpoint,
56
- };
57
- };
58
-
59
- export const getOpenApiTitleAndDescription = (openApi, openApiMetaField) => {
60
- if (openApi == null || !openApiMetaField || openApiMetaField == null) {
61
- return {};
62
- }
63
-
64
- const { operation } = getOpenApiOperationMethodAndEndpoint(
65
- openApi,
66
- openApiMetaField
67
- );
68
-
69
- if (operation == null) {
70
- return {};
71
- }
72
-
73
- return {
74
- title: operation.summary,
75
- description: operation.description,
76
- };
77
- };
@@ -1,28 +0,0 @@
1
- import { promises as _promises } from "fs";
2
- import { pathExists } from "fs-extra";
3
- import pathUtil from "path";
4
-
5
- const { readFile } = _promises;
6
-
7
- // TODO: Put in prebuild package
8
- export const getConfigPath = async (
9
- contentDirectoryPath: string
10
- ): Promise<string | null> => {
11
- if (await pathExists(pathUtil.join(contentDirectoryPath, "mint.json"))) {
12
- return pathUtil.join(contentDirectoryPath, "mint.json");
13
- }
14
- return null;
15
- };
16
-
17
- // TODO: Put in prebuild package
18
- export const getConfigObj = async (
19
- contentDirectoryPath: string
20
- ): Promise<any> => {
21
- const configPath = await getConfigPath(contentDirectoryPath);
22
- let configObj = null;
23
- if (configPath) {
24
- const configContents = await readFile(configPath);
25
- configObj = await JSON.parse(configContents.toString());
26
- }
27
- return configObj;
28
- };
@@ -1,40 +0,0 @@
1
- export function toTitleCase(text: string) {
2
- const smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i;
3
- const alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/;
4
- const wordSeparators = /([ :–—-])/;
5
-
6
- return text
7
- .split(wordSeparators)
8
- .map(function (current, index, array) {
9
- if (
10
- // Check for small words
11
- current.search(smallWords) > -1 &&
12
- // Skip first and last word
13
- index !== 0 &&
14
- index !== array.length - 1 &&
15
- // Ignore title end and subtitle start
16
- array[index - 3] !== ':' &&
17
- array[index + 1] !== ':' &&
18
- // Ignore small words that start a hyphenated phrase
19
- (array[index + 1] !== '-' || (array[index - 1] === '-' && array[index + 1] === '-'))
20
- ) {
21
- return current.toLowerCase();
22
- }
23
-
24
- // Ignore intentional capitalization
25
- if (current.substring(1).search(/[A-Z]|\../) > -1) {
26
- return current;
27
- }
28
-
29
- // Ignore URLs
30
- if (array[index + 1] === ':' && array[index + 2] !== '') {
31
- return current;
32
- }
33
-
34
- // Capitalize the first letter
35
- return current.replace(alphanumericPattern, function (match: string) {
36
- return match.toUpperCase();
37
- });
38
- })
39
- .join('');
40
- }
@@ -1,14 +0,0 @@
1
- export type PotentialFileCategory =
2
- | "page"
3
- | "snippet"
4
- | "mintConfig"
5
- | "potentialYamlOpenApiSpec"
6
- | "potentialJsonOpenApiSpec"
7
- | "staticFile";
8
-
9
- export type FileCategory =
10
- | "page"
11
- | "snippet"
12
- | "mintConfig"
13
- | "openApi"
14
- | "staticFile";
@@ -1,87 +0,0 @@
1
- import SwaggerParser from "@apidevtools/swagger-parser";
2
- import { promises as _promises } from "fs";
3
-
4
- const { readdir, stat } = _promises;
5
-
6
- export const getFileExtension = (filename: string) => {
7
- return (
8
- filename.substring(filename.lastIndexOf(".") + 1, filename.length) ||
9
- filename
10
- );
11
- };
12
-
13
- export type OpenApiCheckResult = {
14
- spec: any;
15
- isOpenApi: boolean;
16
- };
17
-
18
- export const openApiCheck = async (
19
- path: string
20
- ): Promise<OpenApiCheckResult> => {
21
- let spec;
22
- let isOpenApi = false;
23
- try {
24
- spec = await SwaggerParser.validate(path);
25
- isOpenApi = true;
26
- } catch {
27
- // not valid openApi
28
- }
29
- return { spec, isOpenApi };
30
- };
31
-
32
- export const filterOutNullInGroup = (group: MintNavigation) => {
33
- const newPages = filterOutNullInPages(group.pages);
34
- const newGroup = {
35
- ...group,
36
- pages: newPages,
37
- };
38
- return newGroup;
39
- };
40
-
41
- const filterOutNullInPages = (pages: (MintNavigationEntry | null)[]) => {
42
- const newPages: MintNavigationEntry[] = [];
43
- pages.forEach((page) => {
44
- if (page == null) {
45
- return;
46
- }
47
- if (page.hasOwnProperty("pages")) {
48
- const group = page as MintNavigation;
49
- const newGroup = filterOutNullInGroup(group);
50
- newPages.push(newGroup);
51
- } else {
52
- newPages.push(page);
53
- }
54
- });
55
-
56
- return newPages;
57
- };
58
-
59
- export const getFileList = async (dirName: string, og = dirName) => {
60
- let files: string[] = [];
61
- const items = await readdir(dirName, { withFileTypes: true });
62
-
63
- for (const item of items) {
64
- if (item.isDirectory()) {
65
- files = [...files, ...(await getFileList(`${dirName}/${item.name}`, og))];
66
- } else {
67
- const path = `${dirName}/${item.name}`;
68
- const name = path.replace(og, "");
69
- files.push(name);
70
- }
71
- }
72
-
73
- return files;
74
- };
75
-
76
- export const isFileSizeValid = async (
77
- path: string,
78
- maxFileSizeInMb: number
79
- ): Promise<boolean> => {
80
- const maxFileSizeBytes = maxFileSizeInMb * 1000000;
81
- const stats = await stat(path);
82
- return stats.size <= maxFileSizeBytes;
83
- };
84
-
85
- export function isError(obj: unknown) {
86
- return Object.prototype.toString.call(obj) === "[object Error]";
87
- }
package/src/types.d.ts DELETED
@@ -1,35 +0,0 @@
1
- type MintPage = {
2
- title?: string;
3
- description?: string;
4
- markdown?: string;
5
- };
6
-
7
- type MintNavigation = {
8
- group: string;
9
- version?: string;
10
- pages: MintNavigationEntry[];
11
- };
12
- type MintNavigationEntry = string | MintNavigation;
13
-
14
- type ScrapePageFn = (
15
- html: string,
16
- origin: string,
17
- cliDir: string,
18
- imageBaseDir: string,
19
- overwrite: boolean,
20
- version: string | undefined
21
- ) => Promise<MintPage>;
22
-
23
- type ScrapeSectionFn = (
24
- html: string,
25
- origin: string,
26
- cliDir: string,
27
- imageBaseDir: string,
28
- overwrite: boolean,
29
- version: string | undefined
30
- ) => Promise<MintNavigationEntry[]>;
31
-
32
- type OpenApiFile = {
33
- filename: string;
34
- spec: any;
35
- };
package/src/util.ts DELETED
@@ -1,119 +0,0 @@
1
- import { mkdirSync, writeFileSync } from "fs";
2
- import Ora, { Ora as OraType } from "ora";
3
- import path from "path";
4
- import shell from "shelljs";
5
-
6
- export const MintConfig = (
7
- name: string,
8
- color: string,
9
- ctaName: string,
10
- ctaUrl: string,
11
- filename: string
12
- ) => {
13
- return {
14
- name,
15
- logo: "",
16
- favicon: "",
17
- colors: {
18
- primary: color,
19
- },
20
- topbarLinks: [],
21
- topbarCtaButton: {
22
- name: ctaName,
23
- url: ctaUrl,
24
- },
25
- anchors: [],
26
- navigation: [
27
- {
28
- group: "Home",
29
- pages: [filename],
30
- },
31
- ],
32
- // footerSocials: {}, // support object type for footer tyoes
33
- };
34
- };
35
-
36
- export const Page = (
37
- title: string,
38
- description?: string,
39
- markdown?: string
40
- ) => {
41
- // If we are an empty String we want to add two quotes,
42
- // if we added as we went we would detect the first quote
43
- // as the closing quote.
44
- const startsWithQuote = title.startsWith('"');
45
- const endsWithQuote = title.startsWith('"');
46
- if (!startsWithQuote) {
47
- title = '"' + title;
48
- }
49
- if (!endsWithQuote) {
50
- title = title + '"';
51
- }
52
-
53
- const optionalDescription = description
54
- ? `\ndescription: "${description}"`
55
- : "";
56
- return `---\ntitle: ${title}${optionalDescription}\n---\n\n${markdown}`;
57
- };
58
-
59
- export function getOrigin(url: string) {
60
- // eg. https://google.com -> https://google.com
61
- // https://google.com/page -> https://google.com
62
- return new URL(url).origin;
63
- }
64
-
65
- export function objToReadableString(objs: MintNavigationEntry[]) {
66
- // Two spaces as indentation
67
- return objs.map((obj) => JSON.stringify(obj, null, 2)).join(",\n");
68
- }
69
-
70
- export const toFilename = (title: string) => {
71
- // Gets rid of special characters at the start and end
72
- // of the name by converting to spaces then using trim.
73
- return title
74
- .replace(/[^a-z0-9]/gi, " ")
75
- .trim()
76
- .replace(/ /g, "-")
77
- .toLowerCase();
78
- };
79
-
80
- export const addMdx = (fileName: string) => {
81
- if (fileName.endsWith(".mdx")) {
82
- return fileName;
83
- }
84
- return fileName + ".mdx";
85
- };
86
-
87
- export const buildLogger = (startText = ""): OraType => {
88
- const logger = Ora().start(startText);
89
- return logger;
90
- };
91
-
92
- export const getFileExtension = (filename: string) => {
93
- const ext = filename.substring(
94
- filename.lastIndexOf(".") + 1,
95
- filename.length
96
- );
97
- if (filename === ext) return undefined;
98
- return ext;
99
- };
100
-
101
- export const fileBelongsInPagesFolder = (filename: string) => {
102
- const extension = getFileExtension(filename);
103
- return (
104
- extension &&
105
- (extension === "mdx" || extension === "md" || extension === "tsx")
106
- );
107
- };
108
-
109
- export const ensureYarn = (logger: OraType) => {
110
- const yarnInstalled = shell.which("yarn");
111
- if (!yarnInstalled) {
112
- logger.fail(`yarn must be installed, run
113
-
114
- npm install --global yarn
115
-
116
- `);
117
- process.exit(1);
118
- }
119
- };
package/tsconfig.json DELETED
@@ -1,19 +0,0 @@
1
- {
2
- // "extends": "@mintlify/ts-config",
3
- "compilerOptions": {
4
- "module": "ES2020",
5
- "moduleResolution": "node",
6
- "target": "es2020",
7
- "lib": ["es2020", "dom", "ES2021.String"],
8
- "sourceMap": true,
9
- "outDir": "bin",
10
- "baseUrl": ".",
11
- "paths": {
12
- "*": ["node_modules/*", "src/types/*"]
13
- },
14
- "emitDecoratorMetadata": true,
15
- "experimentalDecorators": true,
16
- "esModuleInterop": true
17
- },
18
- "include": ["src/**/*"]
19
- }