@docusaurus/plugin-content-pages 0.0.0-5899 → 0.0.0-5900

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.
@@ -0,0 +1,21 @@
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 { LoadContext } from '@docusaurus/types';
8
+ import type { PagesContentPaths } from './types';
9
+ import type { PluginOptions, LoadedContent } from '@docusaurus/plugin-content-pages';
10
+ export declare function createPagesContentPaths({ context, options, }: {
11
+ context: LoadContext;
12
+ options: PluginOptions;
13
+ }): PagesContentPaths;
14
+ export declare function getContentPathList(contentPaths: PagesContentPaths): string[];
15
+ type LoadContentParams = {
16
+ context: LoadContext;
17
+ options: PluginOptions;
18
+ contentPaths: PagesContentPaths;
19
+ };
20
+ export declare function loadPagesContent(params: LoadContentParams): Promise<LoadedContent>;
21
+ export {};
package/lib/content.js ADDED
@@ -0,0 +1,120 @@
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.loadPagesContent = exports.getContentPathList = exports.createPagesContentPaths = void 0;
10
+ const tslib_1 = require("tslib");
11
+ const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
+ const path_1 = tslib_1.__importDefault(require("path"));
13
+ const utils_1 = require("@docusaurus/utils");
14
+ const frontMatter_1 = require("./frontMatter");
15
+ function createPagesContentPaths({ context, options, }) {
16
+ const { siteDir, localizationDir } = context;
17
+ return {
18
+ contentPath: path_1.default.resolve(siteDir, options.path),
19
+ contentPathLocalized: (0, utils_1.getPluginI18nPath)({
20
+ localizationDir,
21
+ pluginName: 'docusaurus-plugin-content-pages',
22
+ pluginId: options.id,
23
+ }),
24
+ };
25
+ }
26
+ exports.createPagesContentPaths = createPagesContentPaths;
27
+ function getContentPathList(contentPaths) {
28
+ return [contentPaths.contentPathLocalized, contentPaths.contentPath];
29
+ }
30
+ exports.getContentPathList = getContentPathList;
31
+ const isMarkdownSource = (source) => source.endsWith('.md') || source.endsWith('.mdx');
32
+ async function loadPagesContent(params) {
33
+ const { options } = params;
34
+ const pagesFiles = await (0, utils_1.Globby)(params.options.include, {
35
+ cwd: params.contentPaths.contentPath,
36
+ ignore: options.exclude,
37
+ });
38
+ async function doProcessPageSourceFile(relativeSource) {
39
+ try {
40
+ return await processPageSourceFile(relativeSource, params);
41
+ }
42
+ catch (err) {
43
+ throw new Error(`Processing of page source file path=${relativeSource} failed.`, { cause: err });
44
+ }
45
+ }
46
+ return (await Promise.all(pagesFiles.map(doProcessPageSourceFile))).filter((res) => {
47
+ return res !== undefined;
48
+ });
49
+ }
50
+ exports.loadPagesContent = loadPagesContent;
51
+ async function processPageSourceFile(relativeSource, params) {
52
+ const { context, options, contentPaths } = params;
53
+ const { siteConfig, baseUrl, siteDir, i18n } = context;
54
+ const { editUrl } = options;
55
+ // Lookup in localized folder in priority
56
+ const contentPath = await (0, utils_1.getFolderContainingFile)(getContentPathList(contentPaths), relativeSource);
57
+ const source = path_1.default.join(contentPath, relativeSource);
58
+ const aliasedSourcePath = (0, utils_1.aliasedSitePath)(source, siteDir);
59
+ const permalink = (0, utils_1.normalizeUrl)([
60
+ baseUrl,
61
+ options.routeBasePath,
62
+ (0, utils_1.encodePath)((0, utils_1.fileToPath)(relativeSource)),
63
+ ]);
64
+ if (!isMarkdownSource(relativeSource)) {
65
+ return {
66
+ type: 'jsx',
67
+ permalink,
68
+ source: aliasedSourcePath,
69
+ };
70
+ }
71
+ const content = await fs_extra_1.default.readFile(source, 'utf-8');
72
+ const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = await (0, utils_1.parseMarkdownFile)({
73
+ filePath: source,
74
+ fileContent: content,
75
+ parseFrontMatter: siteConfig.markdown.parseFrontMatter,
76
+ });
77
+ const frontMatter = (0, frontMatter_1.validatePageFrontMatter)(unsafeFrontMatter);
78
+ const pagesDirPath = await (0, utils_1.getFolderContainingFile)(getContentPathList(contentPaths), relativeSource);
79
+ const pagesSourceAbsolute = path_1.default.join(pagesDirPath, relativeSource);
80
+ function getPagesEditUrl() {
81
+ const pagesPathRelative = path_1.default.relative(pagesDirPath, path_1.default.resolve(pagesSourceAbsolute));
82
+ if (typeof editUrl === 'function') {
83
+ return editUrl({
84
+ pagesDirPath: (0, utils_1.posixPath)(path_1.default.relative(siteDir, pagesDirPath)),
85
+ pagesPath: (0, utils_1.posixPath)(pagesPathRelative),
86
+ permalink,
87
+ locale: i18n.currentLocale,
88
+ });
89
+ }
90
+ else if (typeof editUrl === 'string') {
91
+ const isLocalized = pagesDirPath === contentPaths.contentPathLocalized;
92
+ const fileContentPath = isLocalized && options.editLocalizedFiles
93
+ ? contentPaths.contentPathLocalized
94
+ : contentPaths.contentPath;
95
+ const contentPathEditUrl = (0, utils_1.normalizeUrl)([
96
+ editUrl,
97
+ (0, utils_1.posixPath)(path_1.default.relative(siteDir, fileContentPath)),
98
+ ]);
99
+ return (0, utils_1.getEditUrl)(pagesPathRelative, contentPathEditUrl);
100
+ }
101
+ return undefined;
102
+ }
103
+ const lastUpdatedData = await (0, utils_1.readLastUpdateData)(source, options, frontMatter.last_update);
104
+ if ((0, utils_1.isDraft)({ frontMatter })) {
105
+ return undefined;
106
+ }
107
+ const unlisted = (0, utils_1.isUnlisted)({ frontMatter });
108
+ return {
109
+ type: 'mdx',
110
+ permalink,
111
+ source: aliasedSourcePath,
112
+ title: frontMatter.title ?? contentTitle,
113
+ description: frontMatter.description ?? excerpt,
114
+ frontMatter,
115
+ lastUpdatedBy: lastUpdatedData.lastUpdatedBy,
116
+ lastUpdatedAt: lastUpdatedData.lastUpdatedAt,
117
+ editUrl: getPagesEditUrl(),
118
+ unlisted,
119
+ };
120
+ }
package/lib/index.d.ts CHANGED
@@ -5,8 +5,6 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { LoadContext, Plugin } from '@docusaurus/types';
8
- import type { PagesContentPaths } from './types';
9
8
  import type { PluginOptions, LoadedContent } from '@docusaurus/plugin-content-pages';
