@docusaurus/core 2.0.0-beta.1decd6f80 → 2.0.0-beta.20

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 (220) hide show
  1. package/bin/beforeCli.mjs +138 -0
  2. package/bin/docusaurus.mjs +228 -0
  3. package/lib/babel/preset.d.ts +8 -3
  4. package/lib/babel/preset.js +8 -7
  5. package/lib/client/.eslintrc.js +2 -4
  6. package/lib/client/App.d.ts +2 -3
  7. package/lib/client/App.js +30 -27
  8. package/lib/client/BaseUrlIssueBanner/index.d.ts +27 -0
  9. package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.js → BaseUrlIssueBanner/index.js} +24 -14
  10. package/lib/client/{baseUrlIssueBanner → BaseUrlIssueBanner}/styles.module.css +0 -0
  11. package/lib/client/ClientLifecyclesDispatcher.d.ts +16 -0
  12. package/lib/client/ClientLifecyclesDispatcher.js +39 -0
  13. package/lib/client/LinksCollector.d.ts +3 -3
  14. package/lib/client/LinksCollector.js +8 -13
  15. package/lib/client/PendingNavigation.d.ts +17 -3
  16. package/lib/client/PendingNavigation.js +39 -72
  17. package/lib/client/{baseUrlIssueBanner/BaseUrlIssueBanner.d.ts → SiteMetadataDefaults.d.ts} +1 -2
  18. package/lib/client/SiteMetadataDefaults.js +19 -0
  19. package/lib/{choosePort.d.ts → client/browserContext.d.ts} +5 -5
  20. package/lib/client/browserContext.js +22 -0
  21. package/lib/client/clientEntry.js +14 -9
  22. package/lib/client/docusaurus.d.ts +11 -5
  23. package/lib/client/docusaurus.js +29 -42
  24. package/lib/client/docusaurusContext.d.ts +12 -0
  25. package/lib/client/docusaurusContext.js +25 -0
  26. package/lib/client/exports/BrowserOnly.d.ts +3 -5
  27. package/lib/client/exports/BrowserOnly.js +14 -7
  28. package/lib/client/exports/ComponentCreator.d.ts +1 -2
  29. package/lib/client/exports/ComponentCreator.js +67 -41
  30. package/lib/client/exports/ErrorBoundary.d.ts +18 -0
  31. package/lib/client/exports/ErrorBoundary.js +35 -0
  32. package/lib/client/exports/Head.d.ts +2 -3
  33. package/lib/client/exports/Head.js +3 -4
  34. package/lib/client/exports/Interpolate.d.ts +2 -2
  35. package/lib/client/exports/Interpolate.js +20 -49
  36. package/lib/client/exports/Link.d.ts +4 -10
  37. package/lib/client/exports/Link.js +44 -38
  38. package/lib/client/exports/Translate.d.ts +1 -1
  39. package/lib/client/exports/Translate.js +14 -9
  40. package/lib/client/exports/constants.js +1 -11
  41. package/lib/client/exports/isInternalUrl.js +1 -1
  42. package/lib/client/exports/renderRoutes.d.ts +1 -2
  43. package/lib/client/exports/renderRoutes.js +1 -2
  44. package/lib/client/exports/router.d.ts +1 -1
  45. package/lib/client/exports/router.js +1 -1
  46. package/lib/client/exports/useBaseUrl.js +11 -14
  47. package/lib/client/exports/useDocusaurusContext.d.ts +2 -3
  48. package/lib/client/exports/useDocusaurusContext.js +3 -9
  49. package/lib/client/exports/useGlobalData.d.ts +4 -3
  50. package/lib/client/exports/useGlobalData.js +9 -13
  51. package/lib/{server/versions/__tests/index.test.d.ts → client/exports/useIsBrowser.d.ts} +1 -1
  52. package/lib/client/exports/useIsBrowser.js +11 -0
  53. package/lib/client/exports/useRouteContext.d.ts +8 -0
  54. package/lib/client/exports/useRouteContext.js +15 -0
  55. package/lib/client/flat.d.ts +12 -2
  56. package/lib/client/flat.js +19 -15
  57. package/lib/client/normalizeLocation.d.ts +2 -5
  58. package/lib/client/normalizeLocation.js +14 -10
  59. package/lib/client/prefetch.d.ts +1 -2
  60. package/lib/client/prefetch.js +11 -31
  61. package/lib/client/preload.d.ts +3 -4
  62. package/lib/client/preload.js +7 -12
  63. package/lib/client/routeContext.d.ts +13 -0
  64. package/lib/client/routeContext.js +31 -0
  65. package/lib/client/serverEntry.d.ts +10 -0
  66. package/lib/client/serverEntry.js +91 -132
  67. package/lib/client/theme-fallback/Error/index.d.ts +10 -0
  68. package/lib/client/theme-fallback/Error/index.js +45 -0
  69. package/lib/client/theme-fallback/Layout/index.d.ts +10 -0
  70. package/lib/client/theme-fallback/Layout/index.js +2 -26
  71. package/lib/client/theme-fallback/Loading/index.d.ts +9 -0
  72. package/lib/client/theme-fallback/Loading/index.js +49 -115
  73. package/lib/client/{exports/context.js → theme-fallback/NotFound/index.d.ts} +2 -2
  74. package/lib/client/theme-fallback/NotFound/index.js +19 -18
  75. package/lib/client/theme-fallback/Root/index.d.ts +10 -0
  76. package/lib/client/theme-fallback/Root/index.js +2 -6
  77. package/lib/{server/html-tags/htmlTags.d.ts → client/theme-fallback/SiteMetadata/index.d.ts} +2 -1
  78. package/lib/client/theme-fallback/SiteMetadata/index.js +10 -0
  79. package/lib/commands/build.d.ts +6 -2
  80. package/lib/commands/build.js +77 -61
  81. package/lib/commands/clear.d.ts +7 -1
  82. package/lib/commands/clear.js +32 -20
  83. package/lib/commands/deploy.d.ts +5 -2
  84. package/lib/commands/deploy.js +91 -71
  85. package/lib/commands/external.d.ts +2 -2
  86. package/lib/commands/external.js +6 -11
  87. package/lib/commands/serve.d.ts +7 -2
  88. package/lib/commands/serve.js +31 -18
  89. package/lib/commands/start.d.ts +8 -2
  90. package/lib/commands/start.js +105 -91
  91. package/lib/commands/swizzle/actions.d.ts +23 -0
  92. package/lib/commands/swizzle/actions.js +102 -0
  93. package/lib/commands/swizzle/common.d.ts +33 -0
  94. package/lib/commands/swizzle/common.js +56 -0
  95. package/lib/commands/swizzle/components.d.ts +29 -0
  96. package/lib/commands/swizzle/components.js +200 -0
  97. package/lib/commands/swizzle/config.d.ts +10 -0
  98. package/lib/commands/swizzle/config.js +83 -0
  99. package/lib/{server/client-modules/index.d.ts → commands/swizzle/context.d.ts} +2 -2
  100. package/lib/commands/swizzle/context.js +24 -0
  101. package/lib/commands/swizzle/index.d.ts +8 -0
  102. package/lib/commands/swizzle/index.js +116 -0
  103. package/lib/commands/swizzle/prompts.d.ts +12 -0
  104. package/lib/commands/swizzle/prompts.js +110 -0
  105. package/lib/{client/exports/context.d.ts → commands/swizzle/tables.d.ts} +3 -4
  106. package/lib/commands/swizzle/tables.js +113 -0
  107. package/lib/commands/swizzle/themes.d.ts +20 -0
  108. package/lib/commands/swizzle/themes.js +106 -0
  109. package/lib/commands/writeHeadingIds.d.ts +2 -6
  110. package/lib/commands/writeHeadingIds.js +21 -81
  111. package/lib/commands/writeTranslations.d.ts +4 -5
  112. package/lib/commands/writeTranslations.js +41 -23
  113. package/lib/index.d.ts +9 -9
  114. package/lib/index.js +14 -14
  115. package/lib/server/brokenLinks.d.ts +4 -17
  116. package/lib/server/brokenLinks.js +65 -54
  117. package/lib/server/clientModules.d.ts +12 -0
  118. package/lib/server/clientModules.js +20 -0
  119. package/lib/server/config.d.ts +5 -2
  120. package/lib/server/config.js +14 -6
  121. package/lib/server/configValidation.d.ts +4 -2
  122. package/lib/server/configValidation.js +96 -39
  123. package/lib/server/getHostPort.d.ts +14 -0
  124. package/lib/server/getHostPort.js +79 -0
  125. package/lib/server/htmlTags.d.ts +12 -0
  126. package/lib/server/htmlTags.js +62 -0
  127. package/lib/server/i18n.d.ts +3 -13
  128. package/lib/server/i18n.js +19 -55
  129. package/lib/server/index.d.ts +28 -6
  130. package/lib/server/index.js +82 -171
  131. package/lib/server/plugins/configs.d.ts +51 -0
  132. package/lib/server/plugins/configs.js +101 -0
  133. package/lib/server/plugins/index.d.ts +10 -10
  134. package/lib/server/plugins/index.js +74 -125
  135. package/lib/server/plugins/init.d.ts +6 -9
  136. package/lib/server/plugins/init.js +43 -108
  137. package/lib/server/plugins/moduleShorthand.d.ts +9 -0
  138. package/lib/server/plugins/moduleShorthand.js +46 -0
  139. package/lib/server/plugins/pluginIds.d.ts +6 -2
  140. package/lib/server/plugins/pluginIds.js +12 -7
  141. package/lib/server/plugins/presets.d.ts +12 -0
  142. package/lib/server/plugins/presets.js +49 -0
  143. package/lib/server/plugins/routeConfig.d.ts +11 -0
  144. package/lib/server/plugins/routeConfig.js +54 -0
  145. package/lib/server/plugins/synthetic.d.ts +20 -0
  146. package/lib/server/plugins/synthetic.js +112 -0
  147. package/lib/server/routes.d.ts +39 -7
  148. package/lib/server/routes.js +185 -95
  149. package/lib/server/siteMetadata.d.ts +12 -0
  150. package/lib/server/siteMetadata.js +81 -0
  151. package/lib/server/translations/translations.d.ts +13 -17
  152. package/lib/server/translations/translations.js +37 -61
  153. package/lib/server/translations/translationsExtractor.d.ts +10 -5
  154. package/lib/server/translations/translationsExtractor.js +159 -121
  155. package/lib/server/utils.d.ts +9 -3
  156. package/lib/server/utils.js +7 -9
  157. package/lib/webpack/aliases/index.d.ts +34 -0
  158. package/lib/webpack/aliases/index.js +106 -0
  159. package/lib/webpack/base.d.ts +3 -4
  160. package/lib/webpack/base.js +53 -55
  161. package/lib/webpack/client.d.ts +3 -3
  162. package/lib/webpack/client.js +12 -19
  163. package/lib/webpack/plugins/ChunkAssetPlugin.d.ts +13 -3
  164. package/lib/webpack/plugins/ChunkAssetPlugin.js +24 -17
  165. package/lib/webpack/plugins/CleanWebpackPlugin.d.ts +8 -8
  166. package/lib/webpack/plugins/CleanWebpackPlugin.js +10 -16
  167. package/lib/webpack/plugins/LogPlugin.d.ts +1 -1
  168. package/lib/webpack/plugins/LogPlugin.js +4 -5
  169. package/lib/webpack/plugins/WaitPlugin.d.ts +3 -3
  170. package/lib/webpack/plugins/WaitPlugin.js +1 -1
  171. package/lib/webpack/server.d.ts +5 -5
  172. package/lib/webpack/server.js +18 -8
  173. package/lib/{client → webpack}/templates/index.html.template.ejs +0 -0
  174. package/lib/webpack/templates/ssr.html.template.d.ts +8 -0
  175. package/lib/{client → webpack}/templates/ssr.html.template.js +5 -4
  176. package/lib/webpack/utils.d.ts +16 -31
  177. package/lib/webpack/utils.js +59 -177
  178. package/package.json +77 -73
  179. package/bin/docusaurus.js +0 -326
  180. package/lib/.tsbuildinfo +0 -5682
  181. package/lib/choosePort.js +0 -105
  182. package/lib/client/.tsbuildinfo +0 -4127
  183. package/lib/client/client-lifecycles-dispatcher.d.ts +0 -12
  184. package/lib/client/client-lifecycles-dispatcher.js +0 -27
  185. package/lib/client/nprogress.css +0 -36
  186. package/lib/commands/buildRemoteBranchUrl.d.ts +0 -7
  187. package/lib/commands/buildRemoteBranchUrl.js +0 -27
  188. package/lib/commands/commandUtils.d.ts +0 -3
  189. package/lib/commands/commandUtils.js +0 -21
  190. package/lib/commands/swizzle.d.ts +0 -9
  191. package/lib/commands/swizzle.js +0 -245
  192. package/lib/constants.d.ts +0 -18
  193. package/lib/constants.js +0 -23
  194. package/lib/server/client-modules/index.js +0 -14
  195. package/lib/server/duplicateRoutes.d.ts +0 -10
  196. package/lib/server/duplicateRoutes.js +0 -38
  197. package/lib/server/html-tags/htmlTags.js +0 -39
  198. package/lib/server/html-tags/index.d.ts +0 -9
  199. package/lib/server/html-tags/index.js +0 -43
  200. package/lib/server/loadSetup.d.ts +0 -9
  201. package/lib/server/loadSetup.js +0 -25
  202. package/lib/server/presets/index.d.ts +0 -11
  203. package/lib/server/presets/index.js +0 -48
  204. package/lib/server/themes/alias.d.ts +0 -8
  205. package/lib/server/themes/alias.js +0 -39
  206. package/lib/server/themes/index.d.ts +0 -8
  207. package/lib/server/themes/index.js +0 -35
  208. package/lib/server/versions/__fixtures__/dummy-plugin.js +0 -0
  209. package/lib/server/versions/__fixtures__/package.json +0 -3
  210. package/lib/server/versions/__tests/index.test.js +0 -25
  211. package/lib/server/versions/index.d.ts +0 -10
  212. package/lib/server/versions/index.js +0 -50
  213. package/lib/webpack/react-dev-utils-webpack5/README.md +0 -11
  214. package/lib/webpack/react-dev-utils-webpack5/evalSourceMapMiddleware.js +0 -57
  215. package/lib/webpack/react-dev-utils-webpack5/formatWebpackMessages.js +0 -138
  216. package/lib/webpack/react-dev-utils-webpack5/webpackHotDevClient.js +0 -285
  217. package/lib/webpack/sharedModuleAliases.d.ts +0 -10
  218. package/lib/webpack/sharedModuleAliases.js +0 -18
  219. package/tsconfig.client.json +0 -13
  220. package/tsconfig.json +0 -13
