@docusaurus/utils 2.0.0-beta.119c6d143 → 2.0.0-beta.12

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 (57) hide show
  1. package/lib/.tsbuildinfo +1 -1
  2. package/lib/constants.d.ts +19 -0
  3. package/lib/constants.js +26 -0
  4. package/lib/globUtils.d.ts +11 -0
  5. package/lib/globUtils.js +47 -0
  6. package/lib/{docuHash.d.ts → hashUtils.d.ts} +2 -0
  7. package/lib/{docuHash.js → hashUtils.js} +15 -5
  8. package/lib/index.d.ts +11 -9
  9. package/lib/index.js +44 -98
  10. package/lib/markdownLinks.js +19 -6
  11. package/lib/markdownParser.js +20 -12
  12. package/lib/mdxUtils.d.ts +16 -0
  13. package/lib/mdxUtils.js +30 -0
  14. package/lib/{getFilePathForRoutePath.d.ts → normalizeUrl.d.ts} +1 -1
  15. package/lib/normalizeUrl.js +66 -0
  16. package/lib/pathUtils.d.ts +0 -1
  17. package/lib/pathUtils.js +4 -11
  18. package/lib/slugger.d.ts +13 -0
  19. package/lib/slugger.js +18 -0
  20. package/lib/tags.d.ts +18 -0
  21. package/lib/tags.js +72 -0
  22. package/lib/webpackUtils.d.ts +29 -0
  23. package/lib/webpackUtils.js +109 -0
  24. package/package.json +23 -7
  25. package/src/__tests__/globUtils.test.ts +109 -0
  26. package/src/__tests__/{docuHash.test.ts → hashUtils.test.ts} +22 -1
  27. package/src/__tests__/index.test.ts +6 -110
  28. package/src/__tests__/markdownParser.test.ts +15 -2
  29. package/src/__tests__/mdxUtils.test.ts +133 -0
  30. package/src/__tests__/normalizeUrl.test.ts +117 -0
  31. package/src/__tests__/pathUtils.test.ts +5 -22
  32. package/src/__tests__/slugger.test.ts +27 -0
  33. package/src/__tests__/tags.test.ts +183 -0
  34. package/src/__tests__/webpackUtils.test.ts +33 -0
  35. package/src/constants.ts +38 -0
  36. package/src/deps.d.ts +14 -0
  37. package/src/globUtils.ts +63 -0
  38. package/src/{docuHash.ts → hashUtils.ts} +10 -1
  39. package/src/index.ts +23 -96
  40. package/src/markdownLinks.ts +19 -8
  41. package/src/markdownParser.ts +24 -17
  42. package/src/mdxUtils.ts +32 -0
  43. package/src/normalizeUrl.ts +80 -0
  44. package/src/pathUtils.ts +2 -9
  45. package/src/slugger.ts +24 -0
  46. package/src/tags.ts +100 -0
  47. package/src/webpackUtils.ts +144 -0
  48. package/lib/codeTranslationsUtils.d.ts +0 -11
  49. package/lib/codeTranslationsUtils.js +0 -50
  50. package/lib/getFilePathForRoutePath.js +0 -40
  51. package/src/__tests__/__fixtures__/defaultCodeTranslations/en.json +0 -4
  52. package/src/__tests__/__fixtures__/defaultCodeTranslations/fr-FR.json +0 -5
  53. package/src/__tests__/__fixtures__/defaultCodeTranslations/fr.json +0 -4
  54. package/src/__tests__/codeTranslationsUtils.test.ts +0 -112
  55. package/src/__tests__/getFilePathForRoutePath.test.ts +0 -87
  56. package/src/codeTranslationsUtils.ts +0 -56
  57. package/src/getFilePathForRoutePath.ts +0 -43
