@azerion/bunosaurus-plugin-content-docs 0.0.0-stage → 4.0.0

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 (119) hide show
  1. package/README.md +6 -2
  2. package/lib/categoryGeneratedIndex.d.ts +12 -0
  3. package/lib/categoryGeneratedIndex.js +36 -0
  4. package/lib/cli.d.ts +13 -0
  5. package/lib/cli.js +124 -0
  6. package/lib/client/doc.d.ts +29 -0
  7. package/lib/client/doc.js +47 -0
  8. package/lib/client/docSidebarItemsExpandedState.d.ts +30 -0
  9. package/lib/client/docSidebarItemsExpandedState.js +27 -0
  10. package/lib/client/docsClientUtils.d.ts +15 -0
  11. package/lib/client/docsClientUtils.js +86 -0
  12. package/lib/client/docsPreferredVersion.d.ts +29 -0
  13. package/lib/client/docsPreferredVersion.js +124 -0
  14. package/lib/client/docsSearch.d.ts +19 -0
  15. package/lib/client/docsSearch.js +39 -0
  16. package/lib/client/docsSidebar.d.ts +25 -0
  17. package/lib/client/docsSidebar.js +29 -0
  18. package/lib/client/docsUtils.d.ts +112 -0
  19. package/lib/client/docsUtils.js +299 -0
  20. package/lib/client/docsVersion.d.ts +19 -0
  21. package/lib/client/docsVersion.js +25 -0
  22. package/lib/client/index.d.ts +91 -0
  23. package/lib/client/index.js +83 -0
  24. package/lib/client/structuredDataUtils.d.ts +11 -0
  25. package/lib/client/structuredDataUtils.js +35 -0
  26. package/lib/constants.d.ts +14 -0
  27. package/lib/constants.js +17 -0
  28. package/lib/contentHelpers.d.ts +12 -0
  29. package/lib/contentHelpers.js +31 -0
  30. package/lib/docs.d.ts +48 -0
  31. package/lib/docs.js +252 -0
  32. package/lib/frontMatter.d.ts +10 -0
  33. package/lib/frontMatter.js +46 -0
  34. package/lib/globalData.d.ts +9 -0
  35. package/lib/globalData.js +59 -0
  36. package/lib/index.d.ts +10 -0
  37. package/lib/index.js +198 -0
  38. package/lib/numberPrefix.d.ts +11 -0
  39. package/lib/numberPrefix.js +50 -0
  40. package/lib/options.d.ts +10 -0
  41. package/lib/options.js +138 -0
  42. package/lib/props.d.ts +21 -0
  43. package/lib/props.js +156 -0
  44. package/lib/routes.d.ts +22 -0
  45. package/lib/routes.js +184 -0
  46. package/lib/server-export.d.ts +9 -0
  47. package/lib/server-export.js +25 -0
  48. package/lib/sidebars/generator.d.ts +10 -0
  49. package/lib/sidebars/generator.js +217 -0
  50. package/lib/sidebars/index.d.ts +13 -0
  51. package/lib/sidebars/index.js +99 -0
  52. package/lib/sidebars/normalization.d.ts +13 -0
  53. package/lib/sidebars/normalization.js +58 -0
  54. package/lib/sidebars/postProcessor.d.ts +11 -0
  55. package/lib/sidebars/postProcessor.js +82 -0
  56. package/lib/sidebars/processor.d.ts +10 -0
  57. package/lib/sidebars/processor.js +77 -0
  58. package/lib/sidebars/types.d.ts +192 -0
  59. package/lib/sidebars/types.js +8 -0
  60. package/lib/sidebars/utils.d.ts +69 -0
  61. package/lib/sidebars/utils.js +327 -0
  62. package/lib/sidebars/validation.d.ts +11 -0
  63. package/lib/sidebars/validation.js +152 -0
  64. package/lib/slug.d.ts +15 -0
  65. package/lib/slug.js +51 -0
  66. package/lib/translations.d.ts +10 -0
  67. package/lib/translations.js +243 -0
  68. package/lib/types.d.ts +27 -0
  69. package/lib/types.js +8 -0
  70. package/lib/versions/files.d.ts +54 -0
  71. package/lib/versions/files.js +152 -0
  72. package/lib/versions/loadVersion.d.ts +17 -0
  73. package/lib/versions/loadVersion.js +126 -0
  74. package/lib/versions/validation.d.ts +17 -0
  75. package/lib/versions/validation.js +70 -0
  76. package/lib/versions/version.d.ts +40 -0
  77. package/lib/versions/version.js +189 -0
  78. package/package.json +70 -4
  79. package/src/categoryGeneratedIndex.ts +60 -0
  80. package/src/cli.ts +180 -0
  81. package/src/client/doc.tsx +71 -0
  82. package/src/client/docSidebarItemsExpandedState.tsx +55 -0
  83. package/src/client/docsClientUtils.ts +140 -0
  84. package/src/client/docsPreferredVersion.tsx +245 -0
  85. package/src/client/docsSearch.test.ts +15 -0
  86. package/src/client/docsSearch.ts +57 -0
  87. package/src/client/docsSidebar.tsx +50 -0
  88. package/src/client/docsUtils.tsx +442 -0
  89. package/src/client/docsVersion.tsx +36 -0
  90. package/src/client/index.ts +211 -0
  91. package/src/client/structuredDataUtils.ts +54 -0
  92. package/src/constants.ts +15 -0
  93. package/src/contentHelpers.ts +34 -0
  94. package/src/docs.ts +402 -0
  95. package/src/frontMatter.ts +57 -0
  96. package/src/globalData.ts +79 -0
  97. package/src/index.ts +289 -0
  98. package/src/numberPrefix.ts +62 -0
  99. package/src/options.ts +185 -0
  100. package/src/plugin-content-docs.d.ts +667 -0
  101. package/src/props.ts +223 -0
  102. package/src/routes.ts +263 -0
  103. package/src/server-export.ts +26 -0
  104. package/src/sidebars/README.md +10 -0
  105. package/src/sidebars/generator.ts +307 -0
  106. package/src/sidebars/index.ts +130 -0
  107. package/src/sidebars/normalization.ts +91 -0
  108. package/src/sidebars/postProcessor.ts +115 -0
  109. package/src/sidebars/processor.ts +122 -0
  110. package/src/sidebars/types.ts +293 -0
  111. package/src/sidebars/utils.ts +529 -0
  112. package/src/sidebars/validation.ts +189 -0
  113. package/src/slug.ts +79 -0
  114. package/src/translations.ts +365 -0
  115. package/src/types.ts +34 -0
  116. package/src/versions/files.ts +240 -0
  117. package/src/versions/loadVersion.ts +185 -0
  118. package/src/versions/validation.ts +115 -0
  119. package/src/versions/version.ts +300 -0
