@azerion/bunosaurus-glob 0.0.0-stage → 4.0.0

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/README.md CHANGED
@@ -1,3 +1,5 @@
1
- # Temporary Holding Version
1
+ # `@docusaurus/glob`
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ File globbing, glob matching and file watching utilities for Docusaurus packages.
4
+
5
+ This package is mostly designed for internal usage and is undocumented. Its APIs should remain mostly retro-compatible within a major version.
@@ -0,0 +1,48 @@
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 * as Tinyglobby from 'tinyglobby';
8
+ /**
9
+ * Our own glob options: we only expose the options we actually use, so that
10
+ * we can swap the underlying lib (e.g. for Node.js native `fs.glob`).
11
+ */
12
+ export type GlobOptions = Pick<Tinyglobby.GlobOptions, 'cwd' | 'ignore' | 'absolute'>;
13
+ /** Finds the files matching the given glob patterns. */
14
+ export declare function glob(patterns: string | string[], options?: GlobOptions): Promise<string[]>;
15
+ /**
16
+ * The default glob patterns we ignore when sourcing content.
17
+ * - Ignore files and folders starting with `_` recursively
18
+ * - Ignore tests
19
+ */
20
+ export declare const GlobExcludeDefault: string[];
21
+ type Matcher = (str: string) => boolean;
22
+ /**
23
+ * Creates a matcher that tells if a path is matched by any of the patterns.
24
+ *
25
+ * @see {@link createAbsoluteFilePathMatcher}
26
+ * @param patterns A list of glob patterns. If the list is empty, it defaults to
27
+ * matching none.
28
+ * @returns A matcher handle that tells if a file path is matched by any of the
29
+ * patterns.
30
+ */
31
+ export declare function createMatcher(patterns: string[]): Matcher;
32
+ /**
33
+ * We use match patterns like `"** /_* /**"` (ignore the spaces), where `"_*"`
34
+ * should only be matched within a subfolder. This function would:
35
+ * - Match `/user/sebastien/website/docs/_partials/xyz.md`
36
+ * - Ignore `/user/_sebastien/website/docs/partials/xyz.md`
37
+ *
38
+ * @param patterns A list of glob patterns.
39
+ * @param rootFolders A list of root folders to resolve the glob from.
40
+ * @returns A matcher handle that tells if a file path is matched by any of the
41
+ * patterns, resolved from the first root folder that contains the path.
42
+ * @throws Throws when the returned matcher receives a path that doesn't belong
43
+ * to any of the `rootFolders`.
44
+ */
45
+ export declare function createAbsoluteFilePathMatcher(patterns: string[], rootFolders: string[]): Matcher;
46
+ export declare function safeGlob(patterns: string[], options?: GlobOptions): Promise<string[]>;
47
+ export {};
48
+ //# sourceMappingURL=globUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globUtils.d.ts","sourceRoot":"","sources":["../src/globUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,UAAU,MAAM,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,IAAI,CAC5B,UAAU,CAAC,WAAW,EACtB,KAAK,GAAG,QAAQ,GAAG,UAAU,CAC9B,CAAC;AAEF,wDAAwD;AACxD,wBAAsB,IAAI,CACxB,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,EAC3B,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB;AAED;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,UAK9B,CAAC;AAEF,KAAK,OAAO,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;AAExC;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,OAAO,CASzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,6BAA6B,CAC3C,QAAQ,EAAE,MAAM,EAAE,EAClB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAuBT;AAcD,wBAAsB,QAAQ,CAC5B,QAAQ,EAAE,MAAM,EAAE,EAClB,OAAO,CAAC,EAAE,WAAW,GACpB,OAAO,CAAC,MAAM,EAAE,CAAC,CAQnB"}
@@ -0,0 +1,93 @@
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.GlobExcludeDefault = void 0;
10
+ exports.glob = glob;
11
+ exports.createMatcher = createMatcher;
12
+ exports.createAbsoluteFilePathMatcher = createAbsoluteFilePathMatcher;
13
+ exports.safeGlob = safeGlob;
14
+ const tslib_1 = require("tslib");
15
+ // Tinyglobby/Micromatch are the 2 libs we use in Docusaurus consistently
16
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
17
+ const micromatch_1 = tslib_1.__importDefault(require("micromatch"));
18
+ const Tinyglobby = tslib_1.__importStar(require("tinyglobby"));
19
+ /** Finds the files matching the given glob patterns. */
20
+ async function glob(patterns, options) {
21
+ // Other lib options are still forwarded at runtime for retro-compatibility
22
+ return Tinyglobby.glob(patterns, { ...options });
23
+ }
24
+ /**
25
+ * The default glob patterns we ignore when sourcing content.
26
+ * - Ignore files and folders starting with `_` recursively
27
+ * - Ignore tests
28
+ */
29
+ exports.GlobExcludeDefault = [
30
+ '**/_*.{js,jsx,ts,tsx,md,mdx}',
31
+ '**/_*/**',
32
+ '**/*.test.{js,jsx,ts,tsx}',
33
+ '**/__tests__/**',
34
+ ];
35
+ /**
36
+ * Creates a matcher that tells if a path is matched by any of the patterns.
37
+ *
38
+ * @see {@link createAbsoluteFilePathMatcher}
39
+ * @param patterns A list of glob patterns. If the list is empty, it defaults to
40
+ * matching none.
41
+ * @returns A matcher handle that tells if a file path is matched by any of the
42
+ * patterns.
43
+ */
44
+ function createMatcher(patterns) {
45
+ if (patterns.length === 0) {
46
+ // `/(?:)/.test("foo")` is `true`
47
+ return () => false;
48
+ }
49
+ const regexp = new RegExp(patterns.map((pattern) => micromatch_1.default.makeRe(pattern).source).join('|'));
50
+ return (str) => regexp.test(str);
51
+ }
52
+ /**
53
+ * We use match patterns like `"** /_* /**"` (ignore the spaces), where `"_*"`
54
+ * should only be matched within a subfolder. This function would:
55
+ * - Match `/user/sebastien/website/docs/_partials/xyz.md`
56
+ * - Ignore `/user/_sebastien/website/docs/partials/xyz.md`
57
+ *
58
+ * @param patterns A list of glob patterns.
59
+ * @param rootFolders A list of root folders to resolve the glob from.
60
+ * @returns A matcher handle that tells if a file path is matched by any of the
61
+ * patterns, resolved from the first root folder that contains the path.
62
+ * @throws Throws when the returned matcher receives a path that doesn't belong
63
+ * to any of the `rootFolders`.
64
+ */
65
+ function createAbsoluteFilePathMatcher(patterns, rootFolders) {
66
+ const matcher = createMatcher(patterns);
67
+ function getRelativeFilePath(absoluteFilePath) {
68
+ const rootFolder = rootFolders.find((folderPath) => ['/', '\\'].some((separator) => absoluteFilePath.startsWith(folderPath.endsWith(separator) ? folderPath : folderPath + separator)));
69
+ if (!rootFolder) {
70
+ throw new Error(`createAbsoluteFilePathMatcher unexpected error, absoluteFilePath=${absoluteFilePath} was not contained in any of the root folders: ${rootFolders.join(', ')}`);
71
+ }
72
+ return node_path_1.default.relative(rootFolder, absoluteFilePath);
73
+ }
74
+ return (absoluteFilePath) => matcher(getRelativeFilePath(absoluteFilePath));
75
+ }
76
+ // Duplicated from @docusaurus/utils to keep this package dependency-free
77
+ // See https://github.com/sindresorhus/slash/blob/main/index.js
78
+ function posixPath(str) {
79
+ const isExtendedLengthPath = str.startsWith('\\\\?\\');
80
+ if (isExtendedLengthPath) {
81
+ return str;
82
+ }
83
+ return str.replace(/\\/g, '/');
84
+ }
85
+ // Glob that fix Windows path patterns
86
+ // See https://github.com/facebook/docusaurus/pull/4222#issuecomment-795517329
87
+ async function safeGlob(patterns, options) {
88
+ // Required for Windows support, as paths using \ should not be used by glob
89
+ // (also using the windows hard drive prefix like c: is not a good idea)
90
+ const globPaths = patterns.map((dirPath) => posixPath(node_path_1.default.relative(process.cwd(), dirPath)));
91
+ return glob(globPaths, options);
92
+ }
93
+ //# sourceMappingURL=globUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"globUtils.js","sourceRoot":"","sources":["../src/globUtils.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;AAEH,yEAAyE;AAEzE,kEAA6B;AAC7B,oEAAoC;AACpC,MAAY,UAAU,+CAAmB;AAWzC,wDAAwD;AACjD,KAAK,eACV,QAA2B,EAC3B,OAAqB;IAErB,2EAA2E;IAC3E,OAAO,UAAU,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAC,GAAG,OAAO,EAAC,CAAC,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACU,QAAA,kBAAkB,GAAG;IAChC,8BAA8B;IAC9B,UAAU;IACV,2BAA2B;IAC3B,iBAAiB;CAClB,CAAC;AAIF;;;;;;;;GAQG;AACH,uBAA8B,QAAkB;IAC9C,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,iCAAiC;QACjC,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC;IACrB,CAAC;IACD,MAAM,MAAM,GAAG,IAAI,MAAM,CACvB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,oBAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CACvE,CAAC;IACF,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,uCACE,QAAkB,EAClB,WAAqB;IAErB,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAExC,SAAS,mBAAmB,CAAC,gBAAwB;QACnD,MAAM,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CACjD,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAC7B,gBAAgB,CAAC,UAAU,CACzB,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,UAAU,GAAG,SAAS,CACrE,CACF,CACF,CAAC;QACF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACb,oEAAoE,gBAAgB,kDAAkD,WAAW,CAAC,IAAI,CACpJ,IAAI,CACL,EAAE,CACJ,CAAC;QACJ,CAAC;QACD,OAAO,mBAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,CAAC,gBAAwB,EAAE,EAAE,CAClC,OAAO,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,CAAC,CAAC;AACnD,CAAC;AAED,yEAAyE;AACzE,+DAA+D;AAC/D,SAAS,SAAS,CAAC,GAAW;IAC5B,MAAM,oBAAoB,GAAG,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACvD,IAAI,oBAAoB,EAAE,CAAC;QACzB,OAAO,GAAG,CAAC;IACb,CAAC;IACD,OAAO,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACjC,CAAC;AAED,sCAAsC;AACtC,8EAA8E;AACvE,KAAK,mBACV,QAAkB,EAClB,OAAqB;IAErB,4EAA4E;IAC5E,wEAAwE;IACxE,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CACzC,SAAS,CAAC,mBAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,CACjD,CAAC;IAEF,OAAO,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAClC,CAAC"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,10 @@
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 { glob, type GlobOptions, GlobExcludeDefault, safeGlob, createMatcher, createAbsoluteFilePathMatcher, } from './globUtils';
8
+ export { globTranslatableSourceFiles } from './translationUtils';
9
+ export { watch, type Watcher, type WatchOptions } from './watchUtils';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,IAAI,EACJ,KAAK,WAAW,EAChB,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,6BAA6B,GAC9B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAC,2BAA2B,EAAC,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAC,KAAK,EAAE,KAAK,OAAO,EAAE,KAAK,YAAY,EAAC,MAAM,cAAc,CAAC"}
package/lib/index.js ADDED
@@ -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.watch = exports.globTranslatableSourceFiles = exports.createAbsoluteFilePathMatcher = exports.createMatcher = exports.safeGlob = exports.GlobExcludeDefault = exports.glob = void 0;
10
+ var globUtils_1 = require("./globUtils");
11
+ Object.defineProperty(exports, "glob", { enumerable: true, get: function () { return globUtils_1.glob; } });
12
+ Object.defineProperty(exports, "GlobExcludeDefault", { enumerable: true, get: function () { return globUtils_1.GlobExcludeDefault; } });
13
+ Object.defineProperty(exports, "safeGlob", { enumerable: true, get: function () { return globUtils_1.safeGlob; } });
14
+ Object.defineProperty(exports, "createMatcher", { enumerable: true, get: function () { return globUtils_1.createMatcher; } });
15
+ Object.defineProperty(exports, "createAbsoluteFilePathMatcher", { enumerable: true, get: function () { return globUtils_1.createAbsoluteFilePathMatcher; } });
16
+ var translationUtils_1 = require("./translationUtils");
17
+ Object.defineProperty(exports, "globTranslatableSourceFiles", { enumerable: true, get: function () { return translationUtils_1.globTranslatableSourceFiles; } });
18
+ var watchUtils_1 = require("./watchUtils");
19
+ Object.defineProperty(exports, "watch", { enumerable: true, get: function () { return watchUtils_1.watch; } });
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;AAEH,yCAOqB;AANnB,iGAAA,IAAI,OAAA;AAEJ,+GAAA,kBAAkB,OAAA;AAClB,qGAAA,QAAQ,OAAA;AACR,0GAAA,aAAa,OAAA;AACb,0HAAA,6BAA6B,OAAA;AAE/B,uDAA+D;AAAvD,+HAAA,2BAA2B,OAAA;AACnC,2CAAoE;AAA5D,mGAAA,KAAK,OAAA"}
@@ -0,0 +1,9 @@
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 const isTranslatableSourceFile: (filePath: string) => boolean;
8
+ export declare function globTranslatableSourceFiles(patterns: string[]): Promise<string[]>;
9
+ //# sourceMappingURL=translationUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translationUtils.d.ts","sourceRoot":"","sources":["../src/translationUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,eAAO,MAAM,wBAAwB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAsBzD,CAAC;AAEL,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,MAAM,EAAE,CAAC,CAKnB"}
@@ -0,0 +1,43 @@
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.isTranslatableSourceFile = void 0;
10
+ exports.globTranslatableSourceFiles = globTranslatableSourceFiles;
11
+ const tslib_1 = require("tslib");
12
+ // Awkward to have translation code in this package, but it is consumed by both
13
+ // @docusaurus/core and @docusaurus/theme-translations: this avoids duplication
14
+ const node_path_1 = tslib_1.__importDefault(require("node:path"));
15
+ const globUtils_1 = require("./globUtils");
16
+ exports.isTranslatableSourceFile = (() => {
17
+ // We only support extracting source code translations from these extensions
18
+ const extensionsAllowed = new Set([
19
+ '.js',
20
+ '.jsx',
21
+ '.ts',
22
+ '.tsx',
23
+ // TODO support md/mdx too? (may be overkill)
24
+ // need to compile the MDX to JSX first and remove front matter
25
+ // '.md',
26
+ // '.mdx',
27
+ ]);
28
+ const isBlacklistedFilePath = (filePath) => {
29
+ // We usually extract from ts files, unless they are .d.ts files
30
+ return filePath.endsWith('.d.ts');
31
+ };
32
+ return (filePath) => {
33
+ const ext = node_path_1.default.extname(filePath);
34
+ return extensionsAllowed.has(ext) && !isBlacklistedFilePath(filePath);
35
+ };
36
+ })();
37
+ async function globTranslatableSourceFiles(patterns) {
38
+ const filePaths = await (0, globUtils_1.safeGlob)(patterns, {
39
+ absolute: true,
40
+ });
41
+ return filePaths.filter(exports.isTranslatableSourceFile);
42
+ }
43
+ //# sourceMappingURL=translationUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"translationUtils.js","sourceRoot":"","sources":["../src/translationUtils.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;AAEH,+EAA+E;AAC/E,+EAA+E;AAE/E,kEAA6B;AAC7B,2CAAqC;AAExB,QAAA,wBAAwB,GAAkC,CAAC,GAAG,EAAE;IAC3E,4EAA4E;IAC5E,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC;QAChC,KAAK;QACL,MAAM;QACN,KAAK;QACL,MAAM;QACN,6CAA6C;QAC7C,+DAA+D;QAC/D,SAAS;QACT,UAAU;KACX,CAAC,CAAC;IAEH,MAAM,qBAAqB,GAAG,CAAC,QAAgB,EAAE,EAAE;QACjD,gEAAgE;QAChE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC,CAAC;IAEF,OAAO,CAAC,QAAQ,EAAW,EAAE;QAC3B,MAAM,GAAG,GAAG,mBAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACnC,OAAO,iBAAiB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IACxE,CAAC,CAAC;AACJ,CAAC,CAAC,EAAE,CAAC;AAEE,KAAK,sCACV,QAAkB;IAElB,MAAM,SAAS,GAAG,MAAM,IAAA,oBAAQ,EAAC,QAAQ,EAAE;QACzC,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IACH,OAAO,SAAS,CAAC,MAAM,CAAC,QAAA,wBAAwB,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,20 @@
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 * as Chokidar from 'chokidar';
8
+ /**
9
+ * Our own watch options: we only expose the options we actually use, so that
10
+ * we can upgrade or swap the underlying lib.
11
+ */
12
+ export type WatchOptions = Pick<Chokidar.WatchOptions, 'cwd' | 'usePolling' | 'interval'>;
13
+ /** Our own file watcher handle, exposing only the APIs we actually use. */
14
+ export type Watcher = Pick<Chokidar.FSWatcher, 'on' | 'close'>;
15
+ /**
16
+ * Watches file system paths for changes.
17
+ * Only emits events for changes happening after the watcher is created.
18
+ */
19
+ export declare function watch(paths: string | string[], options?: WatchOptions): Watcher;
20
+ //# sourceMappingURL=watchUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchUtils.d.ts","sourceRoot":"","sources":["../src/watchUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAErC;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,IAAI,CAC7B,QAAQ,CAAC,YAAY,EACrB,KAAK,GAAG,YAAY,GAAG,UAAU,CAClC,CAAC;AAEF,2EAA2E;AAC3E,MAAM,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,IAAI,GAAG,OAAO,CAAC,CAAC;AAE/D;;;GAGG;AACH,wBAAgB,KAAK,CACnB,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,EACxB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAMT"}
@@ -0,0 +1,24 @@
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.watch = watch;
10
+ const tslib_1 = require("tslib");
11
+ // Chokidar is the lib we use in Docusaurus to watch files
12
+ const Chokidar = tslib_1.__importStar(require("chokidar"));
13
+ /**
14
+ * Watches file system paths for changes.
15
+ * Only emits events for changes happening after the watcher is created.
16
+ */
17
+ function watch(paths, options) {
18
+ return Chokidar.watch(paths, {
19
+ // Other lib options are still forwarded at runtime for retro-compatibility
20
+ ...options,
21
+ ignoreInitial: true,
22
+ });
23
+ }
24
+ //# sourceMappingURL=watchUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchUtils.js","sourceRoot":"","sources":["../src/watchUtils.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;AAEH,0DAA0D;AAE1D,MAAY,QAAQ,6CAAiB;AAcrC;;;GAGG;AACH,eACE,KAAwB,EACxB,OAAsB;IAEtB,OAAO,QAAQ,CAAC,KAAK,CAAC,KAAK,EAAE;QAC3B,2EAA2E;QAC3E,GAAG,OAAO;QACV,aAAa,EAAE,IAAI;KACpB,CAAC,CAAC;AACL,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,32 @@
1
1
  {
2
2
  "name": "@azerion/bunosaurus-glob",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "4.0.0",
4
+ "description": "File globbing, glob matching and file watching utilities for Docusaurus packages.",
5
+ "main": "./lib/index.js",
6
+ "types": "./lib/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "watch": "tsc --watch"
10
+ },
11
+ "publishConfig": {
12
+ "access": "public"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/azerion/bunosaurus.git",
17
+ "directory": "packages/docusaurus-glob"
18
+ },
19
+ "license": "MIT",
20
+ "dependencies": {
21
+ "chokidar": "^3.6.0",
22
+ "micromatch": "^4.0.8",
23
+ "tinyglobby": "^0.2.17",
24
+ "tslib": "^2.8.1"
25
+ },
26
+ "engines": {
27
+ "bun": ">=1.4.1"
28
+ },
29
+ "devDependencies": {
30
+ "@types/micromatch": "^4.0.10"
31
+ }
32
+ }
@@ -0,0 +1,130 @@
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
+ // Tinyglobby/Micromatch are the 2 libs we use in Docusaurus consistently
9
+
10
+ import path from 'node:path';
11
+ import Micromatch from 'micromatch';
12
+ import * as Tinyglobby from 'tinyglobby';
13
+
14
+ /**
15
+ * Our own glob options: we only expose the options we actually use, so that
16
+ * we can swap the underlying lib (e.g. for Node.js native `fs.glob`).
17
+ */
18
+ export type GlobOptions = Pick<
19
+ Tinyglobby.GlobOptions,
20
+ 'cwd' | 'ignore' | 'absolute'
21
+ >;
22
+
23
+ /** Finds the files matching the given glob patterns. */
24
+ export async function glob(
25
+ patterns: string | string[],
26
+ options?: GlobOptions,
27
+ ): Promise<string[]> {
28
+ // Other lib options are still forwarded at runtime for retro-compatibility
29
+ return Tinyglobby.glob(patterns, {...options});
30
+ }
31
+
32
+ /**
33
+ * The default glob patterns we ignore when sourcing content.
34
+ * - Ignore files and folders starting with `_` recursively
35
+ * - Ignore tests
36
+ */
37
+ export const GlobExcludeDefault = [
38
+ '**/_*.{js,jsx,ts,tsx,md,mdx}',
39
+ '**/_*/**',
40
+ '**/*.test.{js,jsx,ts,tsx}',
41
+ '**/__tests__/**',
42
+ ];
43
+
44
+ type Matcher = (str: string) => boolean;
45
+
46
+ /**
47
+ * Creates a matcher that tells if a path is matched by any of the patterns.
48
+ *
49
+ * @see {@link createAbsoluteFilePathMatcher}
50
+ * @param patterns A list of glob patterns. If the list is empty, it defaults to
51
+ * matching none.
52
+ * @returns A matcher handle that tells if a file path is matched by any of the
53
+ * patterns.
54
+ */
55
+ export function createMatcher(patterns: string[]): Matcher {
56
+ if (patterns.length === 0) {
57
+ // `/(?:)/.test("foo")` is `true`
58
+ return () => false;
59
+ }
60
+ const regexp = new RegExp(
61
+ patterns.map((pattern) => Micromatch.makeRe(pattern).source).join('|'),
62
+ );
63
+ return (str) => regexp.test(str);
64
+ }
65
+
66
+ /**
67
+ * We use match patterns like `"** /_* /**"` (ignore the spaces), where `"_*"`
68
+ * should only be matched within a subfolder. This function would:
69
+ * - Match `/user/sebastien/website/docs/_partials/xyz.md`
70
+ * - Ignore `/user/_sebastien/website/docs/partials/xyz.md`
71
+ *
72
+ * @param patterns A list of glob patterns.
73
+ * @param rootFolders A list of root folders to resolve the glob from.
74
+ * @returns A matcher handle that tells if a file path is matched by any of the
75
+ * patterns, resolved from the first root folder that contains the path.
76
+ * @throws Throws when the returned matcher receives a path that doesn't belong
77
+ * to any of the `rootFolders`.
78
+ */
79
+ export function createAbsoluteFilePathMatcher(
80
+ patterns: string[],
81
+ rootFolders: string[],
82
+ ): Matcher {
83
+ const matcher = createMatcher(patterns);
84
+
85
+ function getRelativeFilePath(absoluteFilePath: string) {
86
+ const rootFolder = rootFolders.find((folderPath) =>
87
+ ['/', '\\'].some((separator) =>
88
+ absoluteFilePath.startsWith(
89
+ folderPath.endsWith(separator) ? folderPath : folderPath + separator,
90
+ ),
91
+ ),
92
+ );
93
+ if (!rootFolder) {
94
+ throw new Error(
95
+ `createAbsoluteFilePathMatcher unexpected error, absoluteFilePath=${absoluteFilePath} was not contained in any of the root folders: ${rootFolders.join(
96
+ ', ',
97
+ )}`,
98
+ );
99
+ }
100
+ return path.relative(rootFolder, absoluteFilePath);
101
+ }
102
+
103
+ return (absoluteFilePath: string) =>
104
+ matcher(getRelativeFilePath(absoluteFilePath));
105
+ }
106
+
107
+ // Duplicated from @docusaurus/utils to keep this package dependency-free
108
+ // See https://github.com/sindresorhus/slash/blob/main/index.js
109
+ function posixPath(str: string): string {
110
+ const isExtendedLengthPath = str.startsWith('\\\\?\\');
111
+ if (isExtendedLengthPath) {
112
+ return str;
113
+ }
114
+ return str.replace(/\\/g, '/');
115
+ }
116
+
117
+ // Glob that fix Windows path patterns
118
+ // See https://github.com/facebook/docusaurus/pull/4222#issuecomment-795517329
119
+ export async function safeGlob(
120
+ patterns: string[],
121
+ options?: GlobOptions,
122
+ ): Promise<string[]> {
123
+ // Required for Windows support, as paths using \ should not be used by glob
124
+ // (also using the windows hard drive prefix like c: is not a good idea)
125
+ const globPaths = patterns.map((dirPath) =>
126
+ posixPath(path.relative(process.cwd(), dirPath)),
127
+ );
128
+
129
+ return glob(globPaths, options);
130
+ }
package/src/index.ts ADDED
@@ -0,0 +1,17 @@
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
+ export {
9
+ glob,
10
+ type GlobOptions,
11
+ GlobExcludeDefault,
12
+ safeGlob,
13
+ createMatcher,
14
+ createAbsoluteFilePathMatcher,
15
+ } from './globUtils';
16
+ export {globTranslatableSourceFiles} from './translationUtils';
17
+ export {watch, type Watcher, type WatchOptions} from './watchUtils';
@@ -0,0 +1,45 @@
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
+ // Awkward to have translation code in this package, but it is consumed by both
9
+ // @docusaurus/core and @docusaurus/theme-translations: this avoids duplication
10
+
11
+ import path from 'node:path';
12
+ import {safeGlob} from './globUtils';
13
+
14
+ export const isTranslatableSourceFile: (filePath: string) => boolean = (() => {
15
+ // We only support extracting source code translations from these extensions
16
+ const extensionsAllowed = new Set([
17
+ '.js',
18
+ '.jsx',
19
+ '.ts',
20
+ '.tsx',
21
+ // TODO support md/mdx too? (may be overkill)
22
+ // need to compile the MDX to JSX first and remove front matter
23
+ // '.md',
24
+ // '.mdx',
25
+ ]);
26
+
27
+ const isBlacklistedFilePath = (filePath: string) => {
28
+ // We usually extract from ts files, unless they are .d.ts files
29
+ return filePath.endsWith('.d.ts');
30
+ };
31
+
32
+ return (filePath): boolean => {
33
+ const ext = path.extname(filePath);
34
+ return extensionsAllowed.has(ext) && !isBlacklistedFilePath(filePath);
35
+ };
36
+ })();
37
+
38
+ export async function globTranslatableSourceFiles(
39
+ patterns: string[],
40
+ ): Promise<string[]> {
41
+ const filePaths = await safeGlob(patterns, {
42
+ absolute: true,
43
+ });
44
+ return filePaths.filter(isTranslatableSourceFile);
45
+ }
@@ -0,0 +1,37 @@
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
+ // Chokidar is the lib we use in Docusaurus to watch files
9
+
10
+ import * as Chokidar from 'chokidar';
11
+
12
+ /**
13
+ * Our own watch options: we only expose the options we actually use, so that
14
+ * we can upgrade or swap the underlying lib.
15
+ */
16
+ export type WatchOptions = Pick<
17
+ Chokidar.WatchOptions,
18
+ 'cwd' | 'usePolling' | 'interval'
19
+ >;
20
+
21
+ /** Our own file watcher handle, exposing only the APIs we actually use. */
22
+ export type Watcher = Pick<Chokidar.FSWatcher, 'on' | 'close'>;
23
+
24
+ /**
25
+ * Watches file system paths for changes.
26
+ * Only emits events for changes happening after the watcher is created.
27
+ */
28
+ export function watch(
29
+ paths: string | string[],
30
+ options?: WatchOptions,
31
+ ): Watcher {
32
+ return Chokidar.watch(paths, {
33
+ // Other lib options are still forwarded at runtime for retro-compatibility
34
+ ...options,
35
+ ignoreInitial: true,
36
+ });
37
+ }