@@ -0,0 +1,133 @@
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 {mdxToHtml} from '../mdxUtils';
9
+
10
+ describe('mdxToHtml', () => {
11
+ test('work with simple markdown', () => {
12
+ const mdxString = `
13
+ # title
14
+
15
+ title text **bold**
16
+
17
+ ## subtitle
18
+
19
+ subtitle text *italic*
20
+
21
+ > Quote
22
+
23
+ `;
24
+
25
+ expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
26
+ `"<h1>title</h1><p>title text <strong>bold</strong></p><h2>subtitle</h2><p>subtitle text <em>italic</em></p><blockquote><p>Quote</p></blockquote>"`,
27
+ );
28
+ });
29
+
30
+ test('work with MDX imports', () => {
31
+ const mdxString = `
32
+ # title
33
+
34
+ import Tabs from '@theme/Tabs';
35
+ import TabItem from '@theme/TabItem';
36
+
37
+ text
38
+
39
+ `;
40
+
41
+ expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
42
+ `"<h1>title</h1><p>text</p>"`,
43
+ );
44
+ });
45
+
46
+ test('work with MDX exports', () => {
47
+ const mdxString = `
48
+ # title
49
+
50
+ export const someExport = 42
51
+
52
+ export const MyLocalComponent = () => "result"
53
+
54
+ export const toc = [
55
+ {id: "title",label: "title"}
56
+ ]
57
+
58
+ text
59
+
60
+
61
+ `;
62
+
63
+ expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
64
+ `"<h1>title</h1><p>text</p>"`,
65
+ );
66
+ });
67
+
68
+ test('work with MDX Tabs', () => {
69
+ const mdxString = `
70
+ # title
71
+
72
+ import Tabs from '@theme/Tabs';
73
+ import TabItem from '@theme/TabItem';
74
+
75
+ <Tabs>
76
+ <TabItem value="apple" label="Apple">
77
+ This is an apple 🍎
78
+ </TabItem>
79
+ <TabItem value="orange" label="Orange">
80
+ This is an orange 🍊
81
+ </TabItem>
82
+ </Tabs>
83
+
84
+ text
85
+
86
+
87
+ `;
88
+
89
+ // TODO this is not an ideal behavior!
90
+ // There is a warning "Component TabItem was not imported, exported, or provided by MDXProvider as global scope"
91
+ // Theme + MDX config should provide a list of React components to put in MDX scope
92
+ expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(
93
+ `"<h1>title</h1><div><div value=\\"apple\\" label=\\"Apple\\">This is an apple 🍎</div><div value=\\"orange\\" label=\\"Orange\\">This is an orange 🍊</div></div><p>text</p>"`,
94
+ );
95
+ });
96
+
97
+ test('work with MDX Tabs with ```mdx-code-block', () => {
98
+ const mdxString = `
99
+ # title
100
+
101
+ import Tabs from '@theme/Tabs';
102
+ import TabItem from '@theme/TabItem';
103
+
104
+ \`\`\`mdx-code-block
105
+ <Tabs>
106
+ <TabItem value="apple" label="Apple">
107
+ This is an apple 🍎
108
+ </TabItem>
109
+ <TabItem value="orange" label="Orange">
110
+ This is an orange 🍊
111
+ </TabItem>
112
+ </Tabs>
113
+ \`\`\`
114
+
115
+ text
116
+
117
+ `;
118
+
119
+ // TODO bad behavior!
120
+ // ```mdx-code-block should be unwrapped and inner MDX content should be evaluated
121
+ expect(mdxToHtml(mdxString)).toMatchInlineSnapshot(`
122
+ "<h1>title</h1><pre><code class=\\"language-mdx-code-block\\">&lt;Tabs&gt;
123
+ &lt;TabItem value=&quot;apple&quot; label=&quot;Apple&quot;&gt;
124
+ This is an apple 🍎
125
+ &lt;/TabItem&gt;
126
+ &lt;TabItem value=&quot;orange&quot; label=&quot;Orange&quot;&gt;
127
+ This is an orange 🍊
128
+ &lt;/TabItem&gt;
129
+ &lt;/Tabs&gt;
130
+ </code></pre><p>text</p>"
131
+ `);
132
+ });
133
+ });
@@ -0,0 +1,117 @@
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 {normalizeUrl} from '../normalizeUrl';
9
+
10
+ describe('normalizeUrl', () => {
11
+ test('should normalize urls correctly', () => {
12
+ const asserts = [
13
+ {
14
+ input: ['/', ''],
15
+ output: '/',
16
+ },
17
+ {
18
+ input: ['', '/'],
19
+ output: '/',
20
+ },
21
+ {
22
+ input: ['/'],
23
+ output: '/',
24
+ },
25
+ {
26
+ input: [''],
27
+ output: '',
28
+ },
29
+ {
30
+ input: ['/', '/'],
31
+ output: '/',
32
+ },
33
+ {
34
+ input: ['/', 'docs'],
35
+ output: '/docs',
36
+ },
37
+ {
38
+ input: ['/', 'docs', 'en', 'next', 'blog'],
39
+ output: '/docs/en/next/blog',
40
+ },
41
+ {
42
+ input: ['/test/', '/docs', 'ro', 'doc1'],
43
+ output: '/test/docs/ro/doc1',
44
+ },
45
+ {
46
+ input: ['/test/', '/', 'ro', 'doc1'],
47
+ output: '/test/ro/doc1',
48
+ },
49
+ {
50
+ input: ['/', '/', '2020/02/29/leap-day'],
51
+ output: '/2020/02/29/leap-day',
52
+ },
53
+ {
54
+ input: ['', '/', 'ko', 'hello'],
55
+ output: '/ko/hello',
56
+ },
57
+ {
58
+ input: ['hello', 'world'],
59
+ output: 'hello/world',
60
+ },
61
+ {
62
+ input: ['http://www.google.com/', 'foo/bar', '?test=123'],
63
+ output: 'http://www.google.com/foo/bar?test=123',
64
+ },
65
+ {
66
+ input: ['http:', 'www.google.com///', 'foo/bar', '?test=123'],
67
+ output: 'http://www.google.com/foo/bar?test=123',
68
+ },
69
+ {
70
+ input: ['http://foobar.com', '', 'test'],
71
+ output: 'http://foobar.com/test',
72
+ },
73
+ {
74
+ input: ['http://foobar.com', '', 'test', '/'],
75
+ output: 'http://foobar.com/test/',
76
+ },
77
+ {
78
+ input: ['/', '', 'hello', '', '/', '/', '', '/', '/world'],
79
+ output: '/hello/world',
80
+ },
81
+ {
82
+ input: ['', '', '/tt', 'ko', 'hello'],
83
+ output: '/tt/ko/hello',
84
+ },
85
+ {
86
+ input: ['', '///hello///', '', '///world'],
87
+ output: '/hello/world',
88
+ },
89
+ {
90
+ input: ['', '/hello/', ''],
91
+ output: '/hello/',
92
+ },
93
+ {
94
+ input: ['', '/', ''],
95
+ output: '/',
96
+ },
97
+ {
98
+ input: ['///', '///'],
99
+ output: '/',
100
+ },
101
+ {
102
+ input: ['/', '/hello/world/', '///'],
103
+ output: '/hello/world/',
104
+ },
105
+ ];
106
+ asserts.forEach((testCase) => {
107
+ expect(normalizeUrl(testCase.input)).toBe(testCase.output);
108
+ });
109
+
110
+ expect(() =>
111
+ // @ts-expect-error undefined for test
112
+ normalizeUrl(['http:example.com', undefined]),
113
+ ).toThrowErrorMatchingInlineSnapshot(
114
+ `"Url must be a string. Received undefined"`,
115
+ );
116
+ });
117
+ });
@@ -5,28 +5,9 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
- import {simpleHash, isNameTooLong, shortName} from '../pathUtils';
8
+ import {isNameTooLong, shortName} from '../pathUtils';
9
9
 
