@docusaurus/utils 3.1.1 → 3.2.1
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.
- package/lib/cliUtils.d.ts +14 -0
- package/lib/cliUtils.d.ts.map +1 -0
- package/lib/cliUtils.js +50 -0
- package/lib/cliUtils.js.map +1 -0
- package/lib/emitUtils.d.ts.map +1 -1
- package/lib/emitUtils.js +6 -3
- package/lib/emitUtils.js.map +1 -1
- package/lib/gitUtils.d.ts +6 -6
- package/lib/gitUtils.d.ts.map +1 -1
- package/lib/gitUtils.js +21 -10
- package/lib/gitUtils.js.map +1 -1
- package/lib/globUtils.d.ts.map +1 -1
- package/lib/globUtils.js +2 -2
- package/lib/globUtils.js.map +1 -1
- package/lib/index.d.ts +6 -3
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +12 -7
- package/lib/index.js.map +1 -1
- package/lib/jsUtils.d.ts +0 -8
- package/lib/jsUtils.d.ts.map +1 -1
- package/lib/jsUtils.js +1 -25
- package/lib/jsUtils.js.map +1 -1
- package/lib/lastUpdateUtils.d.ts +28 -0
- package/lib/lastUpdateUtils.d.ts.map +1 -0
- package/lib/lastUpdateUtils.js +88 -0
- package/lib/lastUpdateUtils.js.map +1 -0
- package/lib/markdownUtils.js +2 -2
- package/lib/markdownUtils.js.map +1 -1
- package/lib/pathUtils.d.ts +8 -0
- package/lib/pathUtils.d.ts.map +1 -1
- package/lib/pathUtils.js +15 -1
- package/lib/pathUtils.js.map +1 -1
- package/lib/routeUtils.d.ts +13 -0
- package/lib/routeUtils.d.ts.map +1 -0
- package/lib/routeUtils.js +21 -0
- package/lib/routeUtils.js.map +1 -0
- package/lib/urlUtils.d.ts +0 -6
- package/lib/urlUtils.d.ts.map +1 -1
- package/lib/urlUtils.js +1 -18
- package/lib/urlUtils.js.map +1 -1
- package/package.json +6 -4
- package/src/cliUtils.ts +65 -0
- package/src/emitUtils.ts +7 -3
- package/src/gitUtils.ts +44 -20
- package/src/globUtils.ts +1 -2
- package/src/index.ts +13 -9
- package/src/jsUtils.ts +0 -24
- package/src/lastUpdateUtils.ts +132 -0
- package/src/markdownUtils.ts +2 -2
- package/src/pathUtils.ts +14 -0
- package/src/routeUtils.ts +19 -0
- package/src/urlUtils.ts +0 -17
|
@@ -0,0 +1,132 @@
|
|
|
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
|
+
|
|
8
|
+
import _ from 'lodash';
|
|
9
|
+
import logger from '@docusaurus/logger';
|
|
10
|
+
import {
|
|
11
|
+
FileNotTrackedError,
|
|
12
|
+
GitNotFoundError,
|
|
13
|
+
getFileCommitDate,
|
|
14
|
+
} from './gitUtils';
|
|
15
|
+
import type {PluginOptions} from '@docusaurus/types';
|
|
16
|
+
|
|
17
|
+
export type LastUpdateData = {
|
|
18
|
+
/** A timestamp in **milliseconds**, usually read from `git log` */
|
|
19
|
+
lastUpdatedAt?: number;
|
|
20
|
+
/** The author's name, usually coming from `git log` */
|
|
21
|
+
lastUpdatedBy?: string;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
let showedGitRequirementError = false;
|
|
25
|
+
let showedFileNotTrackedError = false;
|
|
26
|
+
|
|
27
|
+
export async function getGitLastUpdate(
|
|
28
|
+
filePath: string,
|
|
29
|
+
): Promise<LastUpdateData | null> {
|
|
30
|
+
if (!filePath) {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Wrap in try/catch in case the shell commands fail
|
|
35
|
+
// (e.g. project doesn't use Git, etc).
|
|
36
|
+
try {
|
|
37
|
+
const result = await getFileCommitDate(filePath, {
|
|
38
|
+
age: 'newest',
|
|
39
|
+
includeAuthor: true,
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
return {lastUpdatedAt: result.timestamp, lastUpdatedBy: result.author};
|
|
43
|
+
} catch (err) {
|
|
44
|
+
if (err instanceof GitNotFoundError) {
|
|
45
|
+
if (!showedGitRequirementError) {
|
|
46
|
+
logger.warn('Sorry, the last update options require Git.');
|
|
47
|
+
showedGitRequirementError = true;
|
|
48
|
+
}
|
|
49
|
+
} else if (err instanceof FileNotTrackedError) {
|
|
50
|
+
if (!showedFileNotTrackedError) {
|
|
51
|
+
logger.warn(
|
|
52
|
+
'Cannot infer the update date for some files, as they are not tracked by git.',
|
|
53
|
+
);
|
|
54
|
+
showedFileNotTrackedError = true;
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error(
|
|
58
|
+
`An error occurred when trying to get the last update date`,
|
|
59
|
+
{cause: err},
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export const LAST_UPDATE_FALLBACK: LastUpdateData = {
|
|
67
|
+
lastUpdatedAt: 1539502055000,
|
|
68
|
+
lastUpdatedBy: 'Author',
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
export async function getLastUpdate(
|
|
72
|
+
filePath: string,
|
|
73
|
+
): Promise<LastUpdateData | null> {
|
|
74
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
75
|
+
// Use fake data in dev/test for faster development.
|
|
76
|
+
return LAST_UPDATE_FALLBACK;
|
|
77
|
+
}
|
|
78
|
+
return getGitLastUpdate(filePath);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
type LastUpdateOptions = Pick<
|
|
82
|
+
PluginOptions,
|
|
83
|
+
'showLastUpdateAuthor' | 'showLastUpdateTime'
|
|
84
|
+
>;
|
|
85
|
+
|
|
86
|
+
export type FrontMatterLastUpdate = {
|
|
87
|
+
author?: string;
|
|
88
|
+
/**
|
|
89
|
+
* Date can be any
|
|
90
|
+
* [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
|
|
91
|
+
*/
|
|
92
|
+
date?: Date | string;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export async function readLastUpdateData(
|
|
96
|
+
filePath: string,
|
|
97
|
+
options: LastUpdateOptions,
|
|
98
|
+
lastUpdateFrontMatter: FrontMatterLastUpdate | undefined,
|
|
99
|
+
): Promise<LastUpdateData> {
|
|
100
|
+
const {showLastUpdateAuthor, showLastUpdateTime} = options;
|
|
101
|
+
|
|
102
|
+
if (!showLastUpdateAuthor && !showLastUpdateTime) {
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const frontMatterAuthor = lastUpdateFrontMatter?.author;
|
|
107
|
+
const frontMatterTimestamp = lastUpdateFrontMatter?.date
|
|
108
|
+
? new Date(lastUpdateFrontMatter.date).getTime()
|
|
109
|
+
: undefined;
|
|
110
|
+
|
|
111
|
+
// We try to minimize git last update calls
|
|
112
|
+
// We call it at most once
|
|
113
|
+
// If all the data is provided as front matter, we do not call it
|
|
114
|
+
const getLastUpdateMemoized = _.memoize(() => getLastUpdate(filePath));
|
|
115
|
+
const getLastUpdateBy = () =>
|
|
116
|
+
getLastUpdateMemoized().then((update) => update?.lastUpdatedBy);
|
|
117
|
+
const getLastUpdateAt = () =>
|
|
118
|
+
getLastUpdateMemoized().then((update) => update?.lastUpdatedAt);
|
|
119
|
+
|
|
120
|
+
const lastUpdatedBy = showLastUpdateAuthor
|
|
121
|
+
? frontMatterAuthor ?? (await getLastUpdateBy())
|
|
122
|
+
: undefined;
|
|
123
|
+
|
|
124
|
+
const lastUpdatedAt = showLastUpdateTime
|
|
125
|
+
? frontMatterTimestamp ?? (await getLastUpdateAt())
|
|
126
|
+
: undefined;
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
lastUpdatedBy,
|
|
130
|
+
lastUpdatedAt,
|
|
131
|
+
};
|
|
132
|
+
}
|
package/src/markdownUtils.ts
CHANGED
|
@@ -70,9 +70,9 @@ export function escapeMarkdownHeadingIds(content: string): string {
|
|
|
70
70
|
export function unwrapMdxCodeBlocks(content: string): string {
|
|
71
71
|
// We only support 3/4 backticks on purpose, should be good enough
|
|
72
72
|
const regexp3 =
|
|
73
|
-
/(?<begin>^|\n)```(?<spaces>\x20*)mdx-code-block\n(?<children>.*?)\n```(?<end>\n|$)/gs;
|
|
73
|
+
/(?<begin>^|\r?\n)```(?<spaces>\x20*)mdx-code-block\r?\n(?<children>.*?)\r?\n```(?<end>\r?\n|$)/gs;
|
|
74
74
|
const regexp4 =
|
|
75
|
-
/(?<begin>^|\n)````(?<spaces>\x20*)mdx-code-block\n(?<children>.*?)\n````(?<end>\n|$)/gs;
|
|
75
|
+
/(?<begin>^|\r?\n)````(?<spaces>\x20*)mdx-code-block\r?\n(?<children>.*?)\r?\n````(?<end>\r?\n|$)/gs;
|
|
76
76
|
|
|
77
77
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
78
78
|
const replacer = (substring: string, ...args: any[]) => {
|
package/src/pathUtils.ts
CHANGED
|
@@ -92,6 +92,20 @@ export function aliasedSitePath(filePath: string, siteDir: string): string {
|
|
|
92
92
|
return `@site/${relativePath}`;
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Converts back the aliased site path (starting with "@site/...") to a relative path
|
|
97
|
+
*
|
|
98
|
+
* TODO method this is a workaround, we shouldn't need to alias/un-alias paths
|
|
99
|
+
* we should refactor the codebase to not have aliased site paths everywhere
|
|
100
|
+
* We probably only need aliasing for client-only paths required by Webpack
|
|
101
|
+
*/
|
|
102
|
+
export function aliasedSitePathToRelativePath(filePath: string): string {
|
|
103
|
+
if (filePath.startsWith('@site/')) {
|
|
104
|
+
return filePath.replace('@site/', '');
|
|
105
|
+
}
|
|
106
|
+
throw new Error(`Unexpected, filePath is not site-aliased: ${filePath}`);
|
|
107
|
+
}
|
|
108
|
+
|
|
95
109
|
/**
|
|
96
110
|
* When you have a path like C:\X\Y
|
|
97
111
|
* It is not safe to use directly when generating code
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
|
|
8
|
+
import type {RouteConfig} from '@docusaurus/types';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Recursively flatten routes and only return the "leaf routes"
|
|
12
|
+
* Parent routes are filtered out
|
|
13
|
+
*/
|
|
14
|
+
export function flattenRoutes(routeConfig: RouteConfig[]): RouteConfig[] {
|
|
15
|
+
function flatten(route: RouteConfig): RouteConfig[] {
|
|
16
|
+
return route.routes ? route.routes.flatMap(flatten) : [route];
|
|
17
|
+
}
|
|
18
|
+
return routeConfig.flatMap(flatten);
|
|
19
|
+
}
|
package/src/urlUtils.ts
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import resolvePathnameUnsafe from 'resolve-pathname';
|
|
9
|
-
import {addPrefix, addSuffix, removeSuffix} from './jsUtils';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Much like `path.join`, but much better. Takes an array of URL segments, and
|
|
@@ -232,22 +231,6 @@ export function resolvePathname(to: string, from?: string): string {
|
|
|
232
231
|
return resolvePathnameUnsafe(to, from);
|
|
233
232
|
}
|
|
234
233
|
|
|
235
|
-
/** Appends a leading slash to `str`, if one doesn't exist. */
|
|
236
|
-
export function addLeadingSlash(str: string): string {
|
|
237
|
-
return addPrefix(str, '/');
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
// TODO deduplicate: also present in @docusaurus/utils-common
|
|
241
|
-
/** Appends a trailing slash to `str`, if one doesn't exist. */
|
|
242
|
-
export function addTrailingSlash(str: string): string {
|
|
243
|
-
return addSuffix(str, '/');
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
/** Removes the trailing slash from `str`. */
|
|
247
|
-
export function removeTrailingSlash(str: string): string {
|
|
248
|
-
return removeSuffix(str, '/');
|
|
249
|
-
}
|
|
250
|
-
|
|
251
234
|
/** Constructs an SSH URL that can be used to push to GitHub. */
|
|
252
235
|
export function buildSshUrl(
|
|
253
236
|
githubHost: string,
|