@docusaurus/plugin-content-docs 2.0.0-beta.15d451942 → 2.0.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/categoryGeneratedIndex.d.ts +12 -0
- package/lib/categoryGeneratedIndex.js +35 -0
- package/lib/cli.d.ts +2 -2
- package/lib/cli.js +37 -51
- package/lib/client/docsClientUtils.d.ts +6 -26
- package/lib/client/docsClientUtils.js +28 -34
- package/lib/{theme/hooks/useDocs.d.ts → client/index.d.ts} +4 -3
- package/lib/{theme/hooks/useDocs.js → client/index.js} +28 -25
- package/lib/docs.d.ts +31 -4
- package/lib/docs.js +160 -54
- package/{src/__tests__/__fixtures__/simple-site/docusaurus.config.js → lib/frontMatter.d.ts} +4 -8
- package/lib/{docFrontMatter.js → frontMatter.js} +13 -6
- package/lib/globalData.d.ts +2 -2
- package/lib/globalData.js +32 -3
- package/lib/index.d.ts +4 -3
- package/lib/index.js +123 -136
- package/lib/lastUpdate.d.ts +4 -6
- package/lib/lastUpdate.js +22 -26
- package/lib/markdown/index.d.ts +3 -6
- package/lib/markdown/index.js +3 -3
- package/lib/markdown/linkify.d.ts +1 -1
- package/lib/markdown/linkify.js +7 -3
- package/lib/numberPrefix.d.ts +1 -1
- package/lib/numberPrefix.js +16 -21
- package/lib/options.d.ts +3 -5
- package/lib/options.js +55 -19
- package/lib/props.d.ts +7 -2
- package/lib/props.js +70 -14
- package/lib/routes.d.ts +28 -0
- package/lib/routes.js +110 -0
- package/lib/server-export.d.ts +8 -0
- package/lib/server-export.js +23 -0
- package/lib/{sidebarItemsGenerator.d.ts → sidebars/generator.d.ts} +1 -6
- package/lib/sidebars/generator.js +209 -0
- package/lib/sidebars/index.d.ts +13 -0
- package/lib/sidebars/index.js +94 -0
- package/lib/sidebars/normalization.d.ts +13 -0
- package/lib/sidebars/normalization.js +55 -0
- package/lib/sidebars/postProcessor.d.ts +8 -0
- package/lib/sidebars/postProcessor.js +65 -0
- package/lib/sidebars/processor.d.ts +10 -0
- package/lib/sidebars/processor.js +79 -0
- package/lib/sidebars/types.d.ts +174 -0
- package/{src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars2.js → lib/sidebars/types.js} +2 -10
- package/lib/sidebars/utils.d.ts +54 -0
- package/lib/sidebars/utils.js +255 -0
- package/lib/sidebars/validation.d.ts +11 -0
- package/lib/sidebars/validation.js +138 -0
- package/lib/slug.d.ts +6 -4
- package/lib/slug.js +29 -19
- package/{src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docusaurus.config.js → lib/tags.d.ts} +2 -8
- package/lib/tags.js +21 -0
- package/lib/translations.d.ts +2 -2
- package/lib/translations.js +89 -49
- package/lib/types.d.ts +60 -130
- package/lib/versions.d.ts +29 -4
- package/lib/versions.js +134 -97
- package/package.json +30 -26
- package/src/categoryGeneratedIndex.ts +55 -0
- package/src/cli.ts +47 -63
- package/src/client/docsClientUtils.ts +38 -73
- package/src/{theme/hooks/useDocs.ts → client/index.ts} +16 -11
- package/{types.d.ts → src/deps.d.ts} +1 -1
- package/src/docs.ts +212 -46
- package/src/{docFrontMatter.ts → frontMatter.ts} +21 -26
- package/src/globalData.ts +53 -3
- package/src/index.ts +168 -178
- package/src/lastUpdate.ts +26 -33
- package/src/markdown/index.ts +10 -16
- package/src/markdown/linkify.ts +6 -2
- package/src/numberPrefix.ts +19 -26
- package/src/options.ts +60 -32
- package/src/plugin-content-docs.d.ts +263 -40
- package/src/props.ts +105 -21
- package/src/routes.ts +185 -0
- package/src/server-export.ts +24 -0
- package/src/sidebars/README.md +9 -0
- package/src/sidebars/generator.ts +292 -0
- package/src/sidebars/index.ts +120 -0
- package/src/sidebars/normalization.ts +85 -0
- package/src/sidebars/postProcessor.ts +89 -0
- package/src/sidebars/processor.ts +120 -0
- package/src/sidebars/types.ts +274 -0
- package/src/sidebars/utils.ts +388 -0
- package/src/sidebars/validation.ts +174 -0
- package/src/slug.ts +40 -23
- package/src/tags.ts +19 -0
- package/src/translations.ts +124 -66
- package/src/types.ts +67 -187
- package/src/versions.ts +205 -110
- package/lib/.tsbuildinfo +0 -4717
- package/lib/docFrontMatter.d.ts +0 -21
- package/lib/sidebarItemsGenerator.js +0 -211
- package/lib/sidebars.d.ts +0 -42
- package/lib/sidebars.js +0 -309
- package/src/__tests__/__fixtures__/bad-id-site/docs/invalid-id.md +0 -5
- package/src/__tests__/__fixtures__/bad-slug-on-doc-home-site/docs/docWithSlug.md +0 -5
- package/src/__tests__/__fixtures__/empty-site/docusaurus.config.js +0 -16
- package/src/__tests__/__fixtures__/empty-site/sidebars.json +0 -1
- package/src/__tests__/__fixtures__/sidebars/sidebars-category-shorthand.js +0 -34
- package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-items.json +0 -11
- package/src/__tests__/__fixtures__/sidebars/sidebars-category-wrong-label.json +0 -11
- package/src/__tests__/__fixtures__/sidebars/sidebars-category.js +0 -44
- package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed-first-level.json +0 -20
- package/src/__tests__/__fixtures__/sidebars/sidebars-collapsed.json +0 -21
- package/src/__tests__/__fixtures__/sidebars/sidebars-doc-id-not-string.json +0 -10
- package/src/__tests__/__fixtures__/sidebars/sidebars-first-level-not-category.js +0 -20
- package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-href.json +0 -11
- package/src/__tests__/__fixtures__/sidebars/sidebars-link-wrong-label.json +0 -11
- package/src/__tests__/__fixtures__/sidebars/sidebars-link.json +0 -11
- package/src/__tests__/__fixtures__/sidebars/sidebars-unknown-type.json +0 -14
- package/src/__tests__/__fixtures__/sidebars/sidebars-wrong-field.json +0 -20
- package/src/__tests__/__fixtures__/sidebars/sidebars.json +0 -20
- package/src/__tests__/__fixtures__/simple-site/docs/foo/bar.md +0 -69
- package/src/__tests__/__fixtures__/simple-site/docs/foo/baz.md +0 -67
- package/src/__tests__/__fixtures__/simple-site/docs/headingAsTitle.md +0 -1
- package/src/__tests__/__fixtures__/simple-site/docs/hello.md +0 -52
- package/src/__tests__/__fixtures__/simple-site/docs/ipsum.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/lorem.md +0 -6
- package/src/__tests__/__fixtures__/simple-site/docs/rootAbsoluteSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/rootRelativeSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/rootResolvedSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/rootTryToEscapeSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/slugs/absoluteSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/slugs/relativeSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/slugs/resolvedSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/docs/slugs/tryToEscapeSlug.md +0 -5
- package/src/__tests__/__fixtures__/simple-site/sidebars.json +0 -23
- package/src/__tests__/__fixtures__/simple-site/wrong-sidebars.json +0 -7
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/0-getting-started.md +0 -3
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/1-installation.md +0 -3
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/00_api-overview.md +0 -3
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/0 --- Client API.md +0 -1
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/01_Core APIs/1 --- Server API.md +0 -1
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/0. Plugin API.md +0 -1
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/1. Theme API.md +0 -1
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/02_Extension APIs/_category_.yml +0 -1
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/03_api-end.md +0 -3
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/3-API/_category_.json +0 -3
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/0-guide2.5.md +0 -8
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/02-guide2.md +0 -7
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/_category_.json +0 -3
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/a-guide4.md +0 -7
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/b-guide5.md +0 -7
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/guide3.md +0 -8
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/docs/Guides/z-guide1.md +0 -8
- package/src/__tests__/__fixtures__/site-with-autogenerated-sidebar/partialAutogeneratedSidebars.js +0 -23
- package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-1.md +0 -7
- package/src/__tests__/__fixtures__/site-with-doc-label/docs/hello-2.md +0 -8
- package/src/__tests__/__fixtures__/site-with-doc-label/docusaurus.config.js +0 -14
- package/src/__tests__/__fixtures__/site-with-doc-label/sidebars.json +0 -14
- package/src/__tests__/__fixtures__/versioned-site/community/team.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/community_sidebars.json +0 -3
- package/src/__tests__/__fixtures__/versioned-site/community_versioned_docs/version-1.0.0/team.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/community_versioned_sidebars/version-1.0.0-sidebars.json +0 -3
- package/src/__tests__/__fixtures__/versioned-site/community_versions.json +0 -1
- package/src/__tests__/__fixtures__/versioned-site/docs/foo/bar.md +0 -4
- package/src/__tests__/__fixtures__/versioned-site/docs/hello.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/docs/slugs/absoluteSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/docs/slugs/relativeSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/docs/slugs/resolvedSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/docs/slugs/tryToEscapeSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/docusaurus.config.js +0 -18
- package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/sidebars.json +0 -10
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/bar.md +0 -4
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/foo/baz.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.0/hello.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/foo/bar.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-1.0.1/hello.md +0 -1
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootRelativeSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootResolvedSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/relativeSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.0-sidebars.json +0 -11
- package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-1.0.1-sidebars.json +0 -10
- package/src/__tests__/__fixtures__/versioned-site/versioned_sidebars/version-withSlugs-sidebars.json +0 -5
- package/src/__tests__/__fixtures__/versioned-site/versions.json +0 -5
- package/src/__tests__/__snapshots__/cli.test.ts.snap +0 -90
- package/src/__tests__/__snapshots__/index.test.ts.snap +0 -1907
- package/src/__tests__/__snapshots__/sidebars.test.ts.snap +0 -218
- package/src/__tests__/__snapshots__/translations.test.ts.snap +0 -487
- package/src/__tests__/cli.test.ts +0 -333
- package/src/__tests__/docFrontMatter.test.ts +0 -204
- package/src/__tests__/docs.test.ts +0 -875
- package/src/__tests__/index.test.ts +0 -1831
- package/src/__tests__/lastUpdate.test.ts +0 -68
- package/src/__tests__/numberPrefix.test.ts +0 -199
- package/src/__tests__/options.test.ts +0 -232
- package/src/__tests__/sidebarItemsGenerator.test.ts +0 -336
- package/src/__tests__/sidebars.test.ts +0 -638
- package/src/__tests__/slug.test.ts +0 -109
- package/src/__tests__/translations.test.ts +0 -159
- package/src/__tests__/versions.test.ts +0 -718
- package/src/client/__tests__/docsClientUtils.test.ts +0 -372
- package/src/markdown/__tests__/__fixtures__/docs/doc-localized.md +0 -1
- package/src/markdown/__tests__/__fixtures__/docs/doc1.md +0 -13
- package/src/markdown/__tests__/__fixtures__/docs/doc2.md +0 -12
- package/src/markdown/__tests__/__fixtures__/docs/doc4.md +0 -19
- package/src/markdown/__tests__/__fixtures__/docs/doc5.md +0 -6
- package/src/markdown/__tests__/__fixtures__/docs/subdir/doc3.md +0 -3
- package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/doc2.md +0 -7
- package/src/markdown/__tests__/__fixtures__/versioned_docs/version-1.0.0/subdir/doc1.md +0 -3
- package/src/markdown/__tests__/__snapshots__/linkify.test.ts.snap +0 -82
- package/src/markdown/__tests__/linkify.test.ts +0 -190
- package/src/sidebarItemsGenerator.ts +0 -307
- package/src/sidebars.ts +0 -489
- package/tsconfig.json +0 -9
|
@@ -1,190 +0,0 @@
|
|
|
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 {linkify} from '../linkify';
|
|
11
|
-
import {
|
|
12
|
-
DocsMarkdownOption,
|
|
13
|
-
SourceToPermalink,
|
|
14
|
-
VersionMetadata,
|
|
15
|
-
BrokenMarkdownLink,
|
|
16
|
-
} from '../../types';
|
|
17
|
-
import {VERSIONED_DOCS_DIR, CURRENT_VERSION_NAME} from '../../constants';
|
|
18
|
-
|
|
19
|
-
function createFakeVersion({
|
|
20
|
-
versionName,
|
|
21
|
-
contentPath,
|
|
22
|
-
contentPathLocalized,
|
|
23
|
-
}: {
|
|
24
|
-
versionName: string;
|
|
25
|
-
contentPath: string;
|
|
26
|
-
contentPathLocalized: string;
|
|
27
|
-
}): VersionMetadata {
|
|
28
|
-
return {
|
|
29
|
-
versionName,
|
|
30
|
-
versionLabel: 'Any',
|
|
31
|
-
versionPath: 'any',
|
|
32
|
-
contentPath,
|
|
33
|
-
contentPathLocalized,
|
|
34
|
-
sidebarFilePath: 'any',
|
|
35
|
-
routePriority: undefined,
|
|
36
|
-
isLast: false,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
const siteDir = path.join(__dirname, '__fixtures__');
|
|
41
|
-
|
|
42
|
-
const versionCurrent = createFakeVersion({
|
|
43
|
-
versionName: CURRENT_VERSION_NAME,
|
|
44
|
-
contentPath: path.join(siteDir, 'docs'),
|
|
45
|
-
contentPathLocalized: path.join(
|
|
46
|
-
siteDir,
|
|
47
|
-
'i18n',
|
|
48
|
-
'fr',
|
|
49
|
-
'docusaurus-plugin-content-docs',
|
|
50
|
-
CURRENT_VERSION_NAME,
|
|
51
|
-
),
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
const version100 = createFakeVersion({
|
|
55
|
-
versionName: '1.0.0',
|
|
56
|
-
contentPath: path.join(siteDir, VERSIONED_DOCS_DIR, 'version-1.0.0'),
|
|
57
|
-
contentPathLocalized: path.join(
|
|
58
|
-
siteDir,
|
|
59
|
-
'i18n',
|
|
60
|
-
'fr',
|
|
61
|
-
'docusaurus-plugin-content-docs',
|
|
62
|
-
'version-1.0.0',
|
|
63
|
-
),
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
const sourceToPermalink: SourceToPermalink = {
|
|
67
|
-
'@site/docs/doc1.md': '/docs/doc1',
|
|
68
|
-
'@site/docs/doc2.md': '/docs/doc2',
|
|
69
|
-
'@site/docs/subdir/doc3.md': '/docs/subdir/doc3',
|
|
70
|
-
'@site/docs/doc4.md': '/docs/doc4',
|
|
71
|
-
'@site/versioned_docs/version-1.0.0/doc2.md': '/docs/1.0.0/doc2',
|
|
72
|
-
'@site/versioned_docs/version-1.0.0/subdir/doc1.md':
|
|
73
|
-
'/docs/1.0.0/subdir/doc1',
|
|
74
|
-
|
|
75
|
-
'@site/i18n/fr/docusaurus-plugin-content-docs/current/doc-localized.md':
|
|
76
|
-
'/fr/doc-localized',
|
|
77
|
-
'@site/docs/doc-localized': '/doc-localized',
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
function createMarkdownOptions(
|
|
81
|
-
options?: Partial<DocsMarkdownOption>,
|
|
82
|
-
): DocsMarkdownOption {
|
|
83
|
-
return {
|
|
84
|
-
sourceToPermalink,
|
|
85
|
-
onBrokenMarkdownLink: () => {},
|
|
86
|
-
versionsMetadata: [versionCurrent, version100],
|
|
87
|
-
siteDir,
|
|
88
|
-
...options,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
const transform = (filepath: string, options?: Partial<DocsMarkdownOption>) => {
|
|
93
|
-
const markdownOptions = createMarkdownOptions(options);
|
|
94
|
-
const content = fs.readFileSync(filepath, 'utf-8');
|
|
95
|
-
const transformedContent = linkify(content, filepath, markdownOptions);
|
|
96
|
-
return [content, transformedContent];
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
test('transform nothing', () => {
|
|
100
|
-
const doc1 = path.join(versionCurrent.contentPath, 'doc1.md');
|
|
101
|
-
const [content, transformedContent] = transform(doc1);
|
|
102
|
-
expect(transformedContent).toMatchSnapshot();
|
|
103
|
-
expect(content).toEqual(transformedContent);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
test('transform to correct links', () => {
|
|
107
|
-
const doc2 = path.join(versionCurrent.contentPath, 'doc2.md');
|
|
108
|
-
const [content, transformedContent] = transform(doc2);
|
|
109
|
-
expect(transformedContent).toMatchSnapshot();
|
|
110
|
-
expect(transformedContent).toContain('](/docs/doc1');
|
|
111
|
-
expect(transformedContent).toContain('](/docs/doc2');
|
|
112
|
-
expect(transformedContent).toContain('](/docs/subdir/doc3');
|
|
113
|
-
expect(transformedContent).toContain('](/fr/doc-localized');
|
|
114
|
-
expect(transformedContent).not.toContain('](doc1.md)');
|
|
115
|
-
expect(transformedContent).not.toContain('](./doc2.md)');
|
|
116
|
-
expect(transformedContent).not.toContain('](subdir/doc3.md)');
|
|
117
|
-
expect(transformedContent).not.toContain('](/doc-localized');
|
|
118
|
-
expect(content).not.toEqual(transformedContent);
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
test('transform relative links', () => {
|
|
122
|
-
const doc3 = path.join(versionCurrent.contentPath, 'subdir', 'doc3.md');
|
|
123
|
-
|
|
124
|
-
const [content, transformedContent] = transform(doc3);
|
|
125
|
-
expect(transformedContent).toMatchSnapshot();
|
|
126
|
-
expect(transformedContent).toContain('](/docs/doc2');
|
|
127
|
-
expect(transformedContent).not.toContain('](../doc2.md)');
|
|
128
|
-
expect(content).not.toEqual(transformedContent);
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test('transforms reference links', () => {
|
|
132
|
-
const doc4 = path.join(versionCurrent.contentPath, 'doc4.md');
|
|
133
|
-
const [content, transformedContent] = transform(doc4);
|
|
134
|
-
expect(transformedContent).toMatchSnapshot();
|
|
135
|
-
expect(transformedContent).toContain('[doc1]: /docs/doc1');
|
|
136
|
-
expect(transformedContent).toContain('[doc2]: /docs/doc2');
|
|
137
|
-
expect(transformedContent).not.toContain('[doc1]: doc1.md');
|
|
138
|
-
expect(transformedContent).not.toContain('[doc2]: ./doc2.md');
|
|
139
|
-
expect(content).not.toEqual(transformedContent);
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
test('report broken markdown links', () => {
|
|
143
|
-
const doc5 = path.join(versionCurrent.contentPath, 'doc5.md');
|
|
144
|
-
const onBrokenMarkdownLink = jest.fn();
|
|
145
|
-
const [content, transformedContent] = transform(doc5, {
|
|
146
|
-
onBrokenMarkdownLink,
|
|
147
|
-
});
|
|
148
|
-
expect(transformedContent).toEqual(content);
|
|
149
|
-
expect(onBrokenMarkdownLink).toHaveBeenCalledTimes(4);
|
|
150
|
-
expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(1, {
|
|
151
|
-
filePath: doc5,
|
|
152
|
-
link: 'docNotExist1.md',
|
|
153
|
-
contentPaths: versionCurrent,
|
|
154
|
-
} as BrokenMarkdownLink);
|
|
155
|
-
expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(2, {
|
|
156
|
-
filePath: doc5,
|
|
157
|
-
link: './docNotExist2.mdx',
|
|
158
|
-
contentPaths: versionCurrent,
|
|
159
|
-
} as BrokenMarkdownLink);
|
|
160
|
-
expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(3, {
|
|
161
|
-
filePath: doc5,
|
|
162
|
-
link: '../docNotExist3.mdx',
|
|
163
|
-
contentPaths: versionCurrent,
|
|
164
|
-
} as BrokenMarkdownLink);
|
|
165
|
-
expect(onBrokenMarkdownLink).toHaveBeenNthCalledWith(4, {
|
|
166
|
-
filePath: doc5,
|
|
167
|
-
link: './subdir/docNotExist4.md',
|
|
168
|
-
contentPaths: versionCurrent,
|
|
169
|
-
} as BrokenMarkdownLink);
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
test('transforms absolute links in versioned docs', () => {
|
|
173
|
-
const doc2 = path.join(version100.contentPath, 'doc2.md');
|
|
174
|
-
const [content, transformedContent] = transform(doc2);
|
|
175
|
-
expect(transformedContent).toMatchSnapshot();
|
|
176
|
-
expect(transformedContent).toContain('](/docs/1.0.0/subdir/doc1');
|
|
177
|
-
expect(transformedContent).toContain('](/docs/1.0.0/doc2#existing-docs');
|
|
178
|
-
expect(transformedContent).not.toContain('](subdir/doc1.md)');
|
|
179
|
-
expect(transformedContent).not.toContain('](doc2.md#existing-docs)');
|
|
180
|
-
expect(content).not.toEqual(transformedContent);
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
test('transforms relative links in versioned docs', () => {
|
|
184
|
-
const doc1 = path.join(version100.contentPath, 'subdir', 'doc1.md');
|
|
185
|
-
const [content, transformedContent] = transform(doc1);
|
|
186
|
-
expect(transformedContent).toMatchSnapshot();
|
|
187
|
-
expect(transformedContent).toContain('](/docs/1.0.0/doc2');
|
|
188
|
-
expect(transformedContent).not.toContain('](../doc2.md)');
|
|
189
|
-
expect(content).not.toEqual(transformedContent);
|
|
190
|
-
});
|
|
@@ -1,307 +0,0 @@
|
|
|
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
|
-
SidebarItem,
|
|
10
|
-
SidebarItemDoc,
|
|
11
|
-
SidebarItemCategory,
|
|
12
|
-
SidebarItemsGenerator,
|
|
13
|
-
SidebarItemsGeneratorDoc,
|
|
14
|
-
} from './types';
|
|
15
|
-
import {sortBy, take, last, orderBy} from 'lodash';
|
|
16
|
-
import {addTrailingSlash, posixPath} from '@docusaurus/utils';
|
|
17
|
-
import {Joi} from '@docusaurus/utils-validation';
|
|
18
|
-
import chalk from 'chalk';
|
|
19
|
-
import path from 'path';
|
|
20
|
-
import fs from 'fs-extra';
|
|
21
|
-
import Yaml from 'js-yaml';
|
|
22
|
-
import {DefaultCategoryCollapsedValue} from './sidebars';
|
|
23
|
-
|
|
24
|
-
const BreadcrumbSeparator = '/';
|
|
25
|
-
|
|
26
|
-
export const CategoryMetadataFilenameBase = '_category_';
|
|
27
|
-
export const CategoryMetadataFilenamePattern = '_category_.{json,yml,yaml}';
|
|
28
|
-
|
|
29
|
-
export type CategoryMetadatasFile = {
|
|
30
|
-
label?: string;
|
|
31
|
-
position?: number;
|
|
32
|
-
collapsed?: boolean;
|
|
33
|
-
|
|
34
|
-
// TODO should we allow "items" here? how would this work? would an "autogenerated" type be allowed?
|
|
35
|
-
// This mkdocs plugin do something like that: https://github.com/lukasgeiter/mkdocs-awesome-pages-plugin/
|
|
36
|
-
// cf comment: https://github.com/facebook/docusaurus/issues/3464#issuecomment-784765199
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
type WithPosition = {position?: number};
|
|
40
|
-
type SidebarItemWithPosition = SidebarItem & WithPosition;
|
|
41
|
-
|
|
42
|
-
const CategoryMetadatasFileSchema = Joi.object<CategoryMetadatasFile>({
|
|
43
|
-
label: Joi.string(),
|
|
44
|
-
position: Joi.number(),
|
|
45
|
-
collapsed: Joi.boolean(),
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
// TODO I now believe we should read all the category metadata files ahead of time: we may need this metadata to customize docs metadata
|
|
49
|
-
// Example use-case being able to disable number prefix parsing at the folder level, or customize the default route path segment for an intermediate directory...
|
|
50
|
-
// TODO later if there is `CategoryFolder/index.md`, we may want to read the metadata as yaml on it
|
|
51
|
-
// see https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
|
52
|
-
async function readCategoryMetadatasFile(
|
|
53
|
-
categoryDirPath: string,
|
|
54
|
-
): Promise<CategoryMetadatasFile | null> {
|
|
55
|
-
function validateCategoryMetadataFile(
|
|
56
|
-
content: unknown,
|
|
57
|
-
): CategoryMetadatasFile {
|
|
58
|
-
return Joi.attempt(content, CategoryMetadatasFileSchema);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async function tryReadFile(
|
|
62
|
-
fileNameWithExtension: string,
|
|
63
|
-
parse: (content: string) => unknown,
|
|
64
|
-
): Promise<CategoryMetadatasFile | null> {
|
|
65
|
-
// Simpler to use only posix paths for mocking file metadatas in tests
|
|
66
|
-
const filePath = posixPath(
|
|
67
|
-
path.join(categoryDirPath, fileNameWithExtension),
|
|
68
|
-
);
|
|
69
|
-
if (await fs.pathExists(filePath)) {
|
|
70
|
-
const contentString = await fs.readFile(filePath, {encoding: 'utf8'});
|
|
71
|
-
const unsafeContent: unknown = parse(contentString);
|
|
72
|
-
try {
|
|
73
|
-
return validateCategoryMetadataFile(unsafeContent);
|
|
74
|
-
} catch (e) {
|
|
75
|
-
console.error(
|
|
76
|
-
chalk.red(
|
|
77
|
-
`The docs sidebar category metadata file looks invalid!\nPath=${filePath}`,
|
|
78
|
-
),
|
|
79
|
-
);
|
|
80
|
-
throw e;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return (
|
|
87
|
-
(await tryReadFile(`${CategoryMetadataFilenameBase}.json`, JSON.parse)) ??
|
|
88
|
-
(await tryReadFile(`${CategoryMetadataFilenameBase}.yml`, Yaml.load)) ??
|
|
89
|
-
// eslint-disable-next-line no-return-await
|
|
90
|
-
(await tryReadFile(`${CategoryMetadataFilenameBase}.yaml`, Yaml.load))
|
|
91
|
-
);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// [...parents, tail]
|
|
95
|
-
function parseBreadcrumb(
|
|
96
|
-
breadcrumb: string[],
|
|
97
|
-
): {parents: string[]; tail: string} {
|
|
98
|
-
return {
|
|
99
|
-
parents: take(breadcrumb, breadcrumb.length - 1),
|
|
100
|
-
tail: last(breadcrumb)!,
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
// Comment for this feature: https://github.com/facebook/docusaurus/issues/3464#issuecomment-818670449
|
|
105
|
-
export const DefaultSidebarItemsGenerator: SidebarItemsGenerator = async function defaultSidebarItemsGenerator({
|
|
106
|
-
item,
|
|
107
|
-
docs: allDocs,
|
|
108
|
-
version,
|
|
109
|
-
numberPrefixParser,
|
|
110
|
-
}): Promise<SidebarItem[]> {
|
|
111
|
-
// Doc at the root of the autogenerated sidebar dir
|
|
112
|
-
function isRootDoc(doc: SidebarItemsGeneratorDoc) {
|
|
113
|
-
return doc.sourceDirName === item.dirName;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// Doc inside a subfolder of the autogenerated sidebar dir
|
|
117
|
-
function isCategoryDoc(doc: SidebarItemsGeneratorDoc) {
|
|
118
|
-
if (isRootDoc(doc)) {
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return (
|
|
123
|
-
// autogen dir is . and doc is in subfolder
|
|
124
|
-
item.dirName === '.' ||
|
|
125
|
-
// autogen dir is not . and doc is in subfolder
|
|
126
|
-
// "api/myDoc" startsWith "api/" (note "api2/myDoc" is not included)
|
|
127
|
-
doc.sourceDirName.startsWith(addTrailingSlash(item.dirName))
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
function isInAutogeneratedDir(doc: SidebarItemsGeneratorDoc) {
|
|
132
|
-
return isRootDoc(doc) || isCategoryDoc(doc);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
// autogenDir=a/b and docDir=a/b/c/d => returns c/d
|
|
136
|
-
// autogenDir=a/b and docDir=a/b => returns .
|
|
137
|
-
function getDocDirRelativeToAutogenDir(
|
|
138
|
-
doc: SidebarItemsGeneratorDoc,
|
|
139
|
-
): string {
|
|
140
|
-
if (!isInAutogeneratedDir(doc)) {
|
|
141
|
-
throw new Error(
|
|
142
|
-
'getDocDirRelativeToAutogenDir() can only be called for subdocs of the sidebar autogen dir',
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
// Is there a node API to compare 2 relative paths more easily?
|
|
146
|
-
// path.relative() does not give good results
|
|
147
|
-
if (item.dirName === '.') {
|
|
148
|
-
return doc.sourceDirName;
|
|
149
|
-
} else if (item.dirName === doc.sourceDirName) {
|
|
150
|
-
return '.';
|
|
151
|
-
} else {
|
|
152
|
-
return doc.sourceDirName.replace(addTrailingSlash(item.dirName), '');
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// Get only docs in the autogen dir
|
|
157
|
-
// Sort by folder+filename at once
|
|
158
|
-
const docs = sortBy(allDocs.filter(isInAutogeneratedDir), (d) => d.source);
|
|
159
|
-
|
|
160
|
-
if (docs.length === 0) {
|
|
161
|
-
console.warn(
|
|
162
|
-
chalk.yellow(
|
|
163
|
-
`No docs found in dir ${item.dirName}: can't auto-generate a sidebar`,
|
|
164
|
-
),
|
|
165
|
-
);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
function createDocSidebarItem(
|
|
169
|
-
doc: SidebarItemsGeneratorDoc,
|
|
170
|
-
): SidebarItemDoc & WithPosition {
|
|
171
|
-
return {
|
|
172
|
-
type: 'doc',
|
|
173
|
-
id: doc.id,
|
|
174
|
-
...(doc.frontMatter.sidebar_label && {
|
|
175
|
-
label: doc.frontMatter.sidebar_label,
|
|
176
|
-
}),
|
|
177
|
-
...(typeof doc.sidebarPosition !== 'undefined' && {
|
|
178
|
-
position: doc.sidebarPosition,
|
|
179
|
-
}),
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async function createCategorySidebarItem({
|
|
184
|
-
breadcrumb,
|
|
185
|
-
}: {
|
|
186
|
-
breadcrumb: string[];
|
|
187
|
-
}): Promise<SidebarItemCategory & WithPosition> {
|
|
188
|
-
const categoryDirPath = path.join(
|
|
189
|
-
version.contentPath,
|
|
190
|
-
item.dirName, // fix https://github.com/facebook/docusaurus/issues/4638
|
|
191
|
-
breadcrumb.join(BreadcrumbSeparator),
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
const categoryMetadatas = await readCategoryMetadatasFile(categoryDirPath);
|
|
195
|
-
|
|
196
|
-
const {tail} = parseBreadcrumb(breadcrumb);
|
|
197
|
-
|
|
198
|
-
const {filename, numberPrefix} = numberPrefixParser(tail);
|
|
199
|
-
|
|
200
|
-
const position = categoryMetadatas?.position ?? numberPrefix;
|
|
201
|
-
|
|
202
|
-
return {
|
|
203
|
-
type: 'category',
|
|
204
|
-
label: categoryMetadatas?.label ?? filename,
|
|
205
|
-
items: [],
|
|
206
|
-
collapsed: categoryMetadatas?.collapsed ?? DefaultCategoryCollapsedValue,
|
|
207
|
-
...(typeof position !== 'undefined' && {position}),
|
|
208
|
-
};
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Not sure how to simplify this algorithm :/
|
|
212
|
-
async function autogenerateSidebarItems(): Promise<
|
|
213
|
-
SidebarItemWithPosition[]
|
|
214
|
-
> {
|
|
215
|
-
const sidebarItems: SidebarItem[] = []; // mutable result
|
|
216
|
-
|
|
217
|
-
const categoriesByBreadcrumb: Record<string, SidebarItemCategory> = {}; // mutable cache of categories already created
|
|
218
|
-
|
|
219
|
-
async function getOrCreateCategoriesForBreadcrumb(
|
|
220
|
-
breadcrumb: string[],
|
|
221
|
-
): Promise<SidebarItemCategory | null> {
|
|
222
|
-
if (breadcrumb.length === 0) {
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
const {parents} = parseBreadcrumb(breadcrumb);
|
|
226
|
-
const parentCategory = await getOrCreateCategoriesForBreadcrumb(parents);
|
|
227
|
-
const existingCategory =
|
|
228
|
-
categoriesByBreadcrumb[breadcrumb.join(BreadcrumbSeparator)];
|
|
229
|
-
|
|
230
|
-
if (existingCategory) {
|
|
231
|
-
return existingCategory;
|
|
232
|
-
} else {
|
|
233
|
-
const newCategory = await createCategorySidebarItem({
|
|
234
|
-
breadcrumb,
|
|
235
|
-
});
|
|
236
|
-
if (parentCategory) {
|
|
237
|
-
parentCategory.items.push(newCategory);
|
|
238
|
-
} else {
|
|
239
|
-
sidebarItems.push(newCategory);
|
|
240
|
-
}
|
|
241
|
-
categoriesByBreadcrumb[
|
|
242
|
-
breadcrumb.join(BreadcrumbSeparator)
|
|
243
|
-
] = newCategory;
|
|
244
|
-
return newCategory;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// Get the category breadcrumb of a doc (relative to the dir of the autogenerated sidebar item)
|
|
249
|
-
function getRelativeBreadcrumb(doc: SidebarItemsGeneratorDoc): string[] {
|
|
250
|
-
const relativeDirPath = getDocDirRelativeToAutogenDir(doc);
|
|
251
|
-
if (relativeDirPath === '.') {
|
|
252
|
-
return [];
|
|
253
|
-
} else {
|
|
254
|
-
return relativeDirPath.split(BreadcrumbSeparator);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
async function handleDocItem(doc: SidebarItemsGeneratorDoc): Promise<void> {
|
|
259
|
-
const breadcrumb = getRelativeBreadcrumb(doc);
|
|
260
|
-
const category = await getOrCreateCategoriesForBreadcrumb(breadcrumb);
|
|
261
|
-
|
|
262
|
-
const docSidebarItem = createDocSidebarItem(doc);
|
|
263
|
-
if (category) {
|
|
264
|
-
category.items.push(docSidebarItem);
|
|
265
|
-
} else {
|
|
266
|
-
sidebarItems.push(docSidebarItem);
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
// async process made sequential on purpose! order matters
|
|
271
|
-
for (const doc of docs) {
|
|
272
|
-
// eslint-disable-next-line no-await-in-loop
|
|
273
|
-
await handleDocItem(doc);
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
return sidebarItems;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const sidebarItems = await autogenerateSidebarItems();
|
|
280
|
-
|
|
281
|
-
return sortSidebarItems(sidebarItems);
|
|
282
|
-
};
|
|
283
|
-
|
|
284
|
-
// Recursively sort the categories/docs + remove the "position" attribute from final output
|
|
285
|
-
// Note: the "position" is only used to sort "inside" a sidebar slice
|
|
286
|
-
// It is not used to sort across multiple consecutive sidebar slices (ie a whole Category composed of multiple autogenerated items)
|
|
287
|
-
function sortSidebarItems(
|
|
288
|
-
sidebarItems: SidebarItemWithPosition[],
|
|
289
|
-
): SidebarItem[] {
|
|
290
|
-
const processedSidebarItems = sidebarItems.map((item) => {
|
|
291
|
-
if (item.type === 'category') {
|
|
292
|
-
return {
|
|
293
|
-
...item,
|
|
294
|
-
items: sortSidebarItems(item.items),
|
|
295
|
-
};
|
|
296
|
-
}
|
|
297
|
-
return item;
|
|
298
|
-
});
|
|
299
|
-
|
|
300
|
-
const sortedSidebarItems = orderBy(
|
|
301
|
-
processedSidebarItems,
|
|
302
|
-
(item) => item.position,
|
|
303
|
-
['asc'],
|
|
304
|
-
);
|
|
305
|
-
|
|
306
|
-
return sortedSidebarItems.map(({position: _removed, ...item}) => item);
|
|
307
|
-
}
|