10
10
  describe('pathUtils', () => {
11
- test('simpleHash', () => {
12
- const asserts: Record<string, string> = {
13
- '': 'd41',
14
- '/foo-bar': '096',
15
- '/foo/bar': '1df',
16
- '/endi/lie': '9fa',
17
- '/endi-lie': 'fd3',
18
- '/yangshun/tay': '48d',
19
- '/yangshun-tay': 'f3b',
20
- '/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar':
21
- 'd46',
22
- '/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/foo/bar/test1-test2':
23
- '787',
24
- };
25
- Object.keys(asserts).forEach((file) => {
26
- expect(simpleHash(file, 3)).toBe(asserts[file]);
27
- });
28
- });
29
-
30
11
  test('isNameTooLong', () => {
31
12
  const asserts: Record<string, boolean> = {
32
13
  '': false,
@@ -36,8 +17,10 @@ describe('pathUtils', () => {
36
17
  'endi-lie-fd3': false,
37
18
  'yangshun-tay-48d': false,
38
19
  'yangshun-tay-f3b': false,
39
- 'foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-d46': true,
40
- 'foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-test-1-test-2-787': true,
20
+ 'foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-d46':
21
+ true,
22
+ 'foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-foo-bar-test-1-test-2-787':
23
+ true,
41
24
  };
42
25
  Object.keys(asserts).forEach((path) => {
43
26
  expect(isNameTooLong(path)).toBe(asserts[path]);
@@ -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 {createSlugger} from '../slugger';
9
+
10
+ describe('createSlugger', () => {
11
+ test('can create unique slugs', () => {
12
+ const slugger = createSlugger();
13
+ expect(slugger.slug('Some$/vaLue$!^')).toEqual('somevalue');
14
+ expect(slugger.slug('Some$/vaLue$!^')).toEqual('somevalue-1');
15
+ expect(slugger.slug('Some$/vaLue$!^')).toEqual('somevalue-2');
16
+ expect(slugger.slug('Some$/vaLue$!^-1')).toEqual('somevalue-1-1');
17
+ });
18
+
19
+ test('can create unique slugs respecting case', () => {
20
+ const slugger = createSlugger();
21
+ const opt = {maintainCase: true};
22
+ expect(slugger.slug('Some$/vaLue$!^', opt)).toEqual('SomevaLue');
23
+ expect(slugger.slug('Some$/vaLue$!^', opt)).toEqual('SomevaLue-1');
24
+ expect(slugger.slug('Some$/vaLue$!^', opt)).toEqual('SomevaLue-2');
25
+ expect(slugger.slug('Some$/vaLue$!^-1', opt)).toEqual('SomevaLue-1-1');
26
+ });
27
+ });
@@ -0,0 +1,183 @@
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
+ normalizeFrontMatterTag,
10
+ normalizeFrontMatterTags,
11
+ groupTaggedItems,
12
+ Tag,
13
+ } from '../tags';
14
+
15
+ describe('normalizeFrontMatterTag', () => {
16
+ type Input = Parameters<typeof normalizeFrontMatterTag>[1];
17
+ type Output = ReturnType<typeof normalizeFrontMatterTag>;
18
+
19
+ test('should normalize simple string tag', () => {
20
+ const tagsPath = '/all/tags';
21
+ const input: Input = 'tag';
22
+ const expectedOutput: Output = {
23
+ label: 'tag',
24
+ permalink: `${tagsPath}/tag`,
25
+ };
26
+ expect(normalizeFrontMatterTag(tagsPath, input)).toEqual(expectedOutput);
27
+ });
28
+
29
+ test('should normalize complex string tag', () => {
30
+ const tagsPath = '/all/tags';
31
+ const input: Input = 'some more Complex_tag';
32
+ const expectedOutput: Output = {
33
+ label: 'some more Complex_tag',
34
+ permalink: `${tagsPath}/some-more-complex-tag`,
35
+ };
36
+ expect(normalizeFrontMatterTag(tagsPath, input)).toEqual(expectedOutput);
37
+ });
38
+
39
+ test('should normalize simple object tag', () => {
40
+ const tagsPath = '/all/tags';
41
+ const input: Input = {label: 'tag', permalink: 'tagPermalink'};
42
+ const expectedOutput: Output = {
43
+ label: 'tag',
44
+ permalink: `${tagsPath}/tagPermalink`,
45
+ };
46
+ expect(normalizeFrontMatterTag(tagsPath, input)).toEqual(expectedOutput);
47
+ });
48
+
49
+ test('should normalize complex string tag', () => {
50
+ const tagsPath = '/all/tags';
51
+ const input: Input = {
52
+ label: 'tag complex Label',
53
+ permalink: '/MoreComplex/Permalink',
54
+ };
55
+ const expectedOutput: Output = {
56
+ label: 'tag complex Label',
57
+ permalink: `${tagsPath}/MoreComplex/Permalink`,
58
+ };
59
+ expect(normalizeFrontMatterTag(tagsPath, input)).toEqual(expectedOutput);
60
+ });
61
+ });
62
+
63
+ describe('normalizeFrontMatterTags', () => {
64
+ type Input = Parameters<typeof normalizeFrontMatterTags>[1];
65
+ type Output = ReturnType<typeof normalizeFrontMatterTags>;
66
+
67
+ test('should normalize string list', () => {
68
+ const tagsPath = '/all/tags';
69
+ const input: Input = ['tag 1', 'tag-1', 'tag 3', 'tag1', 'tag-2'];
70
+ // Keep user input order but remove tags that lead to same permalink
71
+ const expectedOutput: Output = [
72
+ {
73
+ label: 'tag 1',
74
+ permalink: `${tagsPath}/tag-1`,
75
+ },
76
+ {
77
+ label: 'tag 3',
78
+ permalink: `${tagsPath}/tag-3`,
79
+ },
80
+ {
81
+ label: 'tag-2',
82
+ permalink: `${tagsPath}/tag-2`,
83
+ },
84
+ ];
85
+ expect(normalizeFrontMatterTags(tagsPath, input)).toEqual(expectedOutput);
86
+ });
87
+
88
+ test('should normalize complex mixed list', () => {
89
+ const tagsPath = '/all/tags';
90
+ const input: Input = [
91
+ 'tag 1',
92
+ {label: 'tag-1', permalink: '/tag-1'},
93
+ 'tag 3',
94
+ 'tag1',
95
+ {label: 'tag 4', permalink: '/tag4Permalink'},
96
+ ];
97
+ // Keep user input order but remove tags that lead to same permalink
98
+ const expectedOutput: Output = [
99
+ {
100
+ label: 'tag 1',
101
+ permalink: `${tagsPath}/tag-1`,
102
+ },
103
+ {
104
+ label: 'tag 3',
105
+ permalink: `${tagsPath}/tag-3`,
106
+ },
107
+ {
108
+ label: 'tag 4',
109
+ permalink: `${tagsPath}/tag4Permalink`,
110
+ },
111
+ ];
112
+ expect(normalizeFrontMatterTags(tagsPath, input)).toEqual(expectedOutput);
113
+ });
114
+ });
115
+
116
+ describe('groupTaggedItems', () => {
117
+ type SomeTaggedItem = {
118
+ id: string;
119
+ nested: {
120
+ tags: Tag[];
121
+ };
122
+ };
123
+ function groupItems(items: SomeTaggedItem[]) {
124
+ return groupTaggedItems(items, (item) => item.nested.tags);
125
+ }
126
+
127
+ type Input = Parameters<typeof groupItems>[0];
128
+ type Output = ReturnType<typeof groupItems>;
129
+
130
+ test('should group items by tag permalink', () => {
131
+ const tagGuide = {label: 'Guide', permalink: '/guide'};
132
+ const tagTutorial = {label: 'Tutorial', permalink: '/tutorial'};
133
+ const tagAPI = {label: 'API', permalink: '/api'};
134
+
135
+ // This one will be grouped under same permalink and label is ignored
136
+ const tagTutorialOtherLabel = {
137
+ label: 'TutorialOtherLabel',
138
+ permalink: '/tutorial',
139
+ };
140
+
141
+ const item1: SomeTaggedItem = {
142
+ id: '1',
143
+ nested: {
144
+ tags: [
145
+ tagGuide,
146
+ tagTutorial,
147
+ tagAPI,
148
+ // Add some duplicates on purpose: they should be filtered
149
+ tagGuide,
150
+ tagTutorialOtherLabel,
151
+ ],
152
+ },
153
+ };
154
+ const item2: SomeTaggedItem = {
155
+ id: '2',
156
+ nested: {
157
+ tags: [tagAPI],
158
+ },
159
+ };
160
+ const item3: SomeTaggedItem = {
161
+ id: '3',
162
+ nested: {
163
+ tags: [tagTutorial],
164
+ },
165
+ };
166
+ const item4: SomeTaggedItem = {
167
+ id: '4',
168
+ nested: {
169
+ tags: [tagTutorialOtherLabel],
170
+ },
171
+ };
172
+
173
+ const input: Input = [item1, item2, item3, item4];
174
+
175
+ const expectedOutput: Output = {
176
+ '/guide': {tag: tagGuide, items: [item1]},
177
+ '/tutorial': {tag: tagTutorial, items: [item1, item3, item4]},
178
+ '/api': {tag: tagAPI, items: [item1, item2]},
179
+ };
180
+
181
+ expect(groupItems(input)).toEqual(expectedOutput);
182
+ });
183
+ });
@@ -0,0 +1,33 @@
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 {getFileLoaderUtils} from '../webpackUtils';
9
+
10
+ describe('getFileLoaderUtils()', () => {
11
+ test('plugin svgo/removeViewBox should be disabled', () => {
12
+ const {oneOf} = getFileLoaderUtils().rules.svg();
13
+ expect(oneOf[0].use).toContainEqual(
14
+ expect.objectContaining({
15
+ loader: require.resolve('@svgr/webpack'),
16
+ options: expect.objectContaining({
17
+ svgoConfig: {
18
+ plugins: [
19
+ {
20
+ name: 'preset-default',
21
+ params: {
22
+ overrides: {
23
+ removeViewBox: false,
24
+ },
25
+ },
26
+ },
27
+ ],
28
+ },
29
+ }),
30
+ }),
31
+ );
32
+ });
33
+ });
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright (c) Facebook, Inc. and its affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ export const NODE_MAJOR_VERSION = parseInt(
9
+ process.versions.node.split('.')[0],
10
+ 10,
11
+ );
12
+ export const NODE_MINOR_VERSION = parseInt(
13
+ process.versions.node.split('.')[1],
14
+ 10,
15
+ );
16
+
17
+ // Can be overridden with cli option --out-dir
18
+ export const DEFAULT_BUILD_DIR_NAME = 'build';
19
+
20
+ // Can be overridden with cli option --config
21
+ export const DEFAULT_CONFIG_FILE_NAME = 'docusaurus.config.js';
22
+
23
+ export const BABEL_CONFIG_FILE_NAME =
24
+ process.env.DOCUSAURUS_BABEL_CONFIG_FILE_NAME || 'babel.config.js';
25
+
26
+ export const GENERATED_FILES_DIR_NAME =
27
+ process.env.DOCUSAURUS_GENERATED_FILES_DIR_NAME || '.docusaurus';
28
+
29
+ export const SRC_DIR_NAME = 'src';
30
+ export const STATIC_DIR_NAME = 'static';
31
+ export const OUTPUT_STATIC_ASSETS_DIR_NAME = 'assets'; // files handled by webpack, hashed (can be cached aggressively)
32
+ export const THEME_PATH = `${SRC_DIR_NAME}/theme`;
33
+ export const DEFAULT_PORT = 3000;
34
+ export const DEFAULT_PLUGIN_ID = 'default';
35
+
36
+ // Temporary fix for https://github.com/facebook/docusaurus/issues/5493
37
+ export const WEBPACK_URL_LOADER_LIMIT =
38
+ process.env.WEBPACK_URL_LOADER_LIMIT ?? 10000;
package/src/deps.d.ts ADDED
@@ -0,0 +1,14 @@
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
+ declare module 'resolve-pathname' {
9
+ export default function resolvePathname(to: string, from?: string): string;
10
+ }
11
+
12
+ declare module '@mdx-js/runtime';
13
+ declare module 'remark-mdx-remove-imports';
14
+ declare module 'remark-mdx-remove-exports';
@@ -0,0 +1,63 @@
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
+ // Globby/Micromatch are the 2 libs we use in Docusaurus consistently
9
+
10
+ export {default as Globby} from 'globby';
11
+ import Micromatch from 'micromatch'; // Note: Micromatch is used by Globby
12
+ import path from 'path';
13
+
14
+ // The default patterns we ignore when globbing
15
+ // using _ prefix for exclusion by convention
16
+ export const GlobExcludeDefault = [
17
+ // Ignore files starting with _
18
+ '**/_*.{js,jsx,ts,tsx,md,mdx}',
19
+
20
+ // Ignore folders starting with _ (including folder content)
21
+ '**/_*/**',
22
+
23
+ // Ignore tests
24
+ '**/*.test.{js,jsx,ts,tsx}',
25
+ '**/__tests__/**',
26
+ ];
27
+
28
+ type Matcher = (str: string) => boolean;
29
+
30
+ export function createMatcher(patterns: string[]): Matcher {
31
+ const regexp = new RegExp(
32
+ patterns.map((pattern) => Micromatch.makeRe(pattern).source).join('|'),
33
+ );
34
+ return (str) => regexp.test(str);
35
+ }
36
+
37
+ // We use match patterns like '**/_*/**',
38
+ // This function permits to help to:
39
+ // Match /user/sebastien/website/docs/_partials/xyz.md
40
+ // Ignore /user/_sebastien/website/docs/partials/xyz.md
41
+ export function createAbsoluteFilePathMatcher(
42
+ patterns: string[],
43
+ rootFolders: string[],
44
+ ): Matcher {
45
+ const matcher = createMatcher(patterns);
46
+
47
+ function getRelativeFilePath(absoluteFilePath: string) {
48
+ const rootFolder = rootFolders.find((folderPath) =>
49
+ absoluteFilePath.startsWith(folderPath),
50
+ );
51
+ if (!rootFolder) {
52
+ throw new Error(
53
+ `createAbsoluteFilePathMatcher unexpected error, absoluteFilePath=${absoluteFilePath} was not contained in any of the root folders ${JSON.stringify(
54
+ rootFolders,
55
+ )}`,
56
+ );
57
+ }
58
+ return path.relative(rootFolder, absoluteFilePath);
59
+ }
60
+
61
+ return (absoluteFilePath: string) =>
62
+ matcher(getRelativeFilePath(absoluteFilePath));
63
+ }
@@ -5,10 +5,19 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
 
8
+ import {createHash} from 'crypto';
8
9
  import {kebabCase} from 'lodash';
10
+ import {shortName, isNameTooLong} from './pathUtils';
9
11
 
10
- import {shortName, isNameTooLong, simpleHash} from './pathUtils';
12
+ export function md5Hash(str: string): string {
13
+ return createHash('md5').update(str).digest('hex');
14
+ }
15
+
16
+ export function simpleHash(str: string, length: number): string {
17
+ return md5Hash(str).substr(0, length);
18
+ }
11
19
 
20
+ // Based on https://github.com/gatsbyjs/gatsby/pull/21518/files
12
21
  /**
13
22
  * Given an input string, convert to kebab-case and append a hash.
14
23
  * Avoid str collision.