package/src/slug.ts ADDED
@@ -0,0 +1,79 @@
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 {isValidPathname, resolvePathname} from '@docusaurus/utils';
9
+ import {addLeadingSlash, addTrailingSlash} from '@docusaurus/utils-common';
10
+ import {
11
+ DefaultNumberPrefixParser,
12
+ stripPathNumberPrefixes,
13
+ } from './numberPrefix';
14
+ import {isCategoryIndex, toCategoryIndexMatcherParam} from './docs';
15
+ import type {
16
+ NumberPrefixParser,
17
+ DocMetadataBase,
18
+ } from '@docusaurus/plugin-content-docs';
19
+
20
+ export default function getSlug({
21
+ baseID,
22
+ frontMatterSlug,
23
+ source,
24
+ sourceDirName,
25
+ stripDirNumberPrefixes = true,
26
+ numberPrefixParser = DefaultNumberPrefixParser,
27
+ }: {
28
+ baseID: string;
29
+ frontMatterSlug?: string;
30
+ source: DocMetadataBase['source'];
31
+ sourceDirName: DocMetadataBase['sourceDirName'];
32
+ stripDirNumberPrefixes?: boolean;
33
+ numberPrefixParser?: NumberPrefixParser;
34
+ }): string {
35
+ function getDirNameSlug(): string {
36
+ const dirNameStripped = stripDirNumberPrefixes
37
+ ? stripPathNumberPrefixes(sourceDirName, numberPrefixParser)
38
+ : sourceDirName;
39
+ const resolveDirname =
40
+ sourceDirName === '.'
41
+ ? '/'
42
+ : addLeadingSlash(addTrailingSlash(dirNameStripped));
43
+ return resolveDirname;
44
+ }
45
+
46
+ function computeSlug(): string {
47
+ if (frontMatterSlug?.startsWith('/')) {
48
+ return frontMatterSlug;
49
+ }
50
+ const dirNameSlug = getDirNameSlug();
51
+ if (
52
+ !frontMatterSlug &&
53
+ isCategoryIndex(toCategoryIndexMatcherParam({source, sourceDirName}))
54
+ ) {
55
+ return dirNameSlug;
56
+ }
57
+ const baseSlug = frontMatterSlug ?? baseID;
58
+ return resolvePathname(baseSlug, getDirNameSlug());
59
+ }
60
+
61
+ function ensureValidSlug(slug: string): string {
62
+ if (!isValidPathname(slug)) {
63
+ throw new Error(
64
+ `We couldn't compute a valid slug for document with ID "${baseID}" in "${sourceDirName}" directory.
65
+ The slug we computed looks invalid: ${slug}.
66
+ Maybe your slug front matter is incorrect or there are special characters in the file path?
67
+ By using front matter to set a custom slug, you should be able to fix this error:
68
+
69
+ ---
70
+ slug: /my/customDocPath
71
+ ---
72
+ `,
73
+ );
74
+ }
75
+ return slug;
76
+ }
77
+
78
+ return ensureValidSlug(computeSlug());
79
+ }
@@ -0,0 +1,365 @@
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 _ from 'lodash';
9
+ import {mergeTranslations} from '@docusaurus/utils';
10
+ import logger from '@docusaurus/logger';
11
+ import {CURRENT_VERSION_NAME} from './constants';
12
+ import {
13
+ collectSidebarCategories,
14
+ transformSidebarItems,
15
+ collectSidebarLinks,
16
+ collectSidebarDocItems,
17
+ collectSidebarRefs,
18
+ } from './sidebars/utils';
19
+ import type {
20
+ LoadedVersion,
21
+ LoadedContent,
22
+ } from '@docusaurus/plugin-content-docs';
23
+ import type {
24
+ Sidebar,
25
+ SidebarItemCategory,
26
+ SidebarItemCategoryLink,
27
+ Sidebars,
28
+ } from './sidebars/types';
29
+ import type {
30
+ TranslationFileContent,
31
+ TranslationFile,
32
+ TranslationMessage,
33
+ } from '@docusaurus/types';
34
+
35
+ function getVersionFileName(versionName: string): string {
36
+ if (versionName === CURRENT_VERSION_NAME) {
37
+ return versionName;
38
+ }
39
+ // I don't like this "version-" prefix,
40
+ // but it's for consistency with site/versioned_docs
41
+ return `version-${versionName}`;
42
+ }
43
+
44
+ type TranslationMessageEntry = [string, TranslationMessage];
45
+
46
+ function ensureNoSidebarDuplicateEntries(
47
+ translationEntries: TranslationMessageEntry[],
48
+ ): void {
49
+ const grouped = _.groupBy(translationEntries, (entry) => entry[0]);
50
+ const duplicates = Object.entries(grouped).filter(
51
+ (entry) => entry[1].length > 1,
52
+ );
53
+
54
+ if (duplicates.length > 0) {
55
+ throw new Error(`Multiple docs sidebar items produce the same translation key.
56
+ - ${duplicates
57
+ .map(([translationKey, entries]) => {
58
+ return `${logger.code(translationKey)}: ${logger.num(
59
+ entries.length,
60
+ )} duplicates found:\n - ${entries
61
+ .map((duplicate) => {
62
+ const desc = duplicate[1].description;
63
+ return `${logger.name(duplicate[1].message)} ${
64
+ desc ? `(${logger.subdue(desc)})` : ''
65
+ }`;
66
+ })
67
+ .join('\n - ')}`;
68
+ })
69
+ .join('\n\n- ')}
70
+
71
+ To avoid translation key conflicts, use the ${logger.code(
72
+ 'key',
73
+ )} attribute on the sidebar items above to uniquely identify them.
74
+
75
+ When using autogenerated sidebars, you can provide a unique translation key by adding:
76
+ - the ${logger.code('key')} attribute to category item metadata (${logger.code(
77
+ '_category_.json',
78
+ )} / ${logger.code('_category_.yml')})
79
+ - the ${logger.code(
80
+ 'sidebar_key',
81
+ )} attribute to doc item metadata (front matter in ${logger.code(
82
+ 'Category/index.mdx',
83
+ )})`);
84
+ }
85
+ }
86
+
87
+ function getSidebarTranslationFileContent(
88
+ sidebar: Sidebar,
89
+ sidebarName: string,
90
+ ): TranslationFileContent {
91
+ const categories = collectSidebarCategories(sidebar);
92
+
93
+ const categoryEntries: TranslationMessageEntry[] = categories.flatMap(
94
+ (category) => {
95
+ const entries: TranslationMessageEntry[] = [];
96
+ const categoryKey = category.key ?? category.label;
97
+
98
+ entries.push([
99
+ `sidebar.${sidebarName}.category.${categoryKey}`,
100
+ {
101
+ message: category.label,
102
+ description: `The label for category '${category.label}' in sidebar '${sidebarName}'`,
103
+ },
104
+ ]);
105
+
106
+ if (category.link?.type === 'generated-index') {
107
+ if (category.link.title) {
108
+ entries.push([
109
+ `sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.title`,
110
+ {
111
+ message: category.link.title,
112
+ description: `The generated-index page title for category '${category.label}' in sidebar '${sidebarName}'`,
113
+ },
114
+ ]);
115
+ }
116
+ if (category.link.description) {
117
+ entries.push([
118
+ `sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.description`,
119
+ {
120
+ message: category.link.description,
121
+ description: `The generated-index page description for category '${category.label}' in sidebar '${sidebarName}'`,
122
+ },
123
+ ]);
124
+ }
125
+ }
126
+
127
+ return entries;
128
+ },
129
+ );
130
+
131
+ const links = collectSidebarLinks(sidebar);
132
+ const linksEntries: TranslationMessageEntry[] = links.map((link) => {
133
+ const linkKey = link.key ?? link.label;
134
+ return [
135
+ `sidebar.${sidebarName}.link.${linkKey}`,
136
+ {
137
+ message: link.label,
138
+ description: `The label for link '${link.label}' in sidebar '${sidebarName}', linking to '${link.href}'`,
139
+ },
140
+ ];
141
+ });
142
+
143
+ const docs = collectSidebarDocItems(sidebar)
144
+ .concat(collectSidebarRefs(sidebar))
145
+ .filter((item) => item.translatable);
146
+ const docLinksEntries: TranslationMessageEntry[] = docs.map((doc) => {
147
+ const docKey = doc.key ?? doc.label!;
148
+ return [
149
+ `sidebar.${sidebarName}.doc.${docKey}`,
150
+ {
151
+ message: doc.label!,
152
+ description: `The label for the doc item '${doc.label!}' in sidebar '${sidebarName}', linking to the doc ${
153
+ doc.id
154
+ }`,
155
+ },
156
+ ];
157
+ });
158
+
159
+ const allEntries = [...categoryEntries, ...linksEntries, ...docLinksEntries];
160
+ ensureNoSidebarDuplicateEntries(allEntries);
161
+ return Object.fromEntries(allEntries);
162
+ }
163
+
164
+ function translateSidebar({
165
+ sidebar,
166
+ sidebarName,
167
+ sidebarsTranslations,
168
+ }: {
169
+ sidebar: Sidebar;
170
+ sidebarName: string;
171
+ sidebarsTranslations: TranslationFileContent;
172
+ }): Sidebar {
173
+ function transformSidebarCategoryLink(
174
+ category: SidebarItemCategory,
175
+ ): SidebarItemCategoryLink | undefined {
176
+ if (!category.link) {
177
+ return undefined;
178
+ }
179
+ if (category.link.type === 'generated-index') {
180
+ const categoryKey = category.key ?? category.label;
181
+ const title =
182
+ sidebarsTranslations[
183
+ `sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.title`
184
+ ]?.message ?? category.link.title;
185
+ const description =
186
+ sidebarsTranslations[
187
+ `sidebar.${sidebarName}.category.${categoryKey}.link.generated-index.description`
188
+ ]?.message ?? category.link.description;
189
+ return {
190
+ ...category.link,
191
+ title,
192
+ description,
193
+ };
194
+ }
195
+ return category.link;
196
+ }
197
+
198
+ return transformSidebarItems(sidebar, (item) => {
199
+ if (item.type === 'category') {
200
+ const link = transformSidebarCategoryLink(item);
201
+ const categoryKey = item.key ?? item.label;
202
+ return {
203
+ ...item,
204
+ label:
205
+ sidebarsTranslations[`sidebar.${sidebarName}.category.${categoryKey}`]
206
+ ?.message ?? item.label,
207
+ ...(link && {link}),
208
+ };
209
+ }
210
+ if (item.type === 'link') {
211
+ const linkKey = item.key ?? item.label;
212
+ return {
213
+ ...item,
214
+ label:
215
+ sidebarsTranslations[`sidebar.${sidebarName}.link.${linkKey}`]
216
+ ?.message ?? item.label,
217
+ };
218
+ }
219
+ if ((item.type === 'doc' || item.type === 'ref') && item.translatable) {
220
+ const docKey = item.key ?? item.label!;
221
+ return {
222
+ ...item,
223
+ label:
224
+ sidebarsTranslations[`sidebar.${sidebarName}.doc.${docKey}`]
225
+ ?.message ?? item.label,
226
+ };
227
+ }
228
+ return item;
229
+ });
230
+ }
231
+
232
+ function getSidebarsTranslations(
233
+ version: LoadedVersion,
234
+ ): TranslationFileContent {
235
+ return mergeTranslations(
236
+ Object.entries(version.sidebars).map(([sidebarName, sidebar]) =>
237
+ getSidebarTranslationFileContent(sidebar, sidebarName),
238
+ ),
239
+ );
240
+ }
241
+ function translateSidebars(
242
+ version: LoadedVersion,
243
+ sidebarsTranslations: TranslationFileContent,
244
+ ): Sidebars {
245
+ return _.mapValues(version.sidebars, (sidebar, sidebarName) =>
246
+ translateSidebar({
247
+ sidebar,
248
+ sidebarName,
249
+ sidebarsTranslations,
250
+ }),
251
+ );
252
+ }
253
+
254
+ function getVersionTranslationFiles(version: LoadedVersion): TranslationFile[] {
255
+ const versionTranslations: TranslationFileContent = {
256
+ 'version.label': {
257
+ message: version.label,
258
+ description: `The label for version ${version.versionName}`,
259
+ },
260
+ };
261
+
262
+ const sidebarsTranslations: TranslationFileContent =
263
+ getSidebarsTranslations(version);
264
+
265
+ return [
266
+ {
267
+ path: getVersionFileName(version.versionName),
268
+ content: mergeTranslations([versionTranslations, sidebarsTranslations]),
269
+ },
270
+ ];
271
+ }
272
+
273
+ // TODO Docusaurus v4 or later
274
+ // this temporarily works, but it is not an ideal solution
275
+ // The docs navigation can be computed and shouldn't be part of LoadedVersion
276
+ // We need to derive the navigation from already translated content
277
+ // See https://github.com/facebook/docusaurus/pull/11794
278
+ function translateDocNavigation(
279
+ docs: LoadedVersion['docs'],
280
+ translatedSidebars: Sidebars,
281
+ ): LoadedVersion['docs'] {
282
+ // Build a map of permalink -> translated label for generated-index categories
283
+ const translatedLabelByPermalink = new Map<string, string>();
284
+ for (const sidebar of Object.values(translatedSidebars)) {
285
+ for (const category of collectSidebarCategories(sidebar)) {
286
+ if (category.link?.type === 'generated-index') {
287
+ translatedLabelByPermalink.set(category.link.permalink, category.label);
288
+ }
289
+ }
290
+ }
291
+
292
+ if (translatedLabelByPermalink.size === 0) {
293
+ return docs;
294
+ }
295
+
296
+ return docs.map((doc) => {
297
+ const previous =
298
+ doc.previous && translatedLabelByPermalink.has(doc.previous.permalink)
299
+ ? {
300
+ ...doc.previous,
301
+ title: translatedLabelByPermalink.get(doc.previous.permalink)!,
302
+ }
303
+ : doc.previous;
304
+ const next =
305
+ doc.next && translatedLabelByPermalink.has(doc.next.permalink)
306
+ ? {
307
+ ...doc.next,
308
+ title: translatedLabelByPermalink.get(doc.next.permalink)!,
309
+ }
310
+ : doc.next;
311
+ if (previous === doc.previous && next === doc.next) {
312
+ return doc;
313
+ }
314
+ return {...doc, previous, next};
315
+ });
316
+ }
317
+
318
+ function translateVersion(
319
+ version: LoadedVersion,
320
+ translationFiles: {[fileName: string]: TranslationFile},
321
+ ): LoadedVersion {
322
+ const versionTranslations =
323
+ translationFiles[getVersionFileName(version.versionName)]!.content;
324
+ const translatedSidebars = translateSidebars(version, versionTranslations);
325
+ return {
326
+ ...version,
327
+ label: versionTranslations['version.label']?.message ?? version.label,
328
+ sidebars: translatedSidebars,
329
+ docs: translateDocNavigation(version.docs, translatedSidebars),
330
+ };
331
+ }
332
+
333
+ function getVersionsTranslationFiles(
334
+ versions: LoadedVersion[],
335
+ ): TranslationFile[] {
336
+ return versions.flatMap(getVersionTranslationFiles);
337
+ }
338
+ function translateVersions(
339
+ versions: LoadedVersion[],
340
+ translationFiles: {[fileName: string]: TranslationFile},
341
+ ): LoadedVersion[] {
342
+ return versions.map((version) => translateVersion(version, translationFiles));
343
+ }
344
+
345
+ export function getLoadedContentTranslationFiles(
346
+ loadedContent: LoadedContent,
347
+ ): TranslationFile[] {
348
+ return getVersionsTranslationFiles(loadedContent.loadedVersions);
349
+ }
350
+ export function translateLoadedContent(
351
+ loadedContent: LoadedContent,
352
+ translationFiles: TranslationFile[],
353
+ ): LoadedContent {
354
+ const translationFilesMap: {[fileName: string]: TranslationFile} = _.keyBy(
355
+ translationFiles,
356
+ (f) => f.path,
357
+ );
358
+
359
+ return {
360
+ loadedVersions: translateVersions(
361
+ loadedContent.loadedVersions,
362
+ translationFilesMap,
363
+ ),
364
+ };
365
+ }
package/src/types.ts ADDED
@@ -0,0 +1,34 @@
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 type {TagMetadata} from '@docusaurus/utils';
9
+ import type {
10
+ LoadedVersion,
11
+ CategoryGeneratedIndexMetadata,
12
+ } from '@docusaurus/plugin-content-docs';
13
+ import type {SidebarsUtils} from './sidebars/utils';
14
+
15
+ export type DocFile = {
16
+ contentPath: string; // /!\ may be localized
17
+ filePath: string; // /!\ may be localized
18
+ source: string;
19
+ content: string;
20
+ };
21
+
22
+ export type VersionTag = TagMetadata & {
23
+ /** All doc ids having this tag. */
24
+ docIds: string[];
25
+ unlisted: boolean;
26
+ };
27
+ export type VersionTags = {
28
+ [permalink: string]: VersionTag;
29
+ };
30
+
31
+ export type FullVersion = LoadedVersion & {
32
+ sidebarsUtils: SidebarsUtils;
33
+ categoryGeneratedIndices: CategoryGeneratedIndexMetadata[];
34
+ };