mintlify 1.0.7 → 1.0.8

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 (249) hide show
  1. package/README.md +21 -5
  2. package/bin/constants.js +8 -0
  3. package/bin/constants.js.map +1 -0
  4. package/bin/dev/getOpenApiContext.js +46 -0
  5. package/bin/dev/getOpenApiContext.js.map +1 -0
  6. package/bin/dev/index.js +164 -0
  7. package/bin/dev/index.js.map +1 -0
  8. package/bin/dev/injectNav.js +97 -0
  9. package/bin/dev/injectNav.js.map +1 -0
  10. package/bin/dev/slugToTitle.js +8 -0
  11. package/bin/dev/slugToTitle.js.map +1 -0
  12. package/bin/index.js +45 -224
  13. package/bin/index.js.map +1 -1
  14. package/bin/init-command/index.js +51 -0
  15. package/bin/init-command/index.js.map +1 -0
  16. package/bin/init-command/templates.js +41 -0
  17. package/bin/init-command/templates.js.map +1 -0
  18. package/bin/local-preview/categorizeFiles.js +56 -0
  19. package/bin/local-preview/categorizeFiles.js.map +1 -0
  20. package/bin/local-preview/getOpenApiContext.js +46 -0
  21. package/bin/local-preview/getOpenApiContext.js.map +1 -0
  22. package/bin/local-preview/index.js +138 -0
  23. package/bin/local-preview/index.js.map +1 -0
  24. package/bin/local-preview/injectFavicons.js +72 -0
  25. package/bin/local-preview/injectFavicons.js.map +1 -0
  26. package/bin/local-preview/listener.js +112 -0
  27. package/bin/local-preview/listener.js.map +1 -0
  28. package/bin/local-preview/metadata.js +121 -0
  29. package/bin/local-preview/metadata.js.map +1 -0
  30. package/bin/local-preview/mintConfigFile.js +43 -0
  31. package/bin/local-preview/mintConfigFile.js.map +1 -0
  32. package/bin/local-preview/openApiCheck.js +16 -0
  33. package/bin/local-preview/openApiCheck.js.map +1 -0
  34. package/bin/local-preview/slugToTitle.js +8 -0
  35. package/bin/local-preview/slugToTitle.js.map +1 -0
  36. package/bin/mint/client/.babel-plugin-macrosrc.json +5 -0
  37. package/bin/mint/client/.babelrc +4 -0
  38. package/bin/mint/client/.editorconfig +12 -0
  39. package/bin/mint/client/.eslintrc.json +7 -0
  40. package/bin/mint/client/.prettierignore +4 -0
  41. package/bin/mint/client/.prettierrc +14 -0
  42. package/bin/mint/client/.vscode/launch.json +28 -0
  43. package/bin/mint/client/README.md +46 -0
  44. package/bin/mint/client/jest.config.ts +195 -0
  45. package/bin/mint/client/next-env.d.ts +4 -0
  46. package/bin/mint/client/next.config.js +152 -0
  47. package/bin/mint/client/package.json +140 -0
  48. package/bin/mint/client/postcss.config.cjs +9 -0
  49. package/bin/mint/client/prebuild/faviconConfig.js +35 -0
  50. package/bin/mint/client/prebuild/getOpenApiContext.js +53 -0
  51. package/bin/mint/client/prebuild/index.js +117 -0
  52. package/bin/mint/client/prebuild/injectNav.js +115 -0
  53. package/bin/mint/client/prebuild/slugToTitle.js +7 -0
  54. package/bin/mint/client/rehype/withApiComponents.js +60 -0
  55. package/bin/mint/client/rehype/withCodeBlocks.js +54 -0
  56. package/bin/mint/client/rehype/withLayouts.js +113 -0
  57. package/bin/mint/client/rehype/withLinkRoles.js +13 -0
  58. package/bin/mint/client/rehype/withRawComponents.js +13 -0
  59. package/bin/mint/client/rehype/withStaticProps.js +25 -0
  60. package/bin/mint/client/rehype/withSyntaxHighlighting.js +60 -0
  61. package/bin/mint/client/remark/utils.js +369 -0
  62. package/bin/mint/client/remark/withFrames.js +55 -0
  63. package/bin/mint/client/remark/withImportsInjected.js +36 -0
  64. package/bin/mint/client/remark/withNextLinks.js +37 -0
  65. package/bin/mint/client/remark/withTableOfContents.js +71 -0
  66. package/bin/mint/client/scripts/local-to-docs.js +72 -0
  67. package/bin/mint/client/scripts/local.js +177 -0
  68. package/bin/mint/client/sentry.client.config.js +15 -0
  69. package/bin/mint/client/sentry.properties +4 -0
  70. package/bin/mint/client/sentry.server.config.js +15 -0
  71. package/bin/mint/client/src/analytics/AbstractAnalyticsImplementation.ts +50 -0
  72. package/bin/mint/client/src/analytics/AnalyticsContext.ts +5 -0
  73. package/bin/mint/client/src/analytics/AnalyticsMediator.ts +101 -0
  74. package/bin/mint/client/src/analytics/FakeAnalyticsMediator.ts +9 -0
  75. package/bin/mint/client/src/analytics/GA4Script.tsx +33 -0
  76. package/bin/mint/client/src/analytics/implementations/amplitude.ts +26 -0
  77. package/bin/mint/client/src/analytics/implementations/fathom.ts +38 -0
  78. package/bin/mint/client/src/analytics/implementations/ga4.ts +33 -0
  79. package/bin/mint/client/src/analytics/implementations/hotjar.ts +53 -0
  80. package/bin/mint/client/src/analytics/implementations/mixpanel-browser.d.ts +1 -0
  81. package/bin/mint/client/src/analytics/implementations/mixpanel.ts +52 -0
  82. package/bin/mint/client/src/analytics/implementations/posthog.ts +37 -0
  83. package/bin/mint/client/src/components/Accordion/Accordion.tsx +43 -0
  84. package/bin/mint/client/src/components/Accordion/index.ts +4 -0
  85. package/bin/mint/client/src/components/ApiExample.tsx +9 -0
  86. package/bin/mint/client/src/components/Card.tsx +51 -0
  87. package/bin/mint/client/src/components/CodeGroup.tsx +132 -0
  88. package/bin/mint/client/src/components/Editor.tsx +12 -0
  89. package/bin/mint/client/src/components/Expandable.tsx +40 -0
  90. package/bin/mint/client/src/components/Heading.tsx +84 -0
  91. package/bin/mint/client/src/components/Param.tsx +56 -0
  92. package/bin/mint/client/src/components/Request.tsx +19 -0
  93. package/bin/mint/client/src/components/ResponseField.tsx +33 -0
  94. package/bin/mint/client/src/components/TabBar.tsx +61 -0
  95. package/bin/mint/client/src/config.ts +115 -0
  96. package/bin/mint/client/src/css/bar-of-progress.css +10 -0
  97. package/bin/mint/client/src/css/base.css +29 -0
  98. package/bin/mint/client/src/css/font-awesome.css +7 -0
  99. package/bin/mint/client/src/css/fonts.css +44 -0
  100. package/bin/mint/client/src/css/main.css +11 -0
  101. package/bin/mint/client/src/css/prism.css +270 -0
  102. package/bin/mint/client/src/css/utilities.css +43 -0
  103. package/bin/mint/client/src/enums/components.ts +8 -0
  104. package/bin/mint/client/src/fonts/FiraCode-VF.woff +0 -0
  105. package/bin/mint/client/src/fonts/FiraCode-VF.woff2 +0 -0
  106. package/bin/mint/client/src/fonts/IBMPlexMono-Regular.ttf +0 -0
  107. package/bin/mint/client/src/fonts/IBMPlexMono-SemiBold.ttf +0 -0
  108. package/bin/mint/client/src/fonts/Inter-italic-latin.var.woff2 +0 -0
  109. package/bin/mint/client/src/fonts/Inter-roman-latin.var.woff2 +0 -0
  110. package/bin/mint/client/src/fonts/Pally-Variable.ttf +0 -0
  111. package/bin/mint/client/src/fonts/SourceSansPro-Regular.otf +0 -0
  112. package/bin/mint/client/src/fonts/SourceSerifPro-Regular.ttf +0 -0
  113. package/bin/mint/client/src/fonts/Synonym-Variable.ttf +0 -0
  114. package/bin/mint/client/src/fonts/Ubuntu-Mono-bold.woff2 +0 -0
  115. package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular-subset.woff2 +0 -0
  116. package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular-subset.zopfli.woff +0 -0
  117. package/bin/mint/client/src/fonts/generated/IBMPlexMono-Regular.module.css +11 -0
  118. package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold-subset.woff2 +0 -0
  119. package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold-subset.zopfli.woff +0 -0
  120. package/bin/mint/client/src/fonts/generated/IBMPlexMono-SemiBold.module.css +11 -0
  121. package/bin/mint/client/src/fonts/generated/Pally-Variable-subset.woff2 +0 -0
  122. package/bin/mint/client/src/fonts/generated/Pally-Variable-subset.zopfli.woff +0 -0
  123. package/bin/mint/client/src/fonts/generated/Pally-Variable.module.css +11 -0
  124. package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular-subset.woff2 +0 -0
  125. package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular-subset.zopfli.woff +0 -0
  126. package/bin/mint/client/src/fonts/generated/SourceSerifPro-Regular.module.css +11 -0
  127. package/bin/mint/client/src/fonts/generated/Synonym-Variable-subset.woff2 +0 -0
  128. package/bin/mint/client/src/fonts/generated/Synonym-Variable-subset.zopfli.woff +0 -0
  129. package/bin/mint/client/src/fonts/generated/Synonym-Variable.module.css +11 -0
  130. package/bin/mint/client/src/fonts/generated/TenorSans-Regular-subset.woff2 +0 -0
  131. package/bin/mint/client/src/fonts/generated/TenorSans-Regular-subset.zopfli.woff +0 -0
  132. package/bin/mint/client/src/fonts/generated/TenorSans-Regular.module.css +11 -0
  133. package/bin/mint/client/src/hooks/useActionKey.ts +20 -0
  134. package/bin/mint/client/src/hooks/useIsomorphicLayoutEffect.ts +3 -0
  135. package/bin/mint/client/src/hooks/useMedia.ts +27 -0
  136. package/bin/mint/client/src/hooks/usePrevNext.ts +34 -0
  137. package/bin/mint/client/src/hooks/useTop.ts +15 -0
  138. package/bin/mint/client/src/icons/CopyToClipboard.tsx +33 -0
  139. package/bin/mint/client/src/index.d.ts +1 -0
  140. package/bin/mint/client/src/layouts/ApiSupplemental.tsx +173 -0
  141. package/bin/mint/client/src/layouts/ContentsLayout.tsx +256 -0
  142. package/bin/mint/client/src/layouts/DocumentationLayout.tsx +44 -0
  143. package/bin/mint/client/src/layouts/OpenApiContent.tsx +301 -0
  144. package/bin/mint/client/src/layouts/SidebarLayout.tsx +412 -0
  145. package/bin/mint/client/src/layouts/UserFeedback.tsx +73 -0
  146. package/bin/mint/client/src/layouts/getGroupsInDivision.ts +25 -0
  147. package/bin/mint/client/src/layouts/isPathInGroupPages.ts +10 -0
  148. package/bin/mint/client/src/metadata.ts +58 -0
  149. package/bin/mint/client/src/openapi.ts +3 -0
  150. package/bin/mint/client/src/pages/404.tsx +73 -0
  151. package/bin/mint/client/src/pages/_app.tsx +138 -0
  152. package/bin/mint/client/src/pages/_document.tsx +57 -0
  153. package/bin/mint/client/src/pages/api/issue.ts +10 -0
  154. package/bin/mint/client/src/pages/api/name.ts +8 -0
  155. package/bin/mint/client/src/pages/api/request.ts +31 -0
  156. package/bin/mint/client/src/pages/api/suggest.ts +10 -0
  157. package/bin/mint/client/src/pages/api/syntax-highlighted-json.ts +13 -0
  158. package/bin/mint/client/src/pages/api/utils.ts +6 -0
  159. package/bin/mint/client/src/pages/index.tsx +31 -0
  160. package/bin/mint/client/src/ui/Api.tsx +359 -0
  161. package/bin/mint/client/src/ui/Footer.tsx +124 -0
  162. package/bin/mint/client/src/ui/Header.tsx +370 -0
  163. package/bin/mint/client/src/ui/Logo.tsx +55 -0
  164. package/bin/mint/client/src/ui/PageHeader.tsx +51 -0
  165. package/bin/mint/client/src/ui/Search.tsx +386 -0
  166. package/bin/mint/client/src/ui/ThemeToggle.tsx +285 -0
  167. package/bin/mint/client/src/ui/Title.tsx +22 -0
  168. package/bin/mint/client/src/ui/TopLevelLink.tsx +122 -0
  169. package/bin/mint/client/src/utils/api.ts +252 -0
  170. package/bin/mint/client/src/utils/brands.ts +217 -0
  171. package/bin/mint/client/src/utils/castArray.ts +3 -0
  172. package/bin/mint/client/src/utils/childrenArray.ts +3 -0
  173. package/bin/mint/client/src/utils/fit.ts +27 -0
  174. package/bin/mint/client/src/utils/fontAwesome.ts +577 -0
  175. package/bin/mint/client/src/utils/getAnalyticsConfig.ts +14 -0
  176. package/bin/mint/client/src/utils/getLogoHref.ts +9 -0
  177. package/bin/mint/client/src/utils/getOpenApiContext.ts +26 -0
  178. package/bin/mint/client/src/utils/importAll.ts +6 -0
  179. package/bin/mint/client/src/utils/isObject.ts +3 -0
  180. package/bin/mint/client/src/utils/kebabToTitleCase.ts +3 -0
  181. package/bin/mint/client/src/utils/loadImage.ts +8 -0
  182. package/bin/mint/client/src/utils/slugToTitle.ts +7 -0
  183. package/bin/mint/client/src/utils/wait.ts +5 -0
  184. package/bin/mint/client/tailwind.config.cjs +323 -0
  185. package/bin/mint/client/test/test.test.ts +5 -0
  186. package/bin/mint/client/tsconfig.json +36 -0
  187. package/bin/mint/client/yarn.lock +9702 -0
  188. package/bin/navigation.js +4 -0
  189. package/bin/navigation.js.map +1 -0
  190. package/bin/pageTemplate.js +30 -0
  191. package/bin/pageTemplate.js.map +1 -0
  192. package/bin/scraping/combineNavWithEmptyGroupTitles.js +20 -0
  193. package/bin/scraping/combineNavWithEmptyGroupTitles.js.map +1 -0
  194. package/bin/scraping/getSitemapLinks.js +2 -0
  195. package/bin/scraping/getSitemapLinks.js.map +1 -1
  196. package/bin/scraping/scrapeFileGettingFileNameFromUrl.js +43 -0
  197. package/bin/scraping/scrapeFileGettingFileNameFromUrl.js.map +1 -0
  198. package/bin/scraping/scrapeGettingFileNameFromUrl.js +12 -41
  199. package/bin/scraping/scrapeGettingFileNameFromUrl.js.map +1 -1
  200. package/bin/scraping/scrapePageCommands.js +48 -0
  201. package/bin/scraping/scrapePageCommands.js.map +1 -0
  202. package/bin/scraping/scrapeSectionCommands.js +90 -0
  203. package/bin/scraping/scrapeSectionCommands.js.map +1 -0
  204. package/bin/scraping/site-scrapers/getLinksRecursively.js +33 -0
  205. package/bin/scraping/site-scrapers/getLinksRecursively.js.map +1 -0
  206. package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js +1 -1
  207. package/bin/scraping/site-scrapers/scrapeDocusaurusSection.js.map +1 -1
  208. package/bin/scraping/site-scrapers/scrapeGitBookSection.js +25 -48
  209. package/bin/scraping/site-scrapers/scrapeGitBookSection.js.map +1 -1
  210. package/bin/scraping/site-scrapers/scrapeReadMePage.js +2 -1
  211. package/bin/scraping/site-scrapers/scrapeReadMePage.js.map +1 -1
  212. package/bin/scraping/site-scrapers/scrapeReadMeSection.js +10 -20
  213. package/bin/scraping/site-scrapers/scrapeReadMeSection.js.map +1 -1
  214. package/bin/util.js +21 -1
  215. package/bin/util.js.map +1 -1
  216. package/bin/validation/isValidLink.js +11 -0
  217. package/bin/validation/isValidLink.js.map +1 -0
  218. package/bin/validation/stopIfInvalidLink.js +9 -0
  219. package/bin/validation/stopIfInvalidLink.js.map +1 -0
  220. package/package.json +20 -4
  221. package/src/constants.ts +10 -0
  222. package/src/index.ts +110 -272
  223. package/src/init-command/index.ts +59 -0
  224. package/src/{templates.ts → init-command/templates.ts} +0 -0
  225. package/src/local-preview/categorizeFiles.ts +74 -0
  226. package/src/local-preview/getOpenApiContext.ts +61 -0
  227. package/src/local-preview/index.ts +164 -0
  228. package/src/local-preview/injectFavicons.ts +76 -0
  229. package/src/local-preview/listener.ts +116 -0
  230. package/src/local-preview/metadata.ts +154 -0
  231. package/src/local-preview/mintConfigFile.ts +48 -0
  232. package/src/local-preview/openApiCheck.ts +19 -0
  233. package/src/local-preview/slugToTitle.ts +7 -0
  234. package/src/navigation.ts +12 -0
  235. package/src/pageTemplate.ts +32 -0
  236. package/src/scraping/combineNavWithEmptyGroupTitles.ts +21 -0
  237. package/src/scraping/getSitemapLinks.ts +2 -0
  238. package/src/scraping/scrapeFileGettingFileNameFromUrl.ts +81 -0
  239. package/src/scraping/scrapeGettingFileNameFromUrl.ts +27 -58
  240. package/src/scraping/scrapePageCommands.ts +52 -0
  241. package/src/scraping/scrapeSectionCommands.ts +110 -0
  242. package/src/scraping/site-scrapers/getLinksRecursively.ts +40 -0
  243. package/src/scraping/site-scrapers/scrapeDocusaurusSection.ts +1 -1
  244. package/src/scraping/site-scrapers/scrapeGitBookSection.ts +31 -70
  245. package/src/scraping/site-scrapers/scrapeReadMePage.ts +3 -1
  246. package/src/scraping/site-scrapers/scrapeReadMeSection.ts +21 -38
  247. package/src/util.ts +29 -1
  248. package/src/validation/isValidLink.ts +9 -0
  249. package/src/validation/stopIfInvalidLink.ts +9 -0