10
- export declare function getContentPathList(contentPaths: PagesContentPaths): string[];
11
9
  export default function pluginContentPages(context: LoadContext, options: PluginOptions): Plugin<LoadedContent | null>;
12
10
  export { validateOptions } from './options';
package/lib/index.js CHANGED
@@ -6,174 +6,40 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.validateOptions = exports.getContentPathList = void 0;
9
+ exports.validateOptions = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const fs_extra_1 = tslib_1.__importDefault(require("fs-extra"));
12
12
  const path_1 = tslib_1.__importDefault(require("path"));
13
13
  const utils_1 = require("@docusaurus/utils");
14
- const frontMatter_1 = require("./frontMatter");
15
- function getContentPathList(contentPaths) {
16
- return [contentPaths.contentPathLocalized, contentPaths.contentPath];
17
- }
18
- exports.getContentPathList = getContentPathList;
19
- const isMarkdownSource = (source) => source.endsWith('.md') || source.endsWith('.mdx');
14
+ const routes_1 = require("./routes");
15
+ const content_1 = require("./content");
20
16
  function pluginContentPages(context, options) {
21
- const { siteConfig, siteDir, generatedFilesDir, localizationDir, i18n } = context;
22
- const contentPaths = {
23
- contentPath: path_1.default.resolve(siteDir, options.path),
24
- contentPathLocalized: (0, utils_1.getPluginI18nPath)({
25
- localizationDir,
26
- pluginName: 'docusaurus-plugin-content-pages',
27
- pluginId: options.id,
28
- }),
29
- };
17
+ const { siteConfig, siteDir, generatedFilesDir } = context;
18
+ const contentPaths = (0, content_1.createPagesContentPaths)({ context, options });
30
19
  const pluginDataDirRoot = path_1.default.join(generatedFilesDir, 'docusaurus-plugin-content-pages');
31
20
  const dataDir = path_1.default.join(pluginDataDirRoot, options.id ?? utils_1.DEFAULT_PLUGIN_ID);
32
21
  return {
33
22
  name: 'docusaurus-plugin-content-pages',
34
23
  getPathsToWatch() {
35
24
  const { include } = options;
36
- return getContentPathList(contentPaths).flatMap((contentPath) => include.map((pattern) => `${contentPath}/${pattern}`));
25
+ return (0, content_1.getContentPathList)(contentPaths).flatMap((contentPath) => include.map((pattern) => `${contentPath}/${pattern}`));
37
26
  },
38
27
  async loadContent() {
39
- const { include, editUrl } = options;
40
28
  if (!(await fs_extra_1.default.pathExists(contentPaths.contentPath))) {
41
29
  return null;
42
30
  }
43
- const { baseUrl } = siteConfig;
44
- const pagesFiles = await (0, utils_1.Globby)(include, {
45
- cwd: contentPaths.contentPath,
46
- ignore: options.exclude,
47
- });
48
- async function processPageSourceFile(relativeSource) {
49
- // Lookup in localized folder in priority
50
- const contentPath = await (0, utils_1.getFolderContainingFile)(getContentPathList(contentPaths), relativeSource);
51
- const source = path_1.default.join(contentPath, relativeSource);
52
- const aliasedSourcePath = (0, utils_1.aliasedSitePath)(source, siteDir);
53
- const permalink = (0, utils_1.normalizeUrl)([
54
- baseUrl,
55
- options.routeBasePath,
56
- (0, utils_1.encodePath)((0, utils_1.fileToPath)(relativeSource)),
57
- ]);
58
- if (!isMarkdownSource(relativeSource)) {
59
- return {
60
- type: 'jsx',
61
- permalink,
62
- source: aliasedSourcePath,
63
- };
64
- }
65
- const content = await fs_extra_1.default.readFile(source, 'utf-8');
66
- const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = await (0, utils_1.parseMarkdownFile)({
67
- filePath: source,
68
- fileContent: content,
69
- parseFrontMatter: siteConfig.markdown.parseFrontMatter,
70
- });
71
- const frontMatter = (0, frontMatter_1.validatePageFrontMatter)(unsafeFrontMatter);
72
- const pagesDirPath = await (0, utils_1.getFolderContainingFile)(getContentPathList(contentPaths), relativeSource);
73
- const pagesSourceAbsolute = path_1.default.join(pagesDirPath, relativeSource);
74
- function getPagesEditUrl() {
75
- const pagesPathRelative = path_1.default.relative(pagesDirPath, path_1.default.resolve(pagesSourceAbsolute));
76
- if (typeof editUrl === 'function') {
77
- return editUrl({
78
- pagesDirPath: (0, utils_1.posixPath)(path_1.default.relative(siteDir, pagesDirPath)),
79
- pagesPath: (0, utils_1.posixPath)(pagesPathRelative),
80
- permalink,
81
- locale: i18n.currentLocale,
82
- });
83
- }
84
- else if (typeof editUrl === 'string') {
85
- const isLocalized = pagesDirPath === contentPaths.contentPathLocalized;
86
- const fileContentPath = isLocalized && options.editLocalizedFiles
87
- ? contentPaths.contentPathLocalized
88
- : contentPaths.contentPath;
89
- const contentPathEditUrl = (0, utils_1.normalizeUrl)([
90
- editUrl,
91
- (0, utils_1.posixPath)(path_1.default.relative(siteDir, fileContentPath)),
92
- ]);
93
- return (0, utils_1.getEditUrl)(pagesPathRelative, contentPathEditUrl);
94
- }
95
- return undefined;
96
- }
97
- const lastUpdatedData = await (0, utils_1.readLastUpdateData)(source, options, frontMatter.last_update);
98
- if ((0, utils_1.isDraft)({ frontMatter })) {
99
- return undefined;
100
- }
101
- const unlisted = (0, utils_1.isUnlisted)({ frontMatter });
102
- return {
103
- type: 'mdx',
104
- permalink,
105
- source: aliasedSourcePath,
106
- title: frontMatter.title ?? contentTitle,
107
- description: frontMatter.description ?? excerpt,
108
- frontMatter,
109
- lastUpdatedBy: lastUpdatedData.lastUpdatedBy,
110
- lastUpdatedAt: lastUpdatedData.lastUpdatedAt,
111
- editUrl: getPagesEditUrl(),
112
- unlisted,
113
- };
114
- }
115
- async function doProcessPageSourceFile(relativeSource) {
116
- try {
117
- return await processPageSourceFile(relativeSource);
118
- }
119
- catch (err) {
120
- throw new Error(`Processing of page source file path=${relativeSource} failed.`, { cause: err });
121
- }
122
- }
123
- return (await Promise.all(pagesFiles.map(doProcessPageSourceFile))).filter(Boolean);
31
+ return (0, content_1.loadPagesContent)({ context, options, contentPaths });
124
32
  },
125
33
  async contentLoaded({ content, actions }) {
126
34
  if (!content) {
127
35
  return;
128
36
  }
129
- const { addRoute, createData } = actions;
130
- function createPageRouteMetadata(metadata) {
131
- const lastUpdatedAt = metadata.type === 'mdx' ? metadata.lastUpdatedAt : undefined;
132
- return {
133
- sourceFilePath: (0, utils_1.aliasedSitePathToRelativePath)(metadata.source),
134
- lastUpdatedAt,
135
- };
136
- }
137
- await Promise.all(content.map(async (metadata) => {
138
- const { permalink, source } = metadata;
139
- const routeMetadata = createPageRouteMetadata(metadata);
140
- if (metadata.type === 'mdx') {
141
- await createData(
142
- // Note that this created data path must be in sync with
143
- // metadataPath provided to mdx-loader.
144
- `${(0, utils_1.docuHash)(metadata.source)}.json`, JSON.stringify(metadata, null, 2));
145
- addRoute({
146
- path: permalink,
147
- component: options.mdxPageComponent,
148
- exact: true,
149
- metadata: routeMetadata,
150
- modules: {
151
- content: source,
152
- },
153
- });
154
- }
155
- else {
156
- addRoute({
157
- path: permalink,
158
- component: source,
159
- exact: true,
160
- metadata: routeMetadata,
161
- modules: {
162
- config: `@generated/docusaurus.config`,
163
- },
164
- });
165
- }
166
- }));
37
+ await (0, routes_1.createAllRoutes)({ content, options, actions });
167
38
  },
168
39
  configureWebpack() {
169
40
  const { admonitions, rehypePlugins, remarkPlugins, beforeDefaultRehypePlugins, beforeDefaultRemarkPlugins, } = options;
170
- const contentDirs = getContentPathList(contentPaths);
41
+ const contentDirs = (0, content_1.getContentPathList)(contentPaths);
171
42
  return {
172
- resolve: {
173
- alias: {
174
- '~pages': pluginDataDirRoot,
175
- },
176
- },
177
43
  module: {
178
44
  rules: [
179
45
  {
@@ -0,0 +1,16 @@
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 { PluginContentLoadedActions, RouteConfig } from '@docusaurus/types';
8
+ import type { PluginOptions, LoadedContent } from '@docusaurus/plugin-content-pages';
9
+ type CreateAllRoutesParam = {
10
+ content: LoadedContent;
11
+ options: PluginOptions;
12
+ actions: PluginContentLoadedActions;
13
+ };
14
+ export declare function createAllRoutes(param: CreateAllRoutesParam): Promise<void>;
15
+ export declare function buildAllRoutes({ content, actions, options, }: CreateAllRoutesParam): Promise<RouteConfig[]>;
16
+ export {};
package/lib/routes.js ADDED
@@ -0,0 +1,58 @@
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.buildAllRoutes = exports.createAllRoutes = void 0;
10
+ const utils_1 = require("@docusaurus/utils");
11
+ function createPageRouteMetadata(metadata) {
12
+ const lastUpdatedAt = metadata.type === 'mdx' ? metadata.lastUpdatedAt : undefined;
13
+ return {
14
+ sourceFilePath: (0, utils_1.aliasedSitePathToRelativePath)(metadata.source),
15
+ lastUpdatedAt,
16
+ };
17
+ }
18
+ async function createAllRoutes(param) {
19
+ const routes = await buildAllRoutes(param);
20
+ routes.forEach(param.actions.addRoute);
21
+ }
22
+ exports.createAllRoutes = createAllRoutes;
23
+ async function buildAllRoutes({ content, actions, options, }) {
24
+ const { createData } = actions;
25
+ async function buildMDXPageRoute(metadata) {
26
+ await createData(
27
+ // Note that this created data path must be in sync with
28
+ // metadataPath provided to mdx-loader.
29
+ `${(0, utils_1.docuHash)(metadata.source)}.json`, metadata);
30
+ return {
31
+ path: metadata.permalink,
32
+ component: options.mdxPageComponent,
33
+ exact: true,
34
+ metadata: createPageRouteMetadata(metadata),
35
+ modules: {
36
+ content: metadata.source,
37
+ },
38
+ };
39
+ }
40
+ async function buildJSXRoute(metadata) {
41
+ return {
42
+ path: metadata.permalink,
43
+ component: metadata.source,
44
+ exact: true,
45
+ metadata: createPageRouteMetadata(metadata),
46
+ modules: {
47
+ config: `@generated/docusaurus.config`,
48
+ },
49
+ };
50
+ }
51
+ async function buildPageRoute(metadata) {
52
+ return metadata.type === 'mdx'
53
+ ? buildMDXPageRoute(metadata)
54
+ : buildJSXRoute(metadata);
55
+ }
56
+ return Promise.all(content.map(buildPageRoute));
57
+ }
58
+ exports.buildAllRoutes = buildAllRoutes;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@docusaurus/plugin-content-pages",
3
- "version": "0.0.0-5899",
3
+ "version": "0.0.0-5900",
4
4
  "description": "Pages plugin for Docusaurus.",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/plugin-content-pages.d.ts",
@@ -18,11 +18,11 @@
18
18
  },
19
19
  "license": "MIT",
20
20
  "dependencies": {
21
- "@docusaurus/core": "0.0.0-5899",
22
- "@docusaurus/mdx-loader": "0.0.0-5899",
23
- "@docusaurus/types": "0.0.0-5899",
24
- "@docusaurus/utils": "0.0.0-5899",
25
- "@docusaurus/utils-validation": "0.0.0-5899",
21
+ "@docusaurus/core": "0.0.0-5900",
22
+ "@docusaurus/mdx-loader": "0.0.0-5900",
23
+ "@docusaurus/types": "0.0.0-5900",
24
+ "@docusaurus/utils": "0.0.0-5900",
25
+ "@docusaurus/utils-validation": "0.0.0-5900",
26
26
  "fs-extra": "^11.1.1",
27
27
  "tslib": "^2.6.0",
28
28
  "webpack": "^5.88.1"
@@ -34,5 +34,5 @@
34
34
  "engines": {
35
35
  "node": ">=18.0"
36
36
  },
37
- "gitHead": "e8e1f914293e8dade7f4e0907d9a00bd1df80470"
37
+ "gitHead": "8c799b8d6990ec2aea5708a732db09f4dd9e66cc"
38
38
  }
package/src/content.ts ADDED
@@ -0,0 +1,194 @@
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 fs from 'fs-extra';
9
+ import path from 'path';
10
+ import {
11
+ encodePath,
12
+ fileToPath,
13
+ aliasedSitePath,
14
+ getFolderContainingFile,
15
+ Globby,
16
+ normalizeUrl,
17
+ parseMarkdownFile,
18
+ isUnlisted,
19
+ isDraft,
20
+ readLastUpdateData,
21
+ getEditUrl,
22
+ posixPath,
23
+ getPluginI18nPath,
24
+ } from '@docusaurus/utils';
25
+ import {validatePageFrontMatter} from './frontMatter';
26
+ import type {LoadContext} from '@docusaurus/types';
27
+ import type {PagesContentPaths} from './types';
28
+ import type {
29
+ PluginOptions,
30
+ Metadata,
31
+ LoadedContent,
32
+ } from '@docusaurus/plugin-content-pages';
33
+
34
+ export function createPagesContentPaths({
35
+ context,
36
+ options,
37
+ }: {
38
+ context: LoadContext;
39
+ options: PluginOptions;
40
+ }): PagesContentPaths {
41
+ const {siteDir, localizationDir} = context;
42
+ return {
43
+ contentPath: path.resolve(siteDir, options.path),
44
+ contentPathLocalized: getPluginI18nPath({
45
+ localizationDir,
46
+ pluginName: 'docusaurus-plugin-content-pages',
47
+ pluginId: options.id,
48
+ }),
49
+ };
50
+ }
51
+
52
+ export function getContentPathList(contentPaths: PagesContentPaths): string[] {
53
+ return [contentPaths.contentPathLocalized, contentPaths.contentPath];
54
+ }
55
+
56
+ const isMarkdownSource = (source: string) =>
57
+ source.endsWith('.md') || source.endsWith('.mdx');
58
+
59
+ type LoadContentParams = {
60
+ context: LoadContext;
61
+ options: PluginOptions;
62
+ contentPaths: PagesContentPaths;
63
+ };
64
+
65
+ export async function loadPagesContent(
66
+ params: LoadContentParams,
67
+ ): Promise<LoadedContent> {
68
+ const {options} = params;
69
+
70
+ const pagesFiles = await Globby(params.options.include, {
71
+ cwd: params.contentPaths.contentPath,
72
+ ignore: options.exclude,
73
+ });
74
+
75
+ async function doProcessPageSourceFile(relativeSource: string) {
76
+ try {
77
+ return await processPageSourceFile(relativeSource, params);
78
+ } catch (err) {
79
+ throw new Error(
80
+ `Processing of page source file path=${relativeSource} failed.`,
81
+ {cause: err as Error},
82
+ );
83
+ }
84
+ }
85
+
86
+ return (await Promise.all(pagesFiles.map(doProcessPageSourceFile))).filter(
87
+ (res): res is Metadata => {
88
+ return res !== undefined;
89
+ },
90
+ );
91
+ }
92
+
93
+ async function processPageSourceFile(
94
+ relativeSource: string,
95
+ params: LoadContentParams,
96
+ ): Promise<Metadata | undefined> {
97
+ const {context, options, contentPaths} = params;
98
+ const {siteConfig, baseUrl, siteDir, i18n} = context;
99
+ const {editUrl} = options;
100
+
101
+ // Lookup in localized folder in priority
102
+ const contentPath = await getFolderContainingFile(
103
+ getContentPathList(contentPaths),
104
+ relativeSource,
105
+ );
106
+
107
+ const source = path.join(contentPath, relativeSource);
108
+ const aliasedSourcePath = aliasedSitePath(source, siteDir);
109
+ const permalink = normalizeUrl([
110
+ baseUrl,
111
+ options.routeBasePath,
112
+ encodePath(fileToPath(relativeSource)),
113
+ ]);
114
+ if (!isMarkdownSource(relativeSource)) {
115
+ return {
116
+ type: 'jsx',
117
+ permalink,
118
+ source: aliasedSourcePath,
119
+ };
120
+ }
121
+
122
+ const content = await fs.readFile(source, 'utf-8');
123
+ const {
124
+ frontMatter: unsafeFrontMatter,
125
+ contentTitle,
126
+ excerpt,
127
+ } = await parseMarkdownFile({
128
+ filePath: source,
129
+ fileContent: content,
130
+ parseFrontMatter: siteConfig.markdown.parseFrontMatter,
131
+ });
132
+ const frontMatter = validatePageFrontMatter(unsafeFrontMatter);
133
+
134
+ const pagesDirPath = await getFolderContainingFile(
135
+ getContentPathList(contentPaths),
136
+ relativeSource,
137
+ );
138
+
139
+ const pagesSourceAbsolute = path.join(pagesDirPath, relativeSource);
140
+
141
+ function getPagesEditUrl() {
142
+ const pagesPathRelative = path.relative(
143
+ pagesDirPath,
144
+ path.resolve(pagesSourceAbsolute),
145
+ );
146
+
147
+ if (typeof editUrl === 'function') {
148
+ return editUrl({
149
+ pagesDirPath: posixPath(path.relative(siteDir, pagesDirPath)),
150
+ pagesPath: posixPath(pagesPathRelative),
151
+ permalink,
152
+ locale: i18n.currentLocale,
153
+ });
154
+ } else if (typeof editUrl === 'string') {
155
+ const isLocalized = pagesDirPath === contentPaths.contentPathLocalized;
156
+ const fileContentPath =
157
+ isLocalized && options.editLocalizedFiles
158
+ ? contentPaths.contentPathLocalized
159
+ : contentPaths.contentPath;
160
+
161
+ const contentPathEditUrl = normalizeUrl([
162
+ editUrl,
163
+ posixPath(path.relative(siteDir, fileContentPath)),
164
+ ]);
165
+
166
+ return getEditUrl(pagesPathRelative, contentPathEditUrl);
167
+ }
168
+ return undefined;
169
+ }
170
+
171
+ const lastUpdatedData = await readLastUpdateData(
172
+ source,
173
+ options,
174
+ frontMatter.last_update,
175
+ );
176
+
177
+ if (isDraft({frontMatter})) {
178
+ return undefined;
179
+ }
180
+ const unlisted = isUnlisted({frontMatter});
181
+
182
+ return {
183
+ type: 'mdx',
184
+ permalink,
185
+ source: aliasedSourcePath,
186
+ title: frontMatter.title ?? contentTitle,
187
+ description: frontMatter.description ?? excerpt,
188
+ frontMatter,
189
+ lastUpdatedBy: lastUpdatedData.lastUpdatedBy,
190
+ lastUpdatedAt: lastUpdatedData.lastUpdatedAt,
191
+ editUrl: getPagesEditUrl(),
192
+ unlisted,
193
+ };
194
+ }
package/src/index.ts CHANGED
@@ -8,57 +8,32 @@
8
8
  import fs from 'fs-extra';
9
9
  import path from 'path';
10
10
  import {
11
- encodePath,
12
- fileToPath,
13
11
  aliasedSitePath,
14
- aliasedSitePathToRelativePath,
15
12
  docuHash,
16
- getPluginI18nPath,
17
- getFolderContainingFile,
18
13
  addTrailingPathSeparator,
19
- Globby,
20
14
  createAbsoluteFilePathMatcher,
21
- normalizeUrl,
22
15
  DEFAULT_PLUGIN_ID,
23
- parseMarkdownFile,
24
- isUnlisted,
25
- isDraft,
26
- readLastUpdateData,
27
- getEditUrl,
28
- posixPath,
29
16
  } from '@docusaurus/utils';
30
- import {validatePageFrontMatter} from './frontMatter';
31
- import type {LoadContext, Plugin, RouteMetadata} from '@docusaurus/types';
32
- import type {PagesContentPaths} from './types';
17
+ import {createAllRoutes} from './routes';
18
+ import {
19
+ createPagesContentPaths,
20
+ getContentPathList,
21
+ loadPagesContent,
22
+ } from './content';
23
+ import type {LoadContext, Plugin} from '@docusaurus/types';
33
24
  import type {
34
25
  PluginOptions,
35
- Metadata,
36
26
  LoadedContent,
37
27
  PageFrontMatter,
38
28
  } from '@docusaurus/plugin-content-pages';
39
29
 
40
- export function getContentPathList(contentPaths: PagesContentPaths): string[] {
41
- return [contentPaths.contentPathLocalized, contentPaths.contentPath];
42
- }
43
-
44
- const isMarkdownSource = (source: string) =>
45
- source.endsWith('.md') || source.endsWith('.mdx');
46
-
47
30
  export default function pluginContentPages(
48
31
  context: LoadContext,
49
32
  options: PluginOptions,
50
33
  ): Plugin<LoadedContent | null> {
51
- const {siteConfig, siteDir, generatedFilesDir, localizationDir, i18n} =
52
- context;
34
+ const {siteConfig, siteDir, generatedFilesDir} = context;
53
35
 
54
- const contentPaths: PagesContentPaths = {
55
- contentPath: path.resolve(siteDir, options.path),
56
- contentPathLocalized: getPluginI18nPath({
57
- localizationDir,
58
- pluginName: 'docusaurus-plugin-content-pages',
59
- pluginId: options.id,
60
- }),
61
- };
36
+ const contentPaths = createPagesContentPaths({context, options});
62
37
 
63
38
  const pluginDataDirRoot = path.join(
64
39
  generatedFilesDir,
@@ -77,182 +52,17 @@ export default function pluginContentPages(
77
52
  },
78
53
 
79
54
  async loadContent() {
80
- const {include, editUrl} = options;
81
-
82
55
  if (!(await fs.pathExists(contentPaths.contentPath))) {
83
56
  return null;
84
57
  }
85
-
86
- const {baseUrl} = siteConfig;
87
- const pagesFiles = await Globby(include, {
88
- cwd: contentPaths.contentPath,
89
- ignore: options.exclude,
90
- });
91
-
92
- async function processPageSourceFile(
93
- relativeSource: string,
94
- ): Promise<Metadata | undefined> {
95
- // Lookup in localized folder in priority
96
- const contentPath = await getFolderContainingFile(
97
- getContentPathList(contentPaths),
98
- relativeSource,
99
- );
100
-
101
- const source = path.join(contentPath, relativeSource);
102
- const aliasedSourcePath = aliasedSitePath(source, siteDir);
103
- const permalink = normalizeUrl([
104
- baseUrl,
105
- options.routeBasePath,
106
- encodePath(fileToPath(relativeSource)),
107
- ]);
108
- if (!isMarkdownSource(relativeSource)) {
109
- return {
110
- type: 'jsx',
111
- permalink,
112
- source: aliasedSourcePath,
113
- };
114
- }
115
- const content = await fs.readFile(source, 'utf-8');
116
- const {
117
- frontMatter: unsafeFrontMatter,
118
- contentTitle,
119
- excerpt,
120
- } = await parseMarkdownFile({
121
- filePath: source,
122
- fileContent: content,
123
- parseFrontMatter: siteConfig.markdown.parseFrontMatter,
124
- });
125
- const frontMatter = validatePageFrontMatter(unsafeFrontMatter);
126
-
127
- const pagesDirPath = await getFolderContainingFile(
128
- getContentPathList(contentPaths),
129
- relativeSource,
130
- );
131
-
132
- const pagesSourceAbsolute = path.join(pagesDirPath, relativeSource);
133
-
134
- function getPagesEditUrl() {
135
- const pagesPathRelative = path.relative(
136
- pagesDirPath,
137
- path.resolve(pagesSourceAbsolute),
138
- );
139
-
140
- if (typeof editUrl === 'function') {
141
- return editUrl({
142
- pagesDirPath: posixPath(path.relative(siteDir, pagesDirPath)),
143
- pagesPath: posixPath(pagesPathRelative),
144
- permalink,
145
- locale: i18n.currentLocale,
146
- });
147
- } else if (typeof editUrl === 'string') {
148
- const isLocalized =
149
- pagesDirPath === contentPaths.contentPathLocalized;
150
- const fileContentPath =
151
- isLocalized && options.editLocalizedFiles
152
- ? contentPaths.contentPathLocalized
153
- : contentPaths.contentPath;
154
-
155
- const contentPathEditUrl = normalizeUrl([
156
- editUrl,
157
- posixPath(path.relative(siteDir, fileContentPath)),
158
- ]);
159
-
160
- return getEditUrl(pagesPathRelative, contentPathEditUrl);
161
- }
162
- return undefined;
163
- }
164
-
165
- const lastUpdatedData = await readLastUpdateData(
166
- source,
167
- options,
168
- frontMatter.last_update,
169
- );
170
-
171
- if (isDraft({frontMatter})) {
172
- return undefined;
173
- }
174
- const unlisted = isUnlisted({frontMatter});
175
-
176
- return {
177
- type: 'mdx',
178
- permalink,
179
- source: aliasedSourcePath,
180
- title: frontMatter.title ?? contentTitle,
181
- description: frontMatter.description ?? excerpt,
182
- frontMatter,
183
- lastUpdatedBy: lastUpdatedData.lastUpdatedBy,
184
- lastUpdatedAt: lastUpdatedData.lastUpdatedAt,
185
- editUrl: getPagesEditUrl(),
186
- unlisted,
187
- };
188
- }
189
-
190
- async function doProcessPageSourceFile(relativeSource: string) {
191
- try {
192
- return await processPageSourceFile(relativeSource);
193
- } catch (err) {
194
- throw new Error(
195
- `Processing of page source file path=${relativeSource} failed.`,
196
- {cause: err as Error},
197
- );
198
- }
199
- }
200
-
201
- return (
202
- await Promise.all(pagesFiles.map(doProcessPageSourceFile))
203
- ).filter(Boolean) as Metadata[];
58
+ return loadPagesContent({context, options, contentPaths});
204
59
  },
205
60
 
206
61
  async contentLoaded({content, actions}) {
207
62
  if (!content) {
208
63
  return;
209
64
  }
210
-
211
- const {addRoute, createData} = actions;
212
-
213
- function createPageRouteMetadata(metadata: Metadata): RouteMetadata {
214
- const lastUpdatedAt =
215
- metadata.type === 'mdx' ? metadata.lastUpdatedAt : undefined;
216
-
217
- return {
218
- sourceFilePath: aliasedSitePathToRelativePath(metadata.source),
219
- lastUpdatedAt,
220
- };
221
- }
222
-
223
- await Promise.all(
224
- content.map(async (metadata) => {
225
- const {permalink, source} = metadata;
226
- const routeMetadata = createPageRouteMetadata(metadata);
227
- if (metadata.type === 'mdx') {
228
- await createData(
229
- // Note that this created data path must be in sync with
230
- // metadataPath provided to mdx-loader.
231
- `${docuHash(metadata.source)}.json`,
232
- JSON.stringify(metadata, null, 2),
233
- );
234
- addRoute({
235
- path: permalink,
236
- component: options.mdxPageComponent,
237
- exact: true,
238
- metadata: routeMetadata,
239
- modules: {
240
- content: source,
241
- },
242
- });
243
- } else {
244
- addRoute({
245
- path: permalink,
246
- component: source,
247
- exact: true,
248
- metadata: routeMetadata,
249
- modules: {
250
- config: `@generated/docusaurus.config`,
251
- },
252
- });
253
- }
254
- }),
255
- );
65
+ await createAllRoutes({content, options, actions});
256
66
  },
257
67
 
258
68
  configureWebpack() {
@@ -265,11 +75,6 @@ export default function pluginContentPages(
265
75
  } = options;
266
76
  const contentDirs = getContentPathList(contentPaths);
267
77
  return {
268
- resolve: {
269
- alias: {
270
- '~pages': pluginDataDirRoot,
271
- },
272
- },
273
78
  module: {
274
79
  rules: [
275
80
  {
package/src/routes.ts ADDED
@@ -0,0 +1,89 @@
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 {aliasedSitePathToRelativePath, docuHash} from '@docusaurus/utils';
9
+ import type {
10
+ PluginContentLoadedActions,
11
+ RouteConfig,
12
+ RouteMetadata,
13
+ } from '@docusaurus/types';
14
+ import type {
15
+ PluginOptions,
16
+ Metadata,
17
+ LoadedContent,
18
+ MDXPageMetadata,
19
+ } from '@docusaurus/plugin-content-pages';
20
+
21
+ type CreateAllRoutesParam = {
22
+ content: LoadedContent;
23
+ options: PluginOptions;
24
+ actions: PluginContentLoadedActions;
25
+ };
26
+
27
+ function createPageRouteMetadata(metadata: Metadata): RouteMetadata {
28
+ const lastUpdatedAt =
29
+ metadata.type === 'mdx' ? metadata.lastUpdatedAt : undefined;
30
+ return {
31
+ sourceFilePath: aliasedSitePathToRelativePath(metadata.source),
32
+ lastUpdatedAt,
33
+ };
34
+ }
35
+
36
+ export async function createAllRoutes(
37
+ param: CreateAllRoutesParam,
38
+ ): Promise<void> {
39
+ const routes = await buildAllRoutes(param);
40
+ routes.forEach(param.actions.addRoute);
41
+ }
42
+
43
+ export async function buildAllRoutes({
44
+ content,
45
+ actions,
46
+ options,
47
+ }: CreateAllRoutesParam): Promise<RouteConfig[]> {
48
+ const {createData} = actions;
49
+
50
+ async function buildMDXPageRoute(
51
+ metadata: MDXPageMetadata,
52
+ ): Promise<RouteConfig> {
53
+ await createData(
54
+ // Note that this created data path must be in sync with
55
+ // metadataPath provided to mdx-loader.
56
+ `${docuHash(metadata.source)}.json`,
57
+ metadata,
58
+ );
59
+ return {
60
+ path: metadata.permalink,
61
+ component: options.mdxPageComponent,
62
+ exact: true,
63
+ metadata: createPageRouteMetadata(metadata),
64
+ modules: {
65
+ content: metadata.source,
66
+ },
67
+ };
68
+ }
69
+
70
+ async function buildJSXRoute(metadata: Metadata): Promise<RouteConfig> {
71
+ return {
72
+ path: metadata.permalink,
73
+ component: metadata.source,
74
+ exact: true,
75
+ metadata: createPageRouteMetadata(metadata),
76
+ modules: {
77
+ config: `@generated/docusaurus.config`,
78
+ },
79
+ };
80
+ }
81
+
82
+ async function buildPageRoute(metadata: Metadata): Promise<RouteConfig> {
83
+ return metadata.type === 'mdx'
84
+ ? buildMDXPageRoute(metadata)
85
+ : buildJSXRoute(metadata);
86
+ }
87
+
88
+ return Promise.all(content.map(buildPageRoute));
89
+ }