@docusaurus/plugin-content-pages 2.0.0-beta.ff31de0ff → 2.0.0-rc.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.
Files changed (35) hide show
  1. package/{src/__tests__/__fixtures__/website/i18n/fr/docusaurus-plugin-content-pages/hello/translatedJs.js → lib/frontMatter.d.ts} +4 -8
  2. package/lib/frontMatter.js +21 -0
  3. package/lib/index.d.ts +4 -3
  4. package/lib/index.js +45 -67
  5. package/lib/markdownLoader.d.ts +2 -6
  6. package/lib/markdownLoader.js +4 -4
  7. package/lib/options.d.ts +10 -0
  8. package/lib/{pluginOptionSchema.js → options.js} +16 -8
  9. package/lib/types.d.ts +0 -22
  10. package/package.json +14 -15
  11. package/src/frontMatter.ts +27 -0
  12. package/src/index.ts +57 -90
  13. package/src/markdownLoader.ts +8 -11
  14. package/src/{pluginOptionSchema.ts → options.ts} +15 -8
  15. package/src/plugin-content-pages.d.ts +59 -18
  16. package/src/types.ts +0 -28
  17. package/lib/.tsbuildinfo +0 -4349
  18. package/lib/pluginOptionSchema.d.ts +0 -10
  19. package/src/__tests__/__fixtures__/website/docusaurus.config.js +0 -14
  20. package/src/__tests__/__fixtures__/website/i18n/fr/docusaurus-plugin-content-pages/hello/translatedMd.md +0 -1
  21. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.js +0 -1
  22. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.md +0 -1
  23. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.mdx +0 -1
  24. package/src/__tests__/__fixtures__/website/src/pages/hello/_ignore.tsx +0 -1
  25. package/src/__tests__/__fixtures__/website/src/pages/hello/index.md +0 -2
  26. package/src/__tests__/__fixtures__/website/src/pages/hello/mdxPage.mdx +0 -5
  27. package/src/__tests__/__fixtures__/website/src/pages/hello/translatedJs.js +0 -14
  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
  35. package/types.d.ts +0 -13
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,21 @@ import {
18
15
  getPluginI18nPath,
19
16
  getFolderContainingFile,
20
17
  addTrailingPathSeparator,
21
- } from '@docusaurus/utils';
22
- import {
23
- LoadContext,
24
- Plugin,
25
- OptionValidationContext,
26
- ValidationResult,
27
- ConfigureWebpackUtils,
28
- } from '@docusaurus/types';
29
- import {Configuration} from 'webpack';
30
- import admonitions from 'remark-admonitions';
31
- import {PluginOptionSchema} from './pluginOptionSchema';
32
- import {
18
+ Globby,
19
+ createAbsoluteFilePathMatcher,
20
+ normalizeUrl,
33
21
  DEFAULT_PLUGIN_ID,
34
- STATIC_DIR_NAME,
35
- } from '@docusaurus/core/lib/constants';
22
+ parseMarkdownString,
23
+ } from '@docusaurus/utils';
24
+ import {validatePageFrontMatter} from './frontMatter';
36
25
 
37
- import {
26
+ import type {LoadContext, Plugin} from '@docusaurus/types';
27
+ import type {PagesContentPaths} from './types';
28
+ import type {
38
29
  PluginOptions,
39
- LoadedContent,
40
30
  Metadata,
41
- PagesContentPaths,
42
- } from './types';
43
- import {flatten} from 'lodash';
31
+ LoadedContent,
32
+ } from '@docusaurus/plugin-content-pages';
44
33
 