@@ -6,57 +6,54 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.handleBrokenLinks = exports.filterExistingFileLinks = exports.getBrokenLinksErrorMessage = exports.getAllBrokenLinks = void 0;
9
+ exports.handleBrokenLinks = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const react_router_config_1 = require("react-router-config");
12
- const resolve_pathname_1 = tslib_1.__importDefault(require("resolve-pathname"));
13
12
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
14
- const lodash_1 = require("lodash");
13
+ const lodash_1 = tslib_1.__importDefault(require("lodash"));
15
14
  const utils_1 = require("@docusaurus/utils");
16
15
  const utils_2 = require("./utils");
17
16
  const path_1 = tslib_1.__importDefault(require("path"));
18
- function toReactRouterRoutes(routes) {
19
- // @ts-expect-error: types incompatible???
20
- return routes;
21
- }
17
+ const combine_promises_1 = tslib_1.__importDefault(require("combine-promises"));
18
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
22
19
  // matchRoutes does not support qs/anchors, so we remove it!
23
20
  function onlyPathname(link) {
24
21
  return link.split('#')[0].split('?')[0];
25
22
  }
26
23
  function getPageBrokenLinks({ pagePath, pageLinks, routes, }) {
27
- // ReactRouter is able to support links like ./../somePath
28
- // but matchRoutes does not do this resolving internally
29
- // we must resolve the links before using matchRoutes
30
- // resolvePathname is used internally by ReactRouter
24
+ // ReactRouter is able to support links like ./../somePath but `matchRoutes`
25
+ // does not do this resolution internally. We must resolve the links before
26
+ // using `matchRoutes`. `resolvePathname` is used internally by React Router
31
27
  function resolveLink(link) {
32
- const resolvedLink = resolve_pathname_1.default(onlyPathname(link), pagePath);
28
+ const resolvedLink = (0, utils_1.resolvePathname)(onlyPathname(link), pagePath);
33
29
  return { link, resolvedLink };
34
30
  }
35
31
  function isBrokenLink(link) {
36
32
  const matchedRoutes = [link, decodeURI(link)]
37
- .map((l) => react_router_config_1.matchRoutes(toReactRouterRoutes(routes), l))
38
- .reduce((prev, cur) => prev.concat(cur));
33
+ // @ts-expect-error: React router types RouteConfig with an actual React
34
+ // component, but we load route components with string paths.
35
+ // We don't actually access component here, so it's fine.
36
+ .map((l) => (0, react_router_config_1.matchRoutes)(routes, l))
37
+ .flat();
39
38
  return matchedRoutes.length === 0;
40
39
  }
41
40
  return pageLinks.map(resolveLink).filter((l) => isBrokenLink(l.resolvedLink));
42
41
  }