@@ -0,0 +1,177 @@
1
+ import SwaggerParser from '@apidevtools/swagger-parser';
2
+ import favicons from 'favicons';
3
+ import { promises as _promises } from 'fs';
4
+ import pkg, { remove } from 'fs-extra';
5
+ import { dirname, resolve } from 'path';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ import faviconConfig from '../prebuild/faviconConfig.js';
9
+ import { createPage, injectNav } from '../prebuild/injectNav.js';
10
+
11
+ const { outputFileSync, readFileSync } = pkg;
12
+ const { readdir, readFile } = _promises;
13
+
14
+ const path = process.argv[2] ?? '../docs';
15
+
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = dirname(__filename);
18
+
19
+ const getFileList = async (dirName, og = dirName) => {
20
+ let files = [];
21
+ const items = await readdir(resolve(dirName), { withFileTypes: true });
22
+
23
+ for (const item of items) {
24
+ if (item.isDirectory()) {
25
+ files = [...files, ...(await getFileList(`${dirName}/${item.name}`, og))];
26
+ } else {
27
+ files.push(`${dirName}/${item.name}`);
28
+ }
29
+ }
30
+
31
+ return files;
32
+ };
33
+
34
+ const getFiles = async () => {
35
+ const fileList = await getFileList(path);
36
+ const markdownFiles = [];
37
+ const staticFiles = [];
38
+ let config = undefined;
39
+ let openApi = undefined;
40
+ const promises = [];
41
+ fileList.forEach((filename) => {
42
+ promises.push(
43
+ (async () => {
44
+ const content = await readFile(resolve(filename));
45
+ if (filename.endsWith('mint.config.json') || filename.endsWith('mint.json')) {
46
+ config = content;
47
+ return;
48
+ }
49
+ const absolutePath = filename.substring(path.length + 1);
50
+ const extension =
51
+ filename.substring(filename.lastIndexOf('.') + 1, filename.length) || filename;
52
+ if (extension && (extension === 'mdx' || extension === 'md' || extension === 'tsx')) {
53
+ markdownFiles.push({
54
+ path: absolutePath,
55
+ content: Buffer.from(content, 'base64'),
56
+ });
57
+ return;
58
+ }
59
+
60
+ if (extension === 'json' || extension === 'yaml' || extension === 'yml') {
61
+ try {
62
+ outputFileSync('openapi', Buffer.from(content, 'base64').toString('utf-8'));
63
+ const api = await SwaggerParser.validate('openapi');
64
+ openApi = Buffer.from(JSON.stringify(api, null, 2), 'utf-8');
65
+ } catch {
66
+ // not valid openApi
67
+ }
68
+ }
69
+ // every other file
70
+ staticFiles.push({
71
+ path: absolutePath,
72
+ content: Buffer.from(content, 'base64'),
73
+ });
74
+ })()
75
+ );
76
+ });
77
+ await Promise.all(promises);
78
+ return { markdownFiles, staticFiles, config, openApi };
79
+ };
80
+
81
+ const injectMarkdownFilesAndNav = (markdownFiles, configObj, openApiObj) => {
82
+ let pages = {};
83
+ markdownFiles.forEach((markdownFile) => {
84
+ const path = __dirname + `/../src/pages/${markdownFile.path}`;
85
+ const page = createPage(markdownFile.path, markdownFile.content, openApiObj);
86
+ if (page != null) {
87
+ pages = {
88
+ ...pages,
89
+ ...page,
90
+ };
91
+ }
92
+ outputFileSync(path, Buffer.from(markdownFile.content), { flag: 'w' });
93
+ });
94
+
95
+ console.log(`📄 ${markdownFiles.length} pages injected`);
96
+
97
+ injectNav(pages, configObj);
98
+ };
99
+
100
+ const injectStaticFiles = (staticFiles) => {
101
+ staticFiles.forEach((staticFile) => {
102
+ const path = __dirname + `/../public/${staticFile.path}`;
103
+ outputFileSync(path, Buffer.from(staticFile.content), { flag: 'w' });
104
+ });
105
+
106
+ console.log(`📄 ${staticFiles.length} static files injected`);
107
+ };
108
+
109
+ const injectConfig = (config) => {
110
+ const path = __dirname + `/../src/mint.json`;
111
+ outputFileSync(path, Buffer.from(config), { flag: 'w' });
112
+ console.log('⚙️ Config file set properly');
113
+ };
114
+
115
+ const injectOpenApi = (openApi) => {
116
+ const path = __dirname + `/../src/openapi.json`;
117
+ if (openApi) {
118
+ outputFileSync(path, Buffer.from(openApi), { flag: 'w' });
119
+ console.log('🖥️ OpenAPI file detected and set as openapi.json');
120
+ return;
121
+ }
122
+ outputFileSync(path, '{}', { flag: 'w' });
123
+ };
124
+
125
+ const injectFavicons = async (config) => {
126
+ const buffer = Buffer.from(config);
127
+ const configJSON = JSON.parse(buffer.toString());
128
+
129
+ if (configJSON?.favicon == null) return;
130
+
131
+ const desiredPath = resolve(__dirname + `/../public/${configJSON.favicon}`);
132
+ const favicon = readFileSync(desiredPath);
133
+ if (favicon == null) return;
134
+ console.log('Generating favicons...');
135
+ favicons(favicon, faviconConfig(config?.name), (err, response) => {
136
+ if (err) {
137
+ console.log(err.message); // Error description e.g. "An unknown error has occurred"
138
+ return;
139
+ }
140
+ response.images.forEach((img) => {
141
+ const path = __dirname + `/../public/favicons/${img.name}`;
142
+ outputFileSync(path, Buffer.from(img.contents), { flag: 'w' });
143
+ });
144
+ response.files.forEach((file) => {
145
+ const path = __dirname + `/../public/favicons/${file.name}`;
146
+ outputFileSync(path, file.contents, { flag: 'w' });
147
+ });
148
+ console.log('Favicons generated');
149
+ });
150
+ };
151
+
152
+ const deleteExistingOpenApi = async () => {
153
+ const path = __dirname + '/../openapi';
154
+ await remove(path);
155
+ };
156
+
157
+ const getAllFilesAndConfig = async () => {
158
+ await deleteExistingOpenApi();
159
+ const { markdownFiles, staticFiles, config, openApi } = await getFiles();
160
+ const openApiObj = openApi == null ? null : JSON.parse(openApi.toString());
161
+ const configObj = JSON.parse(config.toString());
162
+ injectMarkdownFilesAndNav(markdownFiles, configObj, openApiObj);
163
+ injectStaticFiles(staticFiles);
164
+ injectOpenApi(openApi);
165
+ injectConfig(config);
166
+ injectFavicons(config);
167
+ };
168
+
169
+ (async function () {
170
+ try {
171
+ console.log('🔍 Fetching files');
172
+ await getAllFilesAndConfig();
173
+ } catch (error) {
174
+ console.log(error);
175
+ console.error('⚠️ Error while prebuilding documents');
176
+ }
177
+ })();
@@ -0,0 +1,15 @@
1
+ // This file configures the initialization of Sentry on the browser.
2
+ // The config you add here will be used whenever a page is visited.
3
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4
+
5
+ import * as Sentry from '@sentry/nextjs';
6
+
7
+ const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8
+
9
+ if (process.env.VERCEL_ENV === 'production') {
10
+ Sentry.init({
11
+ dsn: SENTRY_DSN || 'https://817b9178a3aa4a01b57a91160d3a24bb@o1352345.ingest.sentry.io/6633662',
12
+ tracesSampleRate: 0.05,
13
+ enabled: process.env.VERCEL_ENV === 'production',
14
+ });
15
+ }
@@ -0,0 +1,4 @@
1
+ defaults.url=https://sentry.io/
2
+ defaults.org=mintlify
3
+ defaults.project=docs-frontend
4
+ cli.executable=../../../.npm/_npx/a8388072043b4cbc/node_modules/@sentry/cli/bin/sentry-cli
@@ -0,0 +1,15 @@
1
+ // This file configures the initialization of Sentry on the server.
2
+ // The config you add here will be used whenever the server handles a request.
3
+ // https://docs.sentry.io/platforms/javascript/guides/nextjs/
4
+
5
+ import * as Sentry from '@sentry/nextjs';
6
+
7
+ const SENTRY_DSN = process.env.SENTRY_DSN || process.env.NEXT_PUBLIC_SENTRY_DSN;
8
+
9
+ if (process.env.VERCEL_ENV === 'production') {
10
+ Sentry.init({
11
+ dsn: SENTRY_DSN || 'https://817b9178a3aa4a01b57a91160d3a24bb@o1352345.ingest.sentry.io/6633662',
12
+ tracesSampleRate: 0.05,
13
+ enabled: process.env.VERCEL_ENV === 'production',
14
+ });
15
+ }
@@ -0,0 +1,50 @@
1
+ export type AmplitudeConfigInterface = {
2
+ apiKey?: string;
3
+ };
4
+
5
+ export type FathomConfigInterface = {
6
+ siteId?: string;
7
+ };
8
+
9
+ export type GoogleAnalyticsConfigInterface = {
10
+ measurementId?: string;
11
+ };
12
+
13
+ export type HotjarConfigInterface = {
14
+ hjid?: string;
15
+ hjsv?: string;
16
+ };
17
+
18
+ export type MixpanelConfigInterface = {
19
+ projectToken?: string;
20
+ };
21
+
22
+ export type PostHogConfigInterface = {
23
+ apiKey?: string;
24
+ apiHost?: string;
25
+ };
26
+
27
+ // We can use & instead of | because all keys are optional
28
+ export type ConfigInterface = AmplitudeConfigInterface &
29
+ FathomConfigInterface &
30
+ GoogleAnalyticsConfigInterface &
31
+ HotjarConfigInterface &
32
+ MixpanelConfigInterface &
33
+ PostHogConfigInterface;
34
+
35
+ // TypeScript doesn't recommend setting interfaces on constructors.
36
+ // How an object is constructed should not matter because an interface
37
+ // only cares about what it does.
38
+ export abstract class AbstractAnalyticsImplementation {
39
+ // New implementations need their own config interface.
40
+ abstract init(implementationConfig: ConfigInterface): void;
41
+ createEventListener(eventName: string): (eventProperties: object) => Promise<void> {
42
+ return async function doNothing(_: object) {};
43
+ }
44
+ onRouteChange(url: string, routeProps: any): void {}
45
+ }
46
+
47
+ export type AnalyticsMediatorInterface = {
48
+ createEventListener: (eventName: string) => (eventConfig: object) => Promise<void>;
49
+ onRouteChange: (url: string, routeProps: any) => void;
50
+ };
@@ -0,0 +1,5 @@
1
+ import { createContext } from 'react';
2
+ import { AnalyticsMediatorInterface } from './AbstractAnalyticsImplementation';
3
+
4
+ const AnalyticsContext = createContext({} as AnalyticsMediatorInterface);
5
+ export default AnalyticsContext;
@@ -0,0 +1,101 @@
1
+ import * as Sentry from '@sentry/nextjs';
2
+
3
+ import {
4
+ AmplitudeConfigInterface,
5
+ AbstractAnalyticsImplementation,
6
+ AnalyticsMediatorInterface,
7
+ FathomConfigInterface,
8
+ HotjarConfigInterface,
9
+ MixpanelConfigInterface,
10
+ PostHogConfigInterface,
11
+ GoogleAnalyticsConfigInterface,
12
+ } from '@/analytics/AbstractAnalyticsImplementation';
13
+ import PostHogAnalytics from '@/analytics/implementations/posthog';
14
+
15
+ import AmplitudeAnalytics from './implementations/amplitude';
16
+ import FathomAnalytics from './implementations/fathom';
17
+ import GA4Analytics from './implementations/ga4';
18
+ import HotjarAnalytics from './implementations/hotjar';
19
+ import MixpanelAnalytics from './implementations/mixpanel';
20
+
21
+ export type AnalyticsMediatorConstructorInterface = {
22
+ amplitude?: AmplitudeConfigInterface;
23
+ fathom?: FathomConfigInterface;
24
+ ga4?: GoogleAnalyticsConfigInterface;
25
+ hotjar?: HotjarConfigInterface;
26
+ mixpanel?: MixpanelConfigInterface;
27
+ posthog?: PostHogConfigInterface;
28
+ };
29
+
30
+ export default class AnalyticsMediator implements AnalyticsMediatorInterface {
31
+ analyticsIntegrations: AbstractAnalyticsImplementation[] = [];
32
+
33
+ constructor(analytics?: AnalyticsMediatorConstructorInterface) {
34
+ // Ran first so we can assign the Sentry tags to false when not set.
35
+ const amplitudeEnabled = Boolean(analytics?.amplitude?.apiKey);
36
+ const fathomEnabled = Boolean(analytics?.fathom?.siteId);
37
+ const ga4Enabled = Boolean(analytics?.ga4?.measurementId);
38
+ const hotjarEnabled = Boolean(analytics?.hotjar?.hjid && analytics?.hotjar?.hjsv);
39
+ const mixpanelEnabled = Boolean(analytics?.mixpanel?.projectToken);
40
+ const posthogEnabled = Boolean(analytics?.posthog?.apiKey);
41
+ Sentry.setTag('amplitude_enabled', `${amplitudeEnabled}`);
42
+ Sentry.setTag('fathom_enabled', `${fathomEnabled}`);
43
+ Sentry.setTag('ga4_enabled', `${ga4Enabled}`);
44
+ Sentry.setTag('hotjar_enabled', `${hotjarEnabled}`);
45
+ Sentry.setTag('mixpanel_enabled', `${mixpanelEnabled}`);
46
+ Sentry.setTag('posthog_enabled', `${posthogEnabled}`);
47
+
48
+ if (!analytics || Object.keys(analytics).length === 0) {
49
+ return;
50
+ }
51
+
52
+ if (amplitudeEnabled) {
53
+ const amplitude = new AmplitudeAnalytics();
54
+ amplitude.init(analytics.amplitude!);
55
+ this.analyticsIntegrations.push(amplitude);
56
+ }
57
+
58
+ if (fathomEnabled) {
59
+ const fathom = new FathomAnalytics();
60
+ fathom.init(analytics.fathom!);
61
+ this.analyticsIntegrations.push(fathom);
62
+ }
63
+
64
+ if (ga4Enabled) {
65
+ const ga4 = new GA4Analytics();
66
+ ga4.init(analytics.ga4!);
67
+ this.analyticsIntegrations.push(ga4);
68
+ }
69
+
70
+ if (hotjarEnabled) {
71
+ const hotjar = new HotjarAnalytics();
72
+ hotjar.init(analytics.hotjar!);
73
+ this.analyticsIntegrations.push(hotjar);
74
+ }
75
+
76
+ if (posthogEnabled) {
77
+ const posthog = new PostHogAnalytics();
78
+ posthog.init(analytics.posthog!);
79
+ this.analyticsIntegrations.push(posthog);
80
+ }
81
+
82
+ if (mixpanelEnabled) {
83
+ const mixpanel = new MixpanelAnalytics();
84
+ mixpanel.init(analytics.mixpanel!);
85
+ this.analyticsIntegrations.push(mixpanel);
86
+ }
87
+ }
88
+
89
+ createEventListener(eventName: string) {
90
+ const listeners = this.analyticsIntegrations.map((integration) =>
91
+ integration.createEventListener(eventName)
92
+ );
93
+ return async function (eventConfig: object) {
94
+ listeners.forEach((listener) => listener(eventConfig));
95
+ };
96
+ }
97
+
98
+ onRouteChange(url: string, routeProps: any) {
99
+ this.analyticsIntegrations.forEach((integration) => integration.onRouteChange(url, routeProps));
100
+ }
101
+ }
@@ -0,0 +1,9 @@
1
+ import { AnalyticsMediatorInterface } from './AbstractAnalyticsImplementation';
2
+
3
+ export default class FakeAnalyticsMediator implements AnalyticsMediatorInterface {
4
+ createEventListener(_: string) {
5
+ return async function () {};
6
+ }
7
+
8
+ onRouteChange(_: string, __: any) {}
9
+ }
@@ -0,0 +1,33 @@
1
+ import Script from 'next/script';
2
+
3
+ import { GoogleAnalyticsConfigInterface } from './AbstractAnalyticsImplementation';
4
+
5
+ export default function GA4Script({ ga4 }: { ga4?: GoogleAnalyticsConfigInterface }) {
6
+ if (!ga4?.measurementId || process.env.NODE_ENV !== 'production') {
7
+ return null;
8
+ }
9
+
10
+ // There is no npm package for Google Analytics 4 so set up happens by placing this script.
11
+ // We can send events using window.gtag.
12
+ return (
13
+ <>
14
+ <Script
15
+ strategy="afterInteractive"
16
+ src={`https://www.googletagmanager.com/gtag/js?id=${ga4.measurementId}`}
17
+ />
18
+ <Script
19
+ strategy="afterInteractive"
20
+ dangerouslySetInnerHTML={{
21
+ __html: `
22
+ window.dataLayer = window.dataLayer || [];
23
+ function gtag(){dataLayer.push(arguments);}
24
+ gtag('js', new Date());
25
+ gtag('config', '${ga4.measurementId}', {
26
+ page_path: window.location.pathname,
27
+ });
28
+ `,
29
+ }}
30
+ />
31
+ </>
32
+ );
33
+ }
@@ -0,0 +1,26 @@
1
+ import { init as amplitudeInit, track } from '@amplitude/analytics-browser';
2
+
3
+ import {
4
+ AbstractAnalyticsImplementation,
5
+ ConfigInterface,
6
+ } from '@/analytics/AbstractAnalyticsImplementation';
7
+
8
+ export default class AmplitudeAnalytics extends AbstractAnalyticsImplementation {
9
+ initialized = false;
10
+
11
+ init(implementationConfig: ConfigInterface) {
12
+ if (implementationConfig?.apiKey && process.env.NODE_ENV === 'production') {
13
+ amplitudeInit(implementationConfig.apiKey);
14
+ this.initialized = true;
15
+ }
16
+ }
17
+
18
+ createEventListener(eventName: string) {
19
+ if (this.initialized) {
20
+ return async function capture(eventProperties: object) {
21
+ track(eventName, eventProperties);
22
+ };
23
+ }
24
+ return async function doNothing(_: object) {};
25
+ }
26
+ }
@@ -0,0 +1,38 @@
1
+ import * as Sentry from '@sentry/nextjs';
2
+
3
+ import {
4
+ AbstractAnalyticsImplementation,
5
+ ConfigInterface,
6
+ } from '@/analytics/AbstractAnalyticsImplementation';
7
+
8
+ export default class FathomAnalytics extends AbstractAnalyticsImplementation {
9
+ initialized = false;
10
+ trackPageview: any;
11
+
12
+ init(implementationConfig: ConfigInterface) {
13
+ if (implementationConfig.siteId && process.env.NODE_ENV === 'production') {
14
+ import('fathom-client')
15
+ .then((_fathom) => {
16
+ if (!this.initialized) {
17
+ _fathom.load(implementationConfig.siteId!);
18
+
19
+ // The Fathom library uses asterisk imports (ie. * as Fathom)
20
+ // so there is no default export for us to store a reference to.
21
+ // Instead, we keep a reference to the method we need.
22
+ this.trackPageview = _fathom.trackPageview;
23
+
24
+ this.initialized = true;
25
+ }
26
+ })
27
+ .catch((e) => {
28
+ Sentry.captureException(e);
29
+ });
30
+ }
31
+ }
32
+
33
+ onRouteChange(_: string, routeProps: any) {
34
+ if (this.trackPageview && !routeProps.shallow) {
35
+ this.trackPageview();
36
+ }
37
+ }
38
+ }
@@ -0,0 +1,33 @@
1
+ import {
2
+ AbstractAnalyticsImplementation,
3
+ ConfigInterface,
4
+ } from '@/analytics/AbstractAnalyticsImplementation';
5
+
6
+ export default class GA4Analytics extends AbstractAnalyticsImplementation {
7
+ measurementId: string | undefined;
8
+
9
+ init(implementationConfig: ConfigInterface) {
10
+ // GA4 setup happens by placing GA4Script.
11
+ // This implementation only exists to send custom events using window.gtag.
12
+ if (process.env.NODE_ENV === 'production') {
13
+ this.measurementId = implementationConfig.measurementId;
14
+ }
15
+ }
16
+
17
+ createEventListener(eventName: string) {
18
+ if (this.measurementId && (window as any).gtag) {
19
+ return async function capture(_: object) {
20
+ (window as any).gtag('event', eventName, {});
21
+ };
22
+ }
23
+ return async function doNothing(_: object) {};
24
+ }
25
+
26
+ onRouteChange(url: string): void {
27
+ if (this.measurementId && (window as any).gtag) {
28
+ (window as any).gtag('config', this.measurementId, {
29
+ page_path: url,
30
+ });
31
+ }
32
+ }
33
+ }
@@ -0,0 +1,53 @@
1
+ import * as Sentry from '@sentry/nextjs';
2
+
3
+ import {
4
+ AbstractAnalyticsImplementation,
5
+ ConfigInterface,
6
+ } from '@/analytics/AbstractAnalyticsImplementation';
7
+
8
+ export default class HotjarAnalytics extends AbstractAnalyticsImplementation {
9
+ initialized = false;
10
+
11
+ // Store events to submit after the library is loaded.
12
+ waitTracking: string[] = [];
13
+ hotjar = {
14
+ event: (name: string) => this.waitTracking.push(name),
15
+ } as any;
16
+
17
+ init(implementationConfig: ConfigInterface) {
18
+ if (
19
+ implementationConfig?.hjid &&
20
+ implementationConfig?.hjsv &&
21
+ process.env.NODE_ENV === 'production'
22
+ ) {
23
+ const hjid = parseInt(implementationConfig.hjid, 10);
24
+ const hjsv = parseInt(implementationConfig.hjsv, 10);
25
+
26
+ import('react-hotjar')
27
+ .then((_hotjar) => {
28
+ if (!this.initialized) {
29
+ // Get default module export
30
+ this.hotjar = _hotjar;
31
+ this.hotjar.initialize(hjid, hjsv);
32
+ this.initialized = true;
33
+
34
+ this.waitTracking.forEach((eventName) => {
35
+ this.hotjar.event(eventName);
36
+ });
37
+ }
38
+
39
+ return this.hotjar;
40
+ })
41
+ .catch((e) => {
42
+ Sentry.captureException(e);
43
+ });
44
+ }
45
+ }
46
+
47
+ createEventListener(eventName: string) {
48
+ const captureFunc = async function capture(this: HotjarAnalytics, _: object) {
49
+ this.hotjar.event(eventName);
50
+ };
51
+ return captureFunc.bind(this);
52
+ }
53
+ }
@@ -0,0 +1 @@
1
+ declare module 'mixpanel-browser';
@@ -0,0 +1,52 @@
1
+ import * as Sentry from '@sentry/nextjs';
2
+
3
+ import {
4
+ AbstractAnalyticsImplementation,
5
+ ConfigInterface,
6
+ } from '@/analytics/AbstractAnalyticsImplementation';
7
+
8
+ export default class MixpanelAnalytics extends AbstractAnalyticsImplementation {
9
+ initialized = false;
10
+
11
+ // Store events to submit after the library is loaded.
12
+ waitTracking: { name: string; properties: object }[] = [];
13
+ mixpanel = {
14
+ track: (name: string, properties: object) => this.waitTracking.push({ name, properties }),
15
+ } as any;
16
+
17
+ init(implementationConfig: ConfigInterface) {
18
+ if (implementationConfig.projectToken && process.env.NODE_ENV === 'production') {
19
+ // Dynamic import reduces our First Load JS by 18 kB
20
+ import('mixpanel-browser')
21
+ .then((_mixpanel) => {
22
+ if (!this.initialized) {
23
+ // Get default module export
24
+ const mixpanelLib = _mixpanel.default;
25
+ mixpanelLib.init(implementationConfig.projectToken, {
26
+ secure_cookie: true,
27
+ });
28
+
29
+ this.initialized = true;
30
+ this.mixpanel = mixpanelLib;
31
+
32
+ this.waitTracking.forEach((event) => {
33
+ this.mixpanel.track(event.name, event.properties);
34
+ });
35
+ }
36
+ })
37
+ .catch((e) => {
38
+ Sentry.captureException(e);
39
+ });
40
+ } else {
41
+ // Stop storing events, we don't need them because the library will not be loaded.
42
+ this.mixpanel.track = (_name: string, _properties: object) => {};
43
+ }
44
+ }
45
+
46
+ createEventListener(eventName: string) {
47
+ const captureFunc = async function capture(this: MixpanelAnalytics, eventProperties: object) {
48
+ this.mixpanel.track(eventName, eventProperties);
49
+ };
50
+ return captureFunc.bind(this);
51
+ }
52
+ }
@@ -0,0 +1,37 @@
1
+ import Router from 'next/router';
2
+ import posthog from 'posthog-js';
3
+
4
+ import {
5
+ AbstractAnalyticsImplementation,
6
+ ConfigInterface,
7
+ } from '@/analytics/AbstractAnalyticsImplementation';
8
+
9
+ export default class PostHogAnalytics extends AbstractAnalyticsImplementation {
10
+ initialized = false;
11
+
12
+ init(implementationConfig: ConfigInterface) {
13
+ if (implementationConfig.apiKey && !this.initialized) {
14
+ this.initialized = true;
15
+ // apiHost only has to be passed in if the user is self-hosting PostHog
16
+ posthog.init(implementationConfig.apiKey, {
17
+ api_host: implementationConfig.apiHost || 'https://app.posthog.com',
18
+ loaded: (posthogInstance) => {
19
+ if (process.env.NODE_ENV !== 'production') posthogInstance.opt_out_capturing();
20
+ },
21
+ });
22
+
23
+ // Track page views
24
+ const handleRouteChange = () => posthog.capture('$pageview');
25
+ Router.events.on('routeChangeComplete', handleRouteChange);
26
+ }
27
+ }
28
+
29
+ createEventListener(eventName: string) {
30
+ if (this.initialized) {
31
+ return async function capture(eventProperties: object) {
32
+ posthog.capture(eventName, eventProperties);
33
+ };
34
+ }
35
+ return async function doNothing(_: object) {};
36
+ }
37
+ }