45
34
  export function getContentPathList(contentPaths: PagesContentPaths): string[] {
46
35
  return [contentPaths.contentPathLocalized, contentPaths.contentPath];
@@ -53,23 +42,12 @@ export default function pluginContentPages(
53
42
  context: LoadContext,
54
43
  options: PluginOptions,
55
44
  ): Plugin<LoadedContent | null> {
56
- if (options.admonitions) {
57
- options.remarkPlugins = options.remarkPlugins.concat([
58
- [admonitions, options.admonitions || {}],
59
- ]);
60
- }
61
- const {
62
- siteConfig,
63
- siteDir,
64
- generatedFilesDir,
65
- i18n: {currentLocale},
66
- } = context;
45
+ const {siteConfig, siteDir, generatedFilesDir, localizationDir} = context;
67
46
 
68
47
  const contentPaths: PagesContentPaths = {
69
48
  contentPath: path.resolve(siteDir, options.path),
70
49
  contentPathLocalized: getPluginI18nPath({
71
- siteDir,
72
- locale: currentLocale,
50
+ localizationDir,
73
51
  pluginName: 'docusaurus-plugin-content-pages',
74
52
  pluginId: options.id,
75
53
  }),
@@ -81,42 +59,25 @@ export default function pluginContentPages(
81
59
  );
82
60
  const dataDir = path.join(pluginDataDirRoot, options.id ?? DEFAULT_PLUGIN_ID);
83
61
 
84
- const excludeRegex = new RegExp(
85
- options.exclude
86
- .map((pattern) => minimatch.makeRe(pattern).source)
87
- .join('|'),
88
- );
89
62
  return {
90
63
  name: 'docusaurus-plugin-content-pages',
91
64
 
92
65
  getPathsToWatch() {
93
- const {include = []} = options;
94
- return flatten(
95
- getContentPathList(contentPaths).map((contentPath) => {
96
- return include.map((pattern) => `${contentPath}/${pattern}`);
97
- }),
66
+ const {include} = options;
67
+ return getContentPathList(contentPaths).flatMap((contentPath) =>
68
+ include.map((pattern) => `${contentPath}/${pattern}`),
98
69
  );
99
70
  },
100
71
 
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
72
  async loadContent() {
112
73
  const {include} = options;
113
74
 
114
- if (!fs.existsSync(contentPaths.contentPath)) {
75
+ if (!(await fs.pathExists(contentPaths.contentPath))) {
115
76
  return null;
116
77
  }
117
78
 
118
79
  const {baseUrl} = siteConfig;
119
- const pagesFiles = await globby(include, {
80
+ const pagesFiles = await Globby(include, {
120
81
  cwd: contentPaths.contentPath,
121
82
  ignore: options.exclude,
122
83
  });
@@ -130,21 +91,33 @@ export default function pluginContentPages(
130
91
 
131
92
  const source = path.join(contentPath, relativeSource);
132
93
  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 {
94
+ const permalink = normalizeUrl([
95
+ baseUrl,
96
+ options.routeBasePath,
97
+ encodePath(fileToPath(relativeSource)),
98
+ ]);
99
+ if (!isMarkdownSource(relativeSource)) {
142
100
  return {
143
101
  type: 'jsx',
144
102
  permalink,
145
103
  source: aliasedSourcePath,
146
104
  };
147
105
  }
106
+ const content = await fs.readFile(source, 'utf-8');
107
+ const {
108
+ frontMatter: unsafeFrontMatter,
109
+ contentTitle,
110
+ excerpt,
111
+ } = parseMarkdownString(content);
112
+ const frontMatter = validatePageFrontMatter(unsafeFrontMatter);
113
+ return {
114
+ type: 'mdx',
115
+ permalink,
116
+ source: aliasedSourcePath,
117
+ title: frontMatter.title ?? contentTitle,
118
+ description: frontMatter.description ?? excerpt,
119
+ frontMatter,
120
+ };
148
121
  }
149
122
 
150
123
  return Promise.all(pagesFiles.map(toMetadata));
@@ -189,17 +162,15 @@ export default function pluginContentPages(
189
162
  );
190
163
  },
191
164
 
192
- configureWebpack(
193
- _config: Configuration,
194
- isServer: boolean,
195
- {getJSLoader}: ConfigureWebpackUtils,
196
- ) {
165
+ configureWebpack(config, isServer, {getJSLoader}) {
197
166
  const {
167
+ admonitions,
198
168
  rehypePlugins,
199
169
  remarkPlugins,
200
170
  beforeDefaultRehypePlugins,
201
171
  beforeDefaultRemarkPlugins,
202
172
  } = options;
173
+ const contentDirs = getContentPathList(contentPaths);
203
174
  return {
204
175
  resolve: {
205
176
  alias: {
@@ -209,8 +180,8 @@ export default function pluginContentPages(
209
180
  module: {
210
181
  rules: [
211
182
  {
212
- test: /(\.mdx?)$/,
213
- include: getContentPathList(contentPaths)
183
+ test: /\.mdx?$/i,
184
+ include: contentDirs
214
185
  // Trailing slash is important, see https://github.com/facebook/docusaurus/pull/3970
215
186
  .map(addTrailingPathSeparator),
216
187
  use: [
@@ -218,26 +189,28 @@ export default function pluginContentPages(
218
189
  {
219
190
  loader: require.resolve('@docusaurus/mdx-loader'),
220
191
  options: {
192
+ admonitions,
221
193
  remarkPlugins,
222
194
  rehypePlugins,
223
195
  beforeDefaultRehypePlugins,
224
196
  beforeDefaultRemarkPlugins,
225
- keepContentTitle: true,
226
- staticDir: path.join(siteDir, STATIC_DIR_NAME),
227
- // Note that metadataPath must be the same/in-sync as
228
- // the path from createData for each MDX.
197
+ staticDirs: siteConfig.staticDirectories.map((dir) =>
198
+ path.resolve(siteDir, dir),
199
+ ),
200
+ siteDir,
201
+ isMDXPartial: createAbsoluteFilePathMatcher(
202
+ options.exclude,
203
+ contentDirs,
204
+ ),
229
205
  metadataPath: (mdxPath: string) => {
230
- if (excludeRegex.test(slash(mdxPath))) {
231
- return null;
232
- }
206
+ // Note that metadataPath must be the same/in-sync as
207
+ // the path from createData for each MDX.
233
208
  const aliasedSource = aliasedSitePath(mdxPath, siteDir);
234
209
  return path.join(
235
210
  dataDir,
236
211
  `${docuHash(aliasedSource)}.json`,
237
212
  );
238
213
  },
239
- forbidFrontMatter: (mdxPath: string) =>
240
- excludeRegex.test(slash(mdxPath)),
241
214
  },
242
215
  },
243
216
  {
@@ -256,10 +229,4 @@ export default function pluginContentPages(
256
229
  };
257
230
  }
258
231
 
259
- export function validateOptions({
260
- validate,
261
- options,
262
- }: OptionValidationContext<PluginOptions>): ValidationResult<PluginOptions> {
263
- const validatedOptions = validate(PluginOptionSchema, options);
264
- return validatedOptions;
265
- }
232
+ export {validateOptions} from './options';
@@ -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
- return callback && callback(null, fileString);
23
- };
24
-
25
- export default markdownLoader;
21
+ return callback(null, fileString);
22
+ }
@@ -4,32 +4,31 @@
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
+
8
8
  import {
9
9
  Joi,
10
10
  RemarkPluginsSchema,
11
11
  RehypePluginsSchema,
12
12
  AdmonitionsSchema,
13
13
  } from '@docusaurus/utils-validation';
14
+ import {GlobExcludeDefault} from '@docusaurus/utils';
15
+ import type {OptionValidationContext} from '@docusaurus/types';
16
+ import type {PluginOptions, Options} from '@docusaurus/plugin-content-pages';
14
17
 
15
18
  export const DEFAULT_OPTIONS: PluginOptions = {
16
19
  path: 'src/pages', // Path to data on filesystem, relative to site dir.
17
20
  routeBasePath: '/', // URL Route.
18
21
  include: ['**/*.{js,jsx,ts,tsx,md,mdx}'], // Extensions to include.
22
+ exclude: GlobExcludeDefault,
19
23
  mdxPageComponent: '@theme/MDXPage',
20
24
  remarkPlugins: [],
21
25
  rehypePlugins: [],
22
26
  beforeDefaultRehypePlugins: [],
23
27
  beforeDefaultRemarkPlugins: [],
24
- admonitions: {},
25
- exclude: [
26
- '**/_*.{js,jsx,ts,tsx,md,mdx}',
27
- '**/*.test.{js,ts}',
28
- '**/__tests__/**',
29
- ],
28
+ admonitions: true,
30
29
  };
31
30
 
32
- export const PluginOptionSchema = Joi.object({
31
+ const PluginOptionSchema = Joi.object<PluginOptions>({
33
32
  path: Joi.string().default(DEFAULT_OPTIONS.path),
34
33
  routeBasePath: Joi.string().default(DEFAULT_OPTIONS.routeBasePath),
35
34
  include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
@@ -45,3 +44,11 @@ export const PluginOptionSchema = Joi.object({
45
44
  ),
46
45
  admonitions: AdmonitionsSchema.default(DEFAULT_OPTIONS.admonitions),
47
46
  });
47
+
48
+ export function validateOptions({
49
+ validate,
50
+ options,
51
+ }: OptionValidationContext<Options, PluginOptions>): PluginOptions {
52
+ const validatedOptions = validate(PluginOptionSchema, options);
53
+ return validatedOptions;
54
+ }
@@ -5,24 +5,65 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- declare module '@theme/MDXPage' {
9
- import type {TOCItem} from '@docusaurus/types';
10
-
11
- export type Props = {
12
- readonly content: {
13
- readonly frontMatter: {
14
- readonly title: string;
15
- readonly description: string;
16
- readonly wrapperClassName?: string;
17
- // eslint-disable-next-line camelcase
18
- readonly hide_table_of_contents?: string;
19
- };
20
- readonly metadata: {readonly permalink: string};
21
- readonly toc: readonly TOCItem[];
22
- (): JSX.Element;
23
- };
8
+ declare module '@docusaurus/plugin-content-pages' {
9
+ import type {MDXOptions} from '@docusaurus/mdx-loader';
10
+ import type {LoadContext, Plugin} from '@docusaurus/types';
11
+
12
+ export type PluginOptions = MDXOptions & {
13
+ id?: string;
14
+ path: string;
15
+ routeBasePath: string;
16
+ include: string[];
17
+ exclude: string[];
18
+ mdxPageComponent: string;
19
+ };
20
+
21
+ export type Options = Partial<PluginOptions>;
22
+
23
+ export type FrontMatter = {
24
+ readonly title?: string;
25
+ readonly description?: string;
26
+ readonly wrapperClassName?: string;
27
+ readonly hide_table_of_contents?: string;
28
+ readonly toc_min_heading_level?: number;
29
+ readonly toc_max_heading_level?: number;
30
+ };
31
+
32
+ export type JSXPageMetadata = {
33
+ type: 'jsx';
34
+ permalink: string;
35
+ source: string;
36
+ };
37
+
38
+ export type MDXPageMetadata = {
39
+ type: 'mdx';
40
+ permalink: string;
41
+ source: string;
42
+ frontMatter: FrontMatter & {[key: string]: unknown};
43
+ title?: string;
44
+ description?: string;
24
45
  };
25
46
 
26
- const MDXPage: (props: Props) => JSX.Element;
27
- export default MDXPage;
47
+ export type Metadata = JSXPageMetadata | MDXPageMetadata;
48
+
49
+ export type LoadedContent = Metadata[];
50
+
51
+ export default function pluginContentPages(
52
+ context: LoadContext,
53
+ options: PluginOptions,
54
+ ): Promise<Plugin<LoadedContent | null>>;
55
+ }
56
+
57
+ declare module '@theme/MDXPage' {
58
+ import type {LoadedMDXContent} from '@docusaurus/mdx-loader';
59
+ import type {
60
+ MDXPageMetadata,
61
+ FrontMatter,
62
+ } from '@docusaurus/plugin-content-pages';
63
+
64
+ export interface Props {
65
+ readonly content: LoadedMDXContent<FrontMatter, MDXPageMetadata>;
66
+ }
67
+
68
+ export default function MDXPage(props: Props): JSX.Element;
28
69
  }
package/src/types.ts CHANGED
@@ -5,34 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import type {RemarkAndRehypePluginOptions} from '@docusaurus/mdx-loader';
9
-
10
- export interface PluginOptions extends RemarkAndRehypePluginOptions {
11
- id?: string;
12
- path: string;
13
- routeBasePath: string;
14
- include: string[];
15
- exclude: string[];
16
- mdxPageComponent: string;
17
- admonitions: Record<string, unknown>;
18
- }
19
-
20
- export type JSXPageMetadata = {
21
- type: 'jsx';
22
- permalink: string;
23
- source: string;
24
- };
25
-
26
- export type MDXPageMetadata = {
27
- type: 'mdx';
28
- permalink: string;
29
- source: string;
30
- };
31
-
32
- export type Metadata = JSXPageMetadata | MDXPageMetadata;
33
-
34
- export type LoadedContent = Metadata[];
35
-
36
8
  export type PagesContentPaths = {
37
9
  contentPath: string;
38
10
  contentPathLocalized: string;