43
- // The route defs can be recursive, and have a parent match-all route
44
- // We don't want to match broken links like /docs/brokenLink against /docs/*
45
- // For this reason, we only consider the "final routes", that do not have subroutes
46
- // We also need to remove the match all 404 route
42
+ /**
43
+ * The route defs can be recursive, and have a parent match-all route. We don't
44
+ * want to match broken links like /docs/brokenLink against /docs/*. For this
45
+ * reason, we only consider the "final routes" that do not have subroutes.
46
+ * We also need to remove the match-all 404 route
47
+ */
47
48
  function filterIntermediateRoutes(routesInput) {
48
49
  const routesWithout404 = routesInput.filter((route) => route.path !== '*');
49
- return utils_2.getAllFinalRoutes(routesWithout404);
50
+ return (0, utils_2.getAllFinalRoutes)(routesWithout404);
50
51
  }
51
52
  function getAllBrokenLinks({ allCollectedLinks, routes, }) {
52
53
  const filteredRoutes = filterIntermediateRoutes(routes);
53
- const allBrokenLinks = lodash_1.mapValues(allCollectedLinks, (pageLinks, pagePath) => {
54
- return getPageBrokenLinks({ pageLinks, pagePath, routes: filteredRoutes });
55
- });
56
- // remove pages without any broken link
57
- return lodash_1.pickBy(allBrokenLinks, (brokenLinks) => brokenLinks.length > 0);
54
+ const allBrokenLinks = lodash_1.default.mapValues(allCollectedLinks, (pageLinks, pagePath) => getPageBrokenLinks({ pageLinks, pagePath, routes: filteredRoutes }));
55
+ return lodash_1.default.pickBy(allBrokenLinks, (brokenLinks) => brokenLinks.length > 0);
58
56
  }
