@docusaurus/plugin-content-pages 2.0.0-beta.15a2b59f9 → 2.0.0-beta.17

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 (34) hide show
  1. package/lib/index.d.ts +4 -3
  2. package/lib/index.js +38 -49
  3. package/lib/markdownLoader.d.ts +2 -6
  4. package/lib/markdownLoader.js +3 -3
  5. package/{src/__tests__/__fixtures__/website/src/pages/hello/translatedJs.js → lib/pageFrontMatter.d.ts} +2 -8
  6. package/lib/pageFrontMatter.js +21 -0
  7. package/lib/pluginOptionSchema.d.ts +1 -1
  8. package/lib/pluginOptionSchema.js +8 -5
  9. package/lib/types.d.ts +1 -21
  10. package/package.json +13 -14
  11. package/{types.d.ts → src/deps.d.ts} +0 -0
  12. package/src/index.ts +51 -65
  13. package/src/markdownLoader.ts +7 -10
  14. package/src/pageFrontMatter.ts +27 -0
  15. package/src/plugin-content-pages.d.ts +51 -12
  16. package/src/pluginOptionSchema.ts +4 -6
  17. package/src/types.ts +1 -25
  18. package/lib/.tsbuildinfo +0 -1
  19. package/src/__tests__/__fixtures__/website/docusaurus.config.js +0 -14
  20. package/src/__tests__/__fixtures__/website/i18n/fr/docusaurus-plugin-content-pages/hello/translatedJs.js +0 -14
  21. package/src/__tests__/__fixtures__/website/i18n/fr/docusaurus-plugin-content-pages/hello/translatedMd.md +0 -1
  22. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.js +0 -1
  23. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.md +0 -1
  24. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.mdx +0 -1
  25. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.tsx +0 -1
  26. package/src/__tests__/__fixtures__/website/src/pages/hello/index.md +0 -2
  27. package/src/__tests__/__fixtures__/website/src/pages/hello/mdxPage.mdx +0 -5
  28. package/src/__tests__/__fixtures__/website/src/pages/hello/translatedMd.md +0 -1
  29. package/src/__tests__/__fixtures__/website/src/pages/hello/world.js +0 -22
  30. package/src/__tests__/__fixtures__/website/src/pages/index.js +0 -23
  31. package/src/__tests__/__fixtures__/website/src/pages/typescript.tsx +0 -22
  32. package/src/__tests__/index.test.ts +0 -139
  33. package/src/__tests__/pluginOptionSchema.test.ts +0 -54
  34. package/tsconfig.json +0 -9
package/lib/index.d.ts CHANGED
@@ -4,8 +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 { LoadContext, Plugin, OptionValidationContext, ValidationResult } from '@docusaurus/types';
8
- import { PluginOptions, LoadedContent, PagesContentPaths } from './types';
7
+ import type { LoadContext, Plugin, OptionValidationContext, ValidationResult } from '@docusaurus/types';
8
+ import type { LoadedContent, PagesContentPaths } from './types';
9
+ import type { PluginOptions } from '@docusaurus/plugin-content-pages';
9
10
  export declare function getContentPathList(contentPaths: PagesContentPaths): string[];
10
- export default function pluginContentPages(context: LoadContext, options: PluginOptions): Plugin<LoadedContent | null>;
11
+ export default function pluginContentPages(context: LoadContext, options: PluginOptions): Promise<Plugin<LoadedContent | null>>;
11
12
  export declare function validateOptions({ validate, options, }: OptionValidationContext<PluginOptions>): ValidationResult<PluginOptions>;
package/lib/index.js CHANGED
@@ -8,23 +8,18 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.validateOptions = exports.getContentPathList = void 0;
10
10
  const tslib_1 = require("tslib");
11
- const globby_1 = tslib_1.__importDefault(require("globby"));
12
- const fs_1 = tslib_1.__importDefault(require("fs"));
11
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
13
12
  const path_1 = tslib_1.__importDefault(require("path"));
14
- const minimatch_1 = tslib_1.__importDefault(require("minimatch"));
15
- const slash_1 = tslib_1.__importDefault(require("slash"));
16
13
  const utils_1 = require("@docusaurus/utils");
17
14
  const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
18
15
  const pluginOptionSchema_1 = require("./pluginOptionSchema");