59
- exports.getAllBrokenLinks = getAllBrokenLinks;
60
57
  function getBrokenLinksErrorMessage(allBrokenLinks) {
61
58
  if (Object.keys(allBrokenLinks).length === 0) {
62
59
  return undefined;
@@ -66,16 +63,20 @@ function getBrokenLinksErrorMessage(allBrokenLinks) {
66
63
  return `${brokenLink.link}${showResolvedLink ? ` (resolved as: ${brokenLink.resolvedLink})` : ''}`;
67
64
  }
68
65
  function pageBrokenLinksMessage(pagePath, brokenLinks) {
69
- return `\n- On source page path = ${pagePath}:\n -> linking to ${brokenLinks
66
+ return `
67
+ - On source page path = ${pagePath}:
68
+ -> linking to ${brokenLinks
70
69
  .map(brokenLinkMessage)
71
70
  .join('\n -> linking to ')}`;
72
71
  }
73
- // If there's a broken link appearing very often, it is probably a broken link on the layout!
74
- // Add an additional message in such case to help user figure this out.
75
- // see https://github.com/facebook/docusaurus/issues/3567#issuecomment-706973805
72
+ /**
73
+ * If there's a broken link appearing very often, it is probably a broken link
74
+ * on the layout. Add an additional message in such case to help user figure
75
+ * this out. See https://github.com/facebook/docusaurus/issues/3567#issuecomment-706973805
76
+ */
76
77
  function getLayoutBrokenLinksHelpMessage() {
77
- const flatList = lodash_1.flatten(Object.entries(allBrokenLinks).map(([pagePage, brokenLinks]) => brokenLinks.map((brokenLink) => ({ pagePage, brokenLink }))));
78
- const countedBrokenLinks = lodash_1.countBy(flatList, (item) => item.brokenLink.link);
78
+ const flatList = Object.entries(allBrokenLinks).flatMap(([pagePage, brokenLinks]) => brokenLinks.map((brokenLink) => ({ pagePage, brokenLink })));
79
+ const countedBrokenLinks = lodash_1.default.countBy(flatList, (item) => item.brokenLink.link);
79
80
  const FrequencyThreshold = 5; // Is this a good value?
80
81
  const frequentLinks = Object.entries(countedBrokenLinks)
81
82
  .filter(([, count]) => count >= FrequencyThreshold)
@@ -83,51 +84,61 @@ function getBrokenLinksErrorMessage(allBrokenLinks) {
83
84
  if (frequentLinks.length === 0) {
84
85
  return '';
85
86
  }
86
- return `\n\nIt looks like some of the broken links we found appear in many pages of your site.\nMaybe those broken links appear on all pages through your site layout?\nWe recommend that you check your theme configuration for such links (particularly, theme navbar and footer).\nFrequent broken links are linking to:\n- ${frequentLinks.join(`\n- `)}\n`;
87
+ return logger_1.default.interpolate `
88
+
89
+ It looks like some of the broken links we found appear in many pages of your site.
90
+ Maybe those broken links appear on all pages through your site layout?
91
+ We recommend that you check your theme configuration for such links (particularly, theme navbar and footer).
92
+ Frequent broken links are linking to:${frequentLinks}`;
87
93
  }
88
- return (`Docusaurus found broken links!\n\nPlease check the pages of your site in the list below, and make sure you don't reference any path that does not exist.\nNote: it's possible to ignore broken links with the 'onBrokenLinks' Docusaurus configuration, and let the build pass.${getLayoutBrokenLinksHelpMessage()}` +
89
- `\n\nExhaustive list of all broken links found:\n${Object.entries(allBrokenLinks)
90
- .map(([pagePath, brokenLinks]) => pageBrokenLinksMessage(pagePath, brokenLinks))
91
- .join('\n')}
92
- `);
94
+ return `Docusaurus found broken links!
95
+
96
+ Please check the pages of your site in the list below, and make sure you don't reference any path that does not exist.
97
+ Note: it's possible to ignore broken links with the 'onBrokenLinks' Docusaurus configuration, and let the build pass.${getLayoutBrokenLinksHelpMessage()}
98
+
99
+ Exhaustive list of all broken links found:
100
+ ${Object.entries(allBrokenLinks)
101
+ .map(([pagePath, brokenLinks]) => pageBrokenLinksMessage(pagePath, brokenLinks))
102
+ .join('\n')}
103
+ `;
93
104
  }
94
- exports.getBrokenLinksErrorMessage = getBrokenLinksErrorMessage;
95
- function isExistingFile(filePath) {
105
+ async function isExistingFile(filePath) {
96
106
  try {
97
- return fs_extra_1.default.statSync(filePath).isFile();
107
+ return (await fs_extra_1.default.stat(filePath)).isFile();
98
108
  }
99
- catch (e) {
109
+ catch {
100
110
  return false;
101
111
  }
102
112
  }
103
113
  // If a file actually exist on the file system, we know the link is valid
104
114
  // even if docusaurus does not know about this file, so we don't report it
105
115
  async function filterExistingFileLinks({ baseUrl, outDir, allCollectedLinks, }) {
106
- // not easy to make this async :'(
107
- function linkFileExists(link) {
116
+ async function linkFileExists(link) {
108
117
  // /baseUrl/javadoc/ -> /outDir/javadoc
109
- const baseFilePath = utils_1.removeSuffix(`${outDir}/${utils_1.removePrefix(link, baseUrl)}`, '/');
118
+ const baseFilePath = onlyPathname((0, utils_1.removeSuffix)(`${outDir}/${(0, utils_1.removePrefix)(link, baseUrl)}`, '/'));
110
119
  // -> /outDir/javadoc
111
120
  // -> /outDir/javadoc.html
112
121
  // -> /outDir/javadoc/index.html
113
122
  const filePathsToTry = [baseFilePath];
114
123
  if (!path_1.default.extname(baseFilePath)) {
115
- filePathsToTry.push(`${baseFilePath}.html`);
116
- filePathsToTry.push(path_1.default.join(baseFilePath, 'index.html'));
124
+ filePathsToTry.push(`${baseFilePath}.html`, path_1.default.join(baseFilePath, 'index.html'));
117
125
  }
118
- return filePathsToTry.some(isExistingFile);
126
+ for (const file of filePathsToTry) {
127
+ if (await isExistingFile(file)) {
128
+ return true;
129
+ }
130
+ }
131
+ return false;
119
132
  }
120
- return lodash_1.mapValues(allCollectedLinks, (links) => {
121
- return links.filter((link) => !linkFileExists(link));
122
- });
133
+ return (0, combine_promises_1.default)(lodash_1.default.mapValues(allCollectedLinks, async (links) => (await Promise.all(links.map(async (link) => ((await linkFileExists(link)) ? '' : link)))).filter(Boolean)));
123
134
  }
124
- exports.filterExistingFileLinks = filterExistingFileLinks;
125
135
  async function handleBrokenLinks({ allCollectedLinks, onBrokenLinks, routes, baseUrl, outDir, }) {
126
136
  if (onBrokenLinks === 'ignore') {
127
137
  return;
128
138
  }
129
- // If we link to a file like /myFile.zip, and the file actually exist for the file system
130
- // it is not a broken link, it may simply be a link to an existing static file...
139
+ // If we link to a file like /myFile.zip, and the file actually exist for the
140
+ // file system. It is not a broken link, it may simply be a link to an
141
+ // existing static file...
131
142
  const allCollectedLinksFiltered = await filterExistingFileLinks({
132
143
  allCollectedLinks,
133
144
  baseUrl,
@@ -139,7 +150,7 @@ async function handleBrokenLinks({ allCollectedLinks, onBrokenLinks, routes, bas
139
150
  });
140
151
  const errorMessage = getBrokenLinksErrorMessage(allBrokenLinks);
141
152
  if (errorMessage) {
142
- utils_1.reportMessage(errorMessage, onBrokenLinks);
153
+ (0, utils_1.reportMessage)(errorMessage, onBrokenLinks);
143
154
  }
144
155
  }
145
156
  exports.handleBrokenLinks = handleBrokenLinks;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import type { LoadedPlugin } from '@docusaurus/types';
8
+ /**
9
+ * Runs the `getClientModules` lifecycle. The returned file paths are all
10
+ * absolute.
11
+ */
12
+ export declare function loadClientModules(plugins: LoadedPlugin[]): string[];
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.loadClientModules = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const path_1 = tslib_1.__importDefault(require("path"));
12
+ /**
13
+ * Runs the `getClientModules` lifecycle. The returned file paths are all
14
+ * absolute.
15
+ */
16
+ function loadClientModules(plugins) {
17
+ return plugins.flatMap((plugin) => plugin.getClientModules?.().map((p) => path_1.default.resolve(plugin.path, p)) ??
18
+ []);
19
+ }
20
+ exports.loadClientModules = loadClientModules;
@@ -4,5 +4,8 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import { DocusaurusConfig } from '@docusaurus/types';
8
- export default function loadConfig(configPath: string): DocusaurusConfig;
7
+ import type { LoadContext } from '@docusaurus/types';
8
+ export declare function loadSiteConfig({ siteDir, customConfigFilePath, }: {
9
+ siteDir: string;
10
+ customConfigFilePath?: string;
11
+ }): Promise<Pick<LoadContext, 'siteConfig' | 'siteConfigPath'>>;
@@ -6,15 +6,23 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.loadSiteConfig = void 0;
9
10
  const tslib_1 = require("tslib");
11
+ const path_1 = tslib_1.__importDefault(require("path"));
10
12
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
11
13
  const import_fresh_1 = tslib_1.__importDefault(require("import-fresh"));
14
+ const utils_1 = require("@docusaurus/utils");
12
15
  const configValidation_1 = require("./configValidation");
13
- function loadConfig(configPath) {
14
- if (!fs_extra_1.default.existsSync(configPath)) {
15
- throw new Error(`Config file "${configPath}" not found`);
16
+ async function loadSiteConfig({ siteDir, customConfigFilePath, }) {
17
+ const siteConfigPath = path_1.default.resolve(siteDir, customConfigFilePath ?? utils_1.DEFAULT_CONFIG_FILE_NAME);
18
+ if (!(await fs_extra_1.default.pathExists(siteConfigPath))) {
19
+ throw new Error(`Config file at "${siteConfigPath}" not found.`);
16
20
  }
17
- const loadedConfig = import_fresh_1.default(configPath);
18
- return configValidation_1.validateConfig(loadedConfig);
21
+ const importedConfig = (0, import_fresh_1.default)(siteConfigPath);
22
+ const loadedConfig = typeof importedConfig === 'function'
23
+ ? await importedConfig()
24
+ : await importedConfig;
25
+ const siteConfig = (0, configValidation_1.validateConfig)(loadedConfig);
26
+ return { siteConfig, siteConfigPath };
19
27
  }
20
- exports.default = loadConfig;
28
+ exports.loadSiteConfig = loadSiteConfig;
@@ -4,7 +4,9 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import { DocusaurusConfig, I18nConfig } from '@docusaurus/types';
7
+ import type { DocusaurusConfig, I18nConfig } from '@docusaurus/types';
8
+ import { Joi } from '@docusaurus/utils-validation';
8
9
  export declare const DEFAULT_I18N_CONFIG: I18nConfig;
9
- export declare const DEFAULT_CONFIG: Pick<DocusaurusConfig, 'i18n' | 'onBrokenLinks' | 'onBrokenMarkdownLinks' | 'onDuplicateRoutes' | 'plugins' | 'themes' | 'presets' | 'customFields' | 'themeConfig' | 'titleDelimiter' | 'noIndex' | 'baseUrlIssueBanner'>;
10
+ export declare const DEFAULT_CONFIG: Pick<DocusaurusConfig, 'i18n' | 'onBrokenLinks' | 'onBrokenMarkdownLinks' | 'onDuplicateRoutes' | 'plugins' | 'themes' | 'presets' | 'stylesheets' | 'scripts' | 'clientModules' | 'customFields' | 'themeConfig' | 'titleDelimiter' | 'noIndex' | 'tagline' | 'baseUrlIssueBanner' | 'staticDirectories'>;
11
+ export declare const ConfigSchema: Joi.ObjectSchema<any>;
10
12
  export declare function validateConfig(config: Partial<DocusaurusConfig>): DocusaurusConfig;
@@ -6,8 +6,8 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.validateConfig = exports.DEFAULT_CONFIG = exports.DEFAULT_I18N_CONFIG = void 0;
10
- const constants_1 = require("../constants");
9
+ exports.validateConfig = exports.ConfigSchema = exports.DEFAULT_CONFIG = exports.DEFAULT_I18N_CONFIG = void 0;
10
+ const utils_1 = require("@docusaurus/utils");
11
11
  const utils_validation_1 = require("@docusaurus/utils-validation");
12
12
  const DEFAULT_I18N_LOCALE = 'en';
13
13
  exports.DEFAULT_I18N_CONFIG = {
@@ -23,23 +23,39 @@ exports.DEFAULT_CONFIG = {
23
23
  plugins: [],
24
24
  themes: [],
25
25
  presets: [],
26
+ stylesheets: [],
27
+ scripts: [],
28
+ clientModules: [],
26
29
  customFields: {},
27
30
  themeConfig: {},
28
31
  titleDelimiter: '|',
29
32
  noIndex: false,
33
+ tagline: '',
30
34
  baseUrlIssueBanner: true,
35
+ staticDirectories: [utils_1.DEFAULT_STATIC_DIR_NAME],
31
36
  };
32
- const PluginSchema = utils_validation_1.Joi.alternatives()
33
- .try(utils_validation_1.Joi.function(), utils_validation_1.Joi.array().ordered(utils_validation_1.Joi.function().required(), utils_validation_1.Joi.object().required()), utils_validation_1.Joi.string(), utils_validation_1.Joi.array()
34
- .ordered(utils_validation_1.Joi.string().required(), utils_validation_1.Joi.object().required())
35
- .length(2), utils_validation_1.Joi.bool().equal(false))
36
- // TODO isn't there a simpler way to customize the default Joi error message???
37
- // Not sure why Joi makes it complicated to add a custom error message...
38
- // See https://stackoverflow.com/a/54657686/82609
39
- .error((errors) => {
40
- errors.forEach((error) => {
41
- error.message = ` => Bad Docusaurus plugin value as path [${error.path}].
42
- Example valid plugin config:
37
+ function createPluginSchema(theme) {
38
+ return (utils_validation_1.Joi.alternatives()
39
+ .try(utils_validation_1.Joi.function(), utils_validation_1.Joi.array()
40
+ .ordered(utils_validation_1.Joi.function().required(), utils_validation_1.Joi.object().required())
41
+ .length(2), utils_validation_1.Joi.string(), utils_validation_1.Joi.array()
42
+ .ordered(utils_validation_1.Joi.string().required(), utils_validation_1.Joi.object().required())
43
+ .length(2), utils_validation_1.Joi.any().valid(false, null))
44
+ // @ts-expect-error: bad lib def, doesn't recognize an array of reports
45
+ .error((errors) => {
46
+ errors.forEach((error) => {
47
+ const validConfigExample = theme
48
+ ? `Example valid theme config:
49
+ {
50
+ themes: [
51
+ ["@docusaurus/theme-classic",options],
52
+ "./myTheme",
53
+ ["./myTheme",{someOption: 42}],
54
+ function myTheme() { },
55
+ [function myTheme() { },options]
56
+ ],
57
+ };`
58
+ : `Example valid plugin config:
43
59
  {
44
60
  plugins: [
45
61
  ["@docusaurus/plugin-content-docs",options],
@@ -48,16 +64,30 @@ Example valid plugin config:
48
64
  function myPlugin() { },
49
65
  [function myPlugin() { },options]
50
66
  ],
51
- };
67
+ };`;
68
+ error.message = ` => Bad Docusaurus ${theme ? 'theme' : 'plugin'} value as path [${error.path}].
69
+ ${validConfigExample}
52
70
  `;
53
- });
54
- return errors;
71
+ });
72
+ return errors;
73
+ }));
74
+ }
75
+ const PluginSchema = createPluginSchema(false);
76
+ const ThemeSchema = createPluginSchema(true);
77
+ const PresetSchema = utils_validation_1.Joi.alternatives()
78
+ .try(utils_validation_1.Joi.string(), utils_validation_1.Joi.array()
79
+ .items(utils_validation_1.Joi.string().required(), utils_validation_1.Joi.object().required())
80
+ .length(2), utils_validation_1.Joi.any().valid(false, null))
81
+ .messages({
82
+ 'alternatives.types': `{#label} does not look like a valid preset config. A preset config entry should be one of:
83
+ - A tuple of [presetName, options], like \`["classic", \\{ blog: false \\}]\`, or
84
+ - A simple string, like \`"classic"\``,
55
85
  });
56
- const ThemeSchema = utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.string(), utils_validation_1.Joi.array().items(utils_validation_1.Joi.string().required(), utils_validation_1.Joi.object().required()).length(2));
57
- const PresetSchema = utils_validation_1.Joi.alternatives().try(utils_validation_1.Joi.string(), utils_validation_1.Joi.array().items(utils_validation_1.Joi.string().required(), utils_validation_1.Joi.object().required()).length(2));
58
86
  const LocaleConfigSchema = utils_validation_1.Joi.object({
59
87
  label: utils_validation_1.Joi.string(),
88
+ htmlLang: utils_validation_1.Joi.string(),
60
89
  direction: utils_validation_1.Joi.string().equal('ltr', 'rtl').default('ltr'),
90
+ calendar: utils_validation_1.Joi.string(),
61
91
  });
62
92
  const I18N_CONFIG_SCHEMA = utils_validation_1.Joi.object({
63
93
  defaultLocale: utils_validation_1.Joi.string().required(),
@@ -68,16 +98,29 @@ const I18N_CONFIG_SCHEMA = utils_validation_1.Joi.object({
68
98
  })
69
99
  .optional()
70
100
  .default(exports.DEFAULT_I18N_CONFIG);
101
+ const SiteUrlSchema = utils_validation_1.URISchema.required().custom((value, helpers) => {
102
+ try {
103
+ const { pathname } = new URL(value);
104
+ if (pathname !== '/') {
105
+ helpers.warn('docusaurus.configValidationWarning', {
106
+ warningMessage: `the url is not supposed to contain a sub-path like '${pathname}', please use the baseUrl field for sub-paths`,
107
+ });
108
+ }
109
+ }
110
+ catch { }
111
+ return value;
112
+ }, 'siteUrlCustomValidation');
71
113
  // TODO move to @docusaurus/utils-validation
72
- const ConfigSchema = utils_validation_1.Joi.object({
114
+ exports.ConfigSchema = utils_validation_1.Joi.object({
73
115
  baseUrl: utils_validation_1.Joi.string()
74
116
  .required()
75
- .regex(new RegExp('/$', 'm'))
76
- .message('{{#label}} must be a string with a trailing `/`'),
117
+ .regex(/\/$/m)
118
+ .message('{{#label}} must be a string with a trailing slash.'),
77
119
  baseUrlIssueBanner: utils_validation_1.Joi.boolean().default(exports.DEFAULT_CONFIG.baseUrlIssueBanner),
78
- favicon: utils_validation_1.Joi.string().required(),
120
+ favicon: utils_validation_1.Joi.string().optional(),
79
121
  title: utils_validation_1.Joi.string().required(),
80
- url: utils_validation_1.URISchema.required(),
122
+ url: SiteUrlSchema,
123
+ trailingSlash: utils_validation_1.Joi.boolean(),
81
124
  i18n: I18N_CONFIG_SCHEMA,
82
125
  onBrokenLinks: utils_validation_1.Joi.string()
83
126
  .equal('ignore', 'log', 'warn', 'error', 'throw')
@@ -89,46 +132,60 @@ const ConfigSchema = utils_validation_1.Joi.object({
89
132
  .equal('ignore', 'log', 'warn', 'error', 'throw')
90
133
  .default(exports.DEFAULT_CONFIG.onDuplicateRoutes),
91
134
  organizationName: utils_validation_1.Joi.string().allow(''),
135
+ staticDirectories: utils_validation_1.Joi.array()
136
+ .items(utils_validation_1.Joi.string())
137
+ .default(exports.DEFAULT_CONFIG.staticDirectories),
92
138
  projectName: utils_validation_1.Joi.string().allow(''),
139
+ deploymentBranch: utils_validation_1.Joi.string().optional(),
93
140
  customFields: utils_validation_1.Joi.object().unknown().default(exports.DEFAULT_CONFIG.customFields),
94
141
  githubHost: utils_validation_1.Joi.string(),
95
142
  plugins: utils_validation_1.Joi.array().items(PluginSchema).default(exports.DEFAULT_CONFIG.plugins),
96
143
  themes: utils_validation_1.Joi.array().items(ThemeSchema).default(exports.DEFAULT_CONFIG.themes),
97
144
  presets: utils_validation_1.Joi.array().items(PresetSchema).default(exports.DEFAULT_CONFIG.presets),
98
145
  themeConfig: utils_validation_1.Joi.object().unknown().default(exports.DEFAULT_CONFIG.themeConfig),
99
- scripts: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string(), utils_validation_1.Joi.object({
146
+ scripts: utils_validation_1.Joi.array()
147
+ .items(utils_validation_1.Joi.string(), utils_validation_1.Joi.object({
100
148
  src: utils_validation_1.Joi.string().required(),
101
149
  async: utils_validation_1.Joi.bool(),
102
150
  defer: utils_validation_1.Joi.bool(),
103
151
  })
104
152
  // See https://github.com/facebook/docusaurus/issues/3378
105
- .unknown()),
153
+ .unknown())
154
+ .messages({
155
+ 'array.includes': '{#label} is invalid. A script must be a plain string (the src), or an object with at least a "src" property.',
156
+ })
157
+ .default(exports.DEFAULT_CONFIG.scripts),
106
158
  ssrTemplate: utils_validation_1.Joi.string(),
107
- stylesheets: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string(), utils_validation_1.Joi.object({
159
+ stylesheets: utils_validation_1.Joi.array()
160
+ .items(utils_validation_1.Joi.string(), utils_validation_1.Joi.object({
108
161
  href: utils_validation_1.Joi.string().required(),
109
- type: utils_validation_1.Joi.string().required(),
110
- }).unknown()),
111
- clientModules: utils_validation_1.Joi.array().items(utils_validation_1.Joi.string()),
112
- tagline: utils_validation_1.Joi.string().allow(''),
113
- titleDelimiter: utils_validation_1.Joi.string().default('|'),
114
- noIndex: utils_validation_1.Joi.bool().default(false),
162
+ type: utils_validation_1.Joi.string(),
163
+ }).unknown())
164
+ .messages({
165
+ 'array.includes': '{#label} is invalid. A stylesheet must be a plain string (the href), or an object with at least a "href" property.',
166
+ })
167
+ .default(exports.DEFAULT_CONFIG.stylesheets),
168
+ clientModules: utils_validation_1.Joi.array()
169
+ .items(utils_validation_1.Joi.string())
170
+ .default(exports.DEFAULT_CONFIG.clientModules),
171
+ tagline: utils_validation_1.Joi.string().allow('').default(exports.DEFAULT_CONFIG.tagline),
172
+ titleDelimiter: utils_validation_1.Joi.string().default(exports.DEFAULT_CONFIG.titleDelimiter),
173
+ noIndex: utils_validation_1.Joi.bool().default(exports.DEFAULT_CONFIG.noIndex),
115
174
  webpack: utils_validation_1.Joi.object({
116
175
  jsLoader: utils_validation_1.Joi.alternatives()
117
176
  .try(utils_validation_1.Joi.string().equal('babel'), utils_validation_1.Joi.function())
118
177
  .optional(),
119
178
  }).optional(),
179
+ }).messages({
180
+ 'docusaurus.configValidationWarning': 'Docusaurus config validation warning. Field {#label}: {#warningMessage}',
120
181
  });
121
182
  // TODO move to @docusaurus/utils-validation
122
183
  function validateConfig(config) {
123
- const { error, value } = ConfigSchema.validate(config, {
184
+ const { error, warning, value } = exports.ConfigSchema.validate(config, {
124
185
  abortEarly: false,
125
186
  });
187
+ (0, utils_validation_1.printWarning)(warning);
126
188
  if (error) {
127
- utils_validation_1.logValidationBugReportHint();
128
- if (utils_validation_1.isValidationDisabledEscapeHatch) {
129
- console.error(error);
130
- return config;
131
- }
132
189
  const unknownFields = error.details.reduce((formattedError, err) => {
133
190
  if (err.type === 'object.unknown') {
134
191
  return `${formattedError}"${err.path}",`;
@@ -139,7 +196,7 @@ function validateConfig(config) {
139
196
  ? `${accumulatedErr}${err.message}\n`
140
197
  : accumulatedErr, '');
141
198
  formattedError = unknownFields
142
- ? `${formattedError}These field(s) [${unknownFields}] are not recognized in ${constants_1.DEFAULT_CONFIG_FILE_NAME}.\nIf you still want these fields to be in your configuration, put them in the 'customFields' attribute.\nSee https://docusaurus.io/docs/docusaurus.config.js/#customfields`
199
+ ? `${formattedError}These field(s) (${unknownFields}) are not recognized in ${utils_1.DEFAULT_CONFIG_FILE_NAME}.\nIf you still want these fields to be in your configuration, put them in the "customFields" field.\nSee https://docusaurus.io/docs/api/docusaurus-config/#customfields`
143
200
  : formattedError;
144
201
  throw new Error(formattedError);
145
202
  }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ export declare type HostPortOptions = {
8
+ host?: string;
9
+ port?: string;
10
+ };
11
+ export declare function getHostPort(options: HostPortOptions): Promise<{
12
+ host: string;
13
+ port: number | null;
14
+ }>;
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Facebook, Inc. and its affiliates.
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.getHostPort = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const child_process_1 = require("child_process");
12
+ const detect_port_1 = tslib_1.__importDefault(require("detect-port"));
13
+ const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
14
+ const utils_1 = require("@docusaurus/utils");
15
+ const prompts_1 = tslib_1.__importDefault(require("prompts"));
16
+ const execOptions = {
17
+ encoding: 'utf8',
18
+ stdio: [/* stdin */ 'pipe', /* stdout */ 'pipe', /* stderr */ 'ignore'],
19
+ };
20
+ function clearConsole() {
21
+ process.stdout.write(process.platform === 'win32' ? '\x1B[2J\x1B[0f' : '\x1B[2J\x1B[3J\x1B[H');
22
+ }
23
+ function getProcessForPort(port) {
24
+ try {
25
+ const processId = (0, child_process_1.execSync)(`lsof -i:${port} -P -t -sTCP:LISTEN`, execOptions)
26
+ .split('\n')[0]
27
+ .trim();
28
+ const directory = (0, child_process_1.execSync)(`lsof -p ${processId} | awk '$4=="cwd" {for (i=9; i<=NF; i++) printf "%s ", $i}'`, execOptions).trim();
29
+ const command = (0, child_process_1.execSync)(`ps -o command -p ${processId} | sed -n 2p`, execOptions).replace(/\n$/, '');
30
+ return logger_1.default.interpolate `code=${command} subdue=${`(pid ${processId})`} in path=${directory}`;
31
+ }
32
+ catch {
33
+ return null;
34
+ }
35
+ }
36
+ /**
37
+ * Detects if program is running on port, and prompts user to choose another if
38
+ * port is already being used. This feature was heavily inspired by
39
+ * create-react-app and uses many of the same utility functions to implement it.
40
+ */
41
+ async function choosePort(host, defaultPort) {
42
+ try {
43
+ const port = await (0, detect_port_1.default)({ port: defaultPort, hostname: host });
44
+ if (port === defaultPort) {
45
+ return port;
46
+ }
47
+ const isRoot = process.getuid?.() === 0;
48
+ const isInteractive = process.stdout.isTTY;
49
+ const message = process.platform !== 'win32' && defaultPort < 1024 && !isRoot
50
+ ? `Admin permissions are required to run a server on a port below 1024.`
51
+ : `Something is already running on port ${defaultPort}.`;
52
+ if (!isInteractive) {
53
+ logger_1.default.error(message);
54
+ return null;
55
+ }
56
+ clearConsole();
57
+ const existingProcess = getProcessForPort(defaultPort);
58
+ const { shouldChangePort } = await (0, prompts_1.default)({
59
+ type: 'confirm',
60
+ name: 'shouldChangePort',
61
+ message: logger_1.default.yellow(`${logger_1.default.bold('[WARNING]')} ${message}${existingProcess ? ` Probably:\n ${existingProcess}` : ''}
62
+
63
+ Would you like to run the app on another port instead?`),
64
+ initial: true,
65
+ });
66
+ return shouldChangePort ? port : null;
67
+ }
68
+ catch (err) {
69
+ logger_1.default.error `Could not find an open port at ${host}.`;
70
+ throw err;
71
+ }
72
+ }
73
+ async function getHostPort(options) {
74
+ const host = options.host ?? 'localhost';
75
+ const basePort = options.port ? parseInt(options.port, 10) : utils_1.DEFAULT_PORT;
76
+ const port = await choosePort(host, basePort);
77
+ return { host, port };
78
+ }
79
+ exports.getHostPort = getHostPort;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import type { Props, LoadedPlugin } from '@docusaurus/types';
8
+ /**
9
+ * Runs the `injectHtmlTags` lifecycle, and aggregates all plugins' tags into
10
+ * directly render-able HTML markup.
11
+ */
12
+ export declare function loadHtmlTags(plugins: LoadedPlugin[]): Pick<Props, 'headTags' | 'preBodyTags' | 'postBodyTags'>;