19
- const constants_1 = require("@docusaurus/core/lib/constants");
20
- const lodash_1 = require("lodash");
16
+ const pageFrontMatter_1 = require("./pageFrontMatter");
21
17
  function getContentPathList(contentPaths) {
22
18
  return [contentPaths.contentPathLocalized, contentPaths.contentPath];
23
19
  }
24
20
  exports.getContentPathList = getContentPathList;
25
21
  const isMarkdownSource = (source) => source.endsWith('.md') || source.endsWith('.mdx');
26
- function pluginContentPages(context, options) {
27
- var _a;
22
+ async function pluginContentPages(context, options) {
28
23
  if (options.admonitions) {
29
24
  options.remarkPlugins = options.remarkPlugins.concat([
30
25
  [remark_admonitions_1.default, options.admonitions || {}],
@@ -33,7 +28,7 @@ function pluginContentPages(context, options) {
33
28
  const { siteConfig, siteDir, generatedFilesDir, i18n: { currentLocale }, } = context;
34
29
  const contentPaths = {
35
30
  contentPath: path_1.default.resolve(siteDir, options.path),
36
- contentPathLocalized: utils_1.getPluginI18nPath({
31
+ contentPathLocalized: (0, utils_1.getPluginI18nPath)({
37
32
  siteDir,
38
33
  locale: currentLocale,
39
34
  pluginName: 'docusaurus-plugin-content-pages',
@@ -41,56 +36,51 @@ function pluginContentPages(context, options) {
41
36
  }),
42
37
  };
43
38
  const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-pages');
44
- const dataDir = path_1.default.join(pluginDataDirRoot, (_a = options.id) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_PLUGIN_ID);
45
- const excludeRegex = new RegExp(options.exclude
46
- .map((pattern) => minimatch_1.default.makeRe(pattern).source)
47
- .join('|'));
39
+ const dataDir = path_1.default.join(pluginDataDirRoot, options.id ?? utils_1.DEFAULT_PLUGIN_ID);
48
40
  return {
49
41
  name: 'docusaurus-plugin-content-pages',
50
42
  getPathsToWatch() {
51
43
  const { include = [] } = options;
52
- return lodash_1.flatten(getContentPathList(contentPaths).map((contentPath) => {
53
- return include.map((pattern) => `${contentPath}/${pattern}`);
54
- }));
55
- },
56
- getClientModules() {
57
- const modules = [];
58
- if (options.admonitions) {
59
- modules.push(require.resolve('remark-admonitions/styles/infima.css'));
60
- }
61
- return modules;
44
+ return getContentPathList(contentPaths).flatMap((contentPath) => include.map((pattern) => `${contentPath}/${pattern}`));
62
45
  },
63
46
  async loadContent() {
64
47
  const { include } = options;
65
- if (!fs_1.default.existsSync(contentPaths.contentPath)) {
48
+ if (!(await fs_extra_1.default.pathExists(contentPaths.contentPath))) {
66
49
  return null;
67
50
  }
68
51
  const { baseUrl } = siteConfig;
69
- const pagesFiles = await globby_1.default(include, {
52
+ const pagesFiles = await (0, utils_1.Globby)(include, {
70
53
  cwd: contentPaths.contentPath,
71
54
  ignore: options.exclude,
72
55
  });
73
56
  async function toMetadata(relativeSource) {
74
57
  // Lookup in localized folder in priority
75
- const contentPath = await utils_1.getFolderContainingFile(getContentPathList(contentPaths), relativeSource);
58
+ const contentPath = await (0, utils_1.getFolderContainingFile)(getContentPathList(contentPaths), relativeSource);
76
59
  const source = path_1.default.join(contentPath, relativeSource);
77
- const aliasedSourcePath = utils_1.aliasedSitePath(source, siteDir);
78
- const pathName = utils_1.encodePath(utils_1.fileToPath(relativeSource));
79
- const permalink = pathName.replace(/^\//, baseUrl || '');
80
- if (isMarkdownSource(relativeSource)) {
81
- return {
82
- type: 'mdx',
83
- permalink,
84
- source: aliasedSourcePath,
85
- };
86
- }
87
- else {
60
+ const aliasedSourcePath = (0, utils_1.aliasedSitePath)(source, siteDir);
61
+ const permalink = (0, utils_1.normalizeUrl)([
62
+ baseUrl,
63
+ options.routeBasePath,
64
+ (0, utils_1.encodePath)((0, utils_1.fileToPath)(relativeSource)),
65
+ ]);
66
+ if (!isMarkdownSource(relativeSource)) {
88
67
  return {
89
68
  type: 'jsx',
90
69
  permalink,
91
70
  source: aliasedSourcePath,
92
71
  };
93
72
  }
73
+ const content = await fs_extra_1.default.readFile(source, 'utf-8');
74
+ const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = (0, utils_1.parseMarkdownString)(content);
75
+ const frontMatter = (0, pageFrontMatter_1.validatePageFrontMatter)(unsafeFrontMatter);
76
+ return {
77
+ type: 'mdx',
78
+ permalink,
79
+ source: aliasedSourcePath,
80
+ title: frontMatter.title ?? contentTitle,
81
+ description: frontMatter.description ?? excerpt,
82
+ frontMatter,
83
+ };
94
84
  }
95
85
  return Promise.all(pagesFiles.map(toMetadata));
96
86
  },
@@ -105,7 +95,7 @@ function pluginContentPages(context, options) {
105
95
  await createData(
106
96
  // Note that this created data path must be in sync with
107
97
  // metadataPath provided to mdx-loader.
108
- `${utils_1.docuHash(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
98
+ `${(0, utils_1.docuHash)(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
109
99
  addRoute({
110
100
  path: permalink,
111
101
  component: options.mdxPageComponent,
@@ -129,6 +119,7 @@ function pluginContentPages(context, options) {
129
119
  },
130
120
  configureWebpack(_config, isServer, { getJSLoader }) {
131
121
  const { rehypePlugins, remarkPlugins, beforeDefaultRehypePlugins, beforeDefaultRemarkPlugins, } = options;
122
+ const contentDirs = getContentPathList(contentPaths);
132
123
  return {
133
124
  resolve: {
134
125
  alias: {
@@ -138,8 +129,8 @@ function pluginContentPages(context, options) {
138
129
  module: {
139
130
  rules: [
140
131
  {
141
- test: /(\.mdx?)$/,
142
- include: getContentPathList(contentPaths)
132
+ test: /\.mdx?$/i,
133
+ include: contentDirs
143
134
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
144
135
  .map(utils_1.addTrailingPathSeparator),
145
136
  use: [
@@ -151,17 +142,15 @@ function pluginContentPages(context, options) {
151
142
  rehypePlugins,
152
143
  beforeDefaultRehypePlugins,
153
144
  beforeDefaultRemarkPlugins,
154
- staticDir: path_1.default.join(siteDir, constants_1.STATIC_DIR_NAME),
155
- // Note that metadataPath must be the same/in-sync as
156
- // the path from createData for each MDX.
145
+ staticDirs: siteConfig.staticDirectories.map((dir) => path_1.default.resolve(siteDir, dir)),
146
+ siteDir,
147
+ isMDXPartial: (0, utils_1.createAbsoluteFilePathMatcher)(options.exclude, contentDirs),
157
148
  metadataPath: (mdxPath) => {
158
- if (excludeRegex.test(slash_1.default(mdxPath))) {
159
- return null;
160
- }
161
- const aliasedSource = utils_1.aliasedSitePath(mdxPath, siteDir);
162
- return path_1.default.join(dataDir, `${utils_1.docuHash(aliasedSource)}.json`);
149
+ // Note that metadataPath must be the same/in-sync as
150
+ // the path from createData for each MDX.
151
+ const aliasedSource = (0, utils_1.aliasedSitePath)(mdxPath, siteDir);
152
+ return path_1.default.join(dataDir, `${(0, utils_1.docuHash)(aliasedSource)}.json`);
163
153
  },
164
- forbidFrontMatter: (mdxPath) => excludeRegex.test(slash_1.default(mdxPath)),
165
154
  },
166
155
  },
167
156
  {
@@ -4,9 +4,5 @@
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
- /// <reference types="node" />
8
- interface Loader extends Function {
9
- (this: any, source: string): string | Buffer | void | undefined;
10
- }
11
- declare const markdownLoader: Loader;
12
- export default markdownLoader;
7
+ import type { LoaderContext } from 'webpack';
8
+ export default function markdownLoader(this: LoaderContext<undefined>, fileString: string): void;
@@ -6,11 +6,11 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- const markdownLoader = function (fileString) {
9
+ function markdownLoader(fileString) {
10
10
  const callback = this.async();
11
11
  // const options = this.getOptions();
12
- // TODO provide additinal md processing here? like interlinking pages?
12
+ // TODO provide additional md processing here? like interlinking pages?
13
13
  // fileString = linkify(fileString)
14
14
  return callback && callback(null, fileString);
15
- };
15
+ }
16
16
  exports.default = markdownLoader;
@@ -4,11 +4,5 @@
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
-
8
- import React from 'react';
9
-
10
- export default class TranslatedJs extends React.Component {
11
- render() {
12
- return <div>TranslatedJsPage</div>;
13
- }
14
- }
7
+ import type { FrontMatter } from '@docusaurus/plugin-content-pages';
8
+ export declare function validatePageFrontMatter(frontMatter: Record<string, unknown>): FrontMatter;
@@ -0,0 +1,21 @@
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.validatePageFrontMatter = void 0;
10
+ const utils_validation_1 = require("@docusaurus/utils-validation");
11
+ const PageFrontMatterSchema = utils_validation_1.Joi.object({
12
+ title: utils_validation_1.Joi.string(),
13
+ description: utils_validation_1.Joi.string(),
14
+ wrapperClassName: utils_validation_1.Joi.string(),
15
+ hide_table_of_contents: utils_validation_1.Joi.boolean(),
16
+ ...utils_validation_1.FrontMatterTOCHeadingLevels,
17
+ });
18
+ function validatePageFrontMatter(frontMatter) {
19
+ return (0, utils_validation_1.validateFrontMatter)(frontMatter, PageFrontMatterSchema);
20
+ }
21
+ exports.validatePageFrontMatter = validatePageFrontMatter;
@@ -4,7 +4,7 @@
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 { PluginOptions } from './types';
7
+ import type { PluginOptions } from '@docusaurus/plugin-content-pages';
8
8
  import { Joi } from '@docusaurus/utils-validation';
9
9
  export declare const DEFAULT_OPTIONS: PluginOptions;
10
10
  export declare const PluginOptionSchema: Joi.ObjectSchema<any>;
@@ -1,22 +1,25 @@
1
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
+ */
2
8
  Object.defineProperty(exports, "__esModule", { value: true });
3
9
  exports.PluginOptionSchema = exports.DEFAULT_OPTIONS = void 0;
4
10
  const utils_validation_1 = require("@docusaurus/utils-validation");
11
+ const utils_1 = require("@docusaurus/utils");
5
12
  exports.DEFAULT_OPTIONS = {
6
13
  path: 'src/pages',
7
14
  routeBasePath: '/',
8
15
  include: ['**/*.{js,jsx,ts,tsx,md,mdx}'],
16
+ exclude: utils_1.GlobExcludeDefault,
9
17
  mdxPageComponent: '@theme/MDXPage',
10
18
  remarkPlugins: [],
11
19
  rehypePlugins: [],
12
20
  beforeDefaultRehypePlugins: [],
13
21
  beforeDefaultRemarkPlugins: [],
14
22
  admonitions: {},
15
- exclude: [
16
- '**/_*.{js,jsx,ts,tsx,md,mdx}',
17
- '**/*.test.{js,ts}',
18
- '**/__tests__/**',
19
- ],
20
23
  };
21
24
  exports.PluginOptionSchema = utils_validation_1.Joi.object({
22
25
  path: utils_validation_1.Joi.string().default(exports.DEFAULT_OPTIONS.path),
package/lib/types.d.ts CHANGED
@@ -4,27 +4,7 @@
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 type { RemarkAndRehypePluginOptions } from '@docusaurus/mdx-loader';
8
- export interface PluginOptions extends RemarkAndRehypePluginOptions {
9
- id?: string;
10
- path: string;
11
- routeBasePath: string;
12
- include: string[];
13
- exclude: string[];
14
- mdxPageComponent: string;
15
- admonitions: Record<string, unknown>;
16
- }
17
- export declare type JSXPageMetadata = {
18
- type: 'jsx';
19
- permalink: string;
20
- source: string;
21
- };
22
- export declare type MDXPageMetadata = {
23
- type: 'mdx';
24
- permalink: string;
25
- source: string;
26
- };
27
- export declare type Metadata = JSXPageMetadata | MDXPageMetadata;
7
+ import type { Metadata } from '@docusaurus/plugin-content-pages';
28
8
  export declare type LoadedContent = Metadata[];
29
9
  export declare type PagesContentPaths = {
30
10
  contentPath: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/plugin-content-pages",
3
- "version": "2.0.0-beta.15a2b59f9",
3
+ "version": "2.0.0-beta.17",
4
4
  "description": "Pages plugin for Docusaurus.",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/plugin-content-pages.d.ts",
@@ -18,25 +18,24 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
- "@docusaurus/core": "2.0.0-beta.15a2b59f9",
22
- "@docusaurus/mdx-loader": "2.0.0-beta.15a2b59f9",
23
- "@docusaurus/types": "2.0.0-beta.15a2b59f9",
24
- "@docusaurus/utils": "2.0.0-beta.15a2b59f9",
25
- "@docusaurus/utils-validation": "2.0.0-beta.15a2b59f9",
26
- "globby": "^11.0.2",
27
- "lodash": "^4.17.20",
28
- "minimatch": "^3.0.4",
21
+ "@docusaurus/core": "2.0.0-beta.17",
22
+ "@docusaurus/mdx-loader": "2.0.0-beta.17",
23
+ "@docusaurus/utils": "2.0.0-beta.17",
24
+ "@docusaurus/utils-validation": "2.0.0-beta.17",
25
+ "fs-extra": "^10.0.1",
29
26
  "remark-admonitions": "^1.2.1",
30
- "slash": "^3.0.0",
31
- "tslib": "^2.1.0",
32
- "webpack": "^5.40.0"
27
+ "tslib": "^2.3.1",
28
+ "webpack": "^5.69.1"
29
+ },
30
+ "devDependencies": {
31
+ "@docusaurus/types": "2.0.0-beta.17"
33
32
  },
34
33
  "peerDependencies": {
35
34
  "react": "^16.8.4 || ^17.0.0",
36
35
  "react-dom": "^16.8.4 || ^17.0.0"
37
36
  },
38
37
  "engines": {
39
- "node": ">=12.13.0"
38
+ "node": ">=14"
40
39
  },
41
- "gitHead": "34881586224092fb9b5b2f455a46e19b3eee7f08"
40
+ "gitHead": "0032c0b0480083227af2e1b4da2d3ee6ce992403"
42
41
  }
File without changes
package/src/index.ts CHANGED
@@ -5,11 +5,8 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import globby from 'globby';
9
- import fs from 'fs';
8
+ import fs from 'fs-extra';
10
9
  import path from 'path';
11
- import minimatch from 'minimatch';
12
- import slash from 'slash';
13
10
  import {
14
11
  encodePath,
15
12
  fileToPath,
@@ -18,29 +15,24 @@ import {
18
15
  getPluginI18nPath,
19
16
  getFolderContainingFile,
20
17
  addTrailingPathSeparator,
18
+ Globby,
19
+ createAbsoluteFilePathMatcher,
20
+ normalizeUrl,
21
+ DEFAULT_PLUGIN_ID,
22
+ parseMarkdownString,
21
23
  } from '@docusaurus/utils';
22
- import {
24
+ import type {
23
25
  LoadContext,
24
26
  Plugin,
25
27
  OptionValidationContext,
26
28
  ValidationResult,
27
- ConfigureWebpackUtils,
28
29
  } from '@docusaurus/types';
29
- import {Configuration} from 'webpack';
30
30
  import admonitions from 'remark-admonitions';
31
31
  import {PluginOptionSchema} from './pluginOptionSchema';
32
- import {
33
- DEFAULT_PLUGIN_ID,
34
- STATIC_DIR_NAME,
35
- } from '@docusaurus/core/lib/constants';
32
+ import {validatePageFrontMatter} from './pageFrontMatter';
36
33
 
37
- import {
38
- PluginOptions,
39
- LoadedContent,
40
- Metadata,
41
- PagesContentPaths,
42
- } from './types';
43
- import {flatten} from 'lodash';
34
+ import type {LoadedContent, PagesContentPaths} from './types';
35
+ import type {PluginOptions, Metadata} from '@docusaurus/plugin-content-pages';
44
36
 
45
37
  export function getContentPathList(contentPaths: PagesContentPaths): string[] {
46
38
  return [contentPaths.contentPathLocalized, contentPaths.contentPath];
@@ -49,10 +41,10 @@ export function getContentPathList(contentPaths: PagesContentPaths): string[] {
49
41
  const isMarkdownSource = (source: string) =>
50
42
  source.endsWith('.md') || source.endsWith('.mdx');
51
43
 
52
- export default function pluginContentPages(
44
+ export default async function pluginContentPages(
53
45
  context: LoadContext,
54
46
  options: PluginOptions,
55
- ): Plugin<LoadedContent | null> {
47
+ ): Promise<Plugin<LoadedContent | null>> {
56
48
  if (options.admonitions) {
57
49
  options.remarkPlugins = options.remarkPlugins.concat([
58
50
  [admonitions, options.admonitions || {}],
@@ -81,42 +73,25 @@ export default function pluginContentPages(
81
73
  );
82
74
  const dataDir = path.join(pluginDataDirRoot, options.id ?? DEFAULT_PLUGIN_ID);
83
75
 
84
- const excludeRegex = new RegExp(
85
- options.exclude
86
- .map((pattern) => minimatch.makeRe(pattern).source)
87
- .join('|'),
88
- );
89
76
  return {
90
77
  name: 'docusaurus-plugin-content-pages',
91
78
 
92
79
  getPathsToWatch() {
93
80
  const {include = []} = options;
94
- return flatten(
95
- getContentPathList(contentPaths).map((contentPath) => {
96
- return include.map((pattern) => `${contentPath}/${pattern}`);
97
- }),
81
+ return getContentPathList(contentPaths).flatMap((contentPath) =>
82
+ include.map((pattern) => `${contentPath}/${pattern}`),
98
83
  );
99
84
  },
100
85
 
101
- getClientModules() {
102
- const modules = [];
103
-
104
- if (options.admonitions) {
105
- modules.push(require.resolve('remark-admonitions/styles/infima.css'));
106
- }
107
-
108
- return modules;
109
- },
110
-
111
86
  async loadContent() {
112
87
  const {include} = options;
113
88
 
114
- if (!fs.existsSync(contentPaths.contentPath)) {
89
+ if (!(await fs.pathExists(contentPaths.contentPath))) {
115
90
  return null;
116
91
  }
117
92
 
118
93
  const {baseUrl} = siteConfig;
119
- const pagesFiles = await globby(include, {
94
+ const pagesFiles = await Globby(include, {
120
95
  cwd: contentPaths.contentPath,
121
96
  ignore: options.exclude,
122
97
  });
@@ -130,21 +105,33 @@ export default function pluginContentPages(
130
105
 
131
106
  const source = path.join(contentPath, relativeSource);
132
107
  const aliasedSourcePath = aliasedSitePath(source, siteDir);
133
- const pathName = encodePath(fileToPath(relativeSource));
134
- const permalink = pathName.replace(/^\//, baseUrl || '');
135
- if (isMarkdownSource(relativeSource)) {
136
- return {
137
- type: 'mdx',
138
- permalink,
139
- source: aliasedSourcePath,
140
- };
141
- } else {
108
+ const permalink = normalizeUrl([
109
+ baseUrl,
110
+ options.routeBasePath,
111
+ encodePath(fileToPath(relativeSource)),
112
+ ]);
113
+ if (!isMarkdownSource(relativeSource)) {
142
114
  return {
143
115
  type: 'jsx',
144
116
  permalink,
145
117
  source: aliasedSourcePath,
146
118
  };
147
119
  }
120
+ const content = await fs.readFile(source, 'utf-8');
121
+ const {
122
+ frontMatter: unsafeFrontMatter,
123
+ contentTitle,
124
+ excerpt,
125
+ } = parseMarkdownString(content);
126
+ const frontMatter = validatePageFrontMatter(unsafeFrontMatter);
127
+ return {
128
+ type: 'mdx',
129
+ permalink,
130
+ source: aliasedSourcePath,
131
+ title: frontMatter.title ?? contentTitle,
132
+ description: frontMatter.description ?? excerpt,
133
+ frontMatter,
134
+ };
148
135
  }
149
136
 
150
137
  return Promise.all(pagesFiles.map(toMetadata));
@@ -189,17 +176,14 @@ export default function pluginContentPages(
189
176
  );
190
177
  },
191
178
 
192
- configureWebpack(
193
- _config: Configuration,
194
- isServer: boolean,
195
- {getJSLoader}: ConfigureWebpackUtils,
196
- ) {
179
+ configureWebpack(_config, isServer, {getJSLoader}) {
197
180
  const {
198
181
  rehypePlugins,
199
182
  remarkPlugins,
200
183
  beforeDefaultRehypePlugins,
201
184
  beforeDefaultRemarkPlugins,
202
185
  } = options;
186
+ const contentDirs = getContentPathList(contentPaths);
203
187
  return {
204
188
  resolve: {
205
189
  alias: {
@@ -209,8 +193,8 @@ export default function pluginContentPages(
209
193
  module: {
210
194
  rules: [
211
195
  {
212
- test: /(\.mdx?)$/,
213
- include: getContentPathList(contentPaths)
196
+ test: /\.mdx?$/i,
197
+ include: contentDirs
214
198
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
215
199
  .map(addTrailingPathSeparator),
216
200
  use: [
@@ -222,21 +206,23 @@ export default function pluginContentPages(
222
206
  rehypePlugins,
223
207
  beforeDefaultRehypePlugins,
224
208
  beforeDefaultRemarkPlugins,
225
- staticDir: path.join(siteDir, STATIC_DIR_NAME),
226
- // Note that metadataPath must be the same/in-sync as
227
- // the path from createData for each MDX.
209
+ staticDirs: siteConfig.staticDirectories.map((dir) =>
210
+ path.resolve(siteDir, dir),
211
+ ),
212
+ siteDir,
213
+ isMDXPartial: createAbsoluteFilePathMatcher(
214
+ options.exclude,
215
+ contentDirs,
216
+ ),
228
217
  metadataPath: (mdxPath: string) => {
229
- if (excludeRegex.test(slash(mdxPath))) {
230
- return null;
231
- }
218
+ // Note that metadataPath must be the same/in-sync as
219
+ // the path from createData for each MDX.
232
220
  const aliasedSource = aliasedSitePath(mdxPath, siteDir);
233
221
  return path.join(
234
222
  dataDir,
235
223
  `${docuHash(aliasedSource)}.json`,
236
224
  );
237
225
  },
238
- forbidFrontMatter: (mdxPath: string) =>
239
- excludeRegex.test(slash(mdxPath)),
240
226
  },
241
227
  },
242
228
  {
@@ -5,21 +5,18 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- // TODO temporary until Webpack5 export this type
9
- // see https://github.com/webpack/webpack/issues/11630
10
- interface Loader extends Function {
11
- (this: any, source: string): string | Buffer | void | undefined;
12
- }
8
+ import type {LoaderContext} from 'webpack';
13
9
 
14
- const markdownLoader: Loader = function (fileString) {
10
+ export default function markdownLoader(
11
+ this: LoaderContext<undefined>,
12
+ fileString: string,
13
+ ): void {
15
14
  const callback = this.async();
16
15
 
17
16
  // const options = this.getOptions();
18
17
 
19
- // TODO provide additinal md processing here? like interlinking pages?
18
+ // TODO provide additional md processing here? like interlinking pages?
20
19
  // fileString = linkify(fileString)
21
20
 
22
21
  return callback && callback(null, fileString);
23
- };
24
-
25
- export default markdownLoader;
22
+ }
@@ -0,0 +1,27 @@
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 {
9
+ Joi,
10
+ validateFrontMatter,
11
+ FrontMatterTOCHeadingLevels,
12
+ } from '@docusaurus/utils-validation';
13
+ import type {FrontMatter} from '@docusaurus/plugin-content-pages';
14
+
15
+ const PageFrontMatterSchema = Joi.object<FrontMatter>({
16
+ title: Joi.string(),
17
+ description: Joi.string(),
18
+ wrapperClassName: Joi.string(),
19
+ hide_table_of_contents: Joi.boolean(),
20
+ ...FrontMatterTOCHeadingLevels,
21
+ });
22
+
23
+ export function validatePageFrontMatter(
24
+ frontMatter: Record<string, unknown>,
25
+ ): FrontMatter {
26
+ return validateFrontMatter(frontMatter, PageFrontMatterSchema);
27
+ }