@docusaurus/plugin-content-docs 2.0.0-beta.21 → 2.0.0-beta.22

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/cli.js CHANGED
@@ -50,12 +50,12 @@ async function cliDocsVersionCommand(version, { id: pluginId, path: docsPath, si
50
50
  logger_1.default.info `Versioned docs will be created for the following locales: name=${i18n.locales}`;
51
51
  }
52
52
  await Promise.all(i18n.locales.map(async (locale) => {
53
+ const localizationDir = path_1.default.resolve(siteDir, i18n.path, i18n.localeConfigs[locale].path);
53
54
  // Copy docs files.
54
55
  const docsDir = locale === i18n.defaultLocale
55
56
  ? path_1.default.resolve(siteDir, docsPath)
56
57
  : (0, files_1.getDocsDirPathLocalized)({
57
- siteDir,
58
- locale,
58
+ localizationDir,
59
59
  pluginId,
60
60
  versionName: constants_1.CURRENT_VERSION_NAME,
61
61
  });
@@ -72,8 +72,7 @@ async function cliDocsVersionCommand(version, { id: pluginId, path: docsPath, si
72
72
  const newVersionDir = locale === i18n.defaultLocale
73
73
  ? (0, files_1.getVersionDocsDirPath)(siteDir, pluginId, version)
74
74
  : (0, files_1.getDocsDirPathLocalized)({
75
- siteDir,
76
- locale,
75
+ localizationDir,
77
76
  pluginId,
78
77
  versionName: version,
79
78
  });
@@ -4,8 +4,59 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- import type { GlobalPluginData, GlobalVersion, ActivePlugin, ActiveDocContext, DocVersionSuggestions } from '@docusaurus/plugin-content-docs/client';
8
7
  import type { UseDataOptions } from '@docusaurus/types';
8
+ export declare type ActivePlugin = {
9
+ pluginId: string;
10
+ pluginData: GlobalPluginData;
11
+ };
12
+ export declare type ActiveDocContext = {
13
+ activeVersion?: GlobalVersion;
14
+ activeDoc?: GlobalDoc;
15
+ alternateDocVersions: {
16
+ [versionName: string]: GlobalDoc;
17
+ };
18
+ };
19
+ export declare type GlobalDoc = {
20
+ /**
21
+ * For generated index pages, this is the `slug`, **not** `permalink`
22
+ * (without base URL). Because slugs have leading slashes but IDs don't,
23
+ * there won't be clashes.
24
+ */
25
+ id: string;
26
+ path: string;
27
+ sidebar: string | undefined;
28
+ };
29
+ export declare type GlobalVersion = {
30
+ name: string;
31
+ label: string;
32
+ isLast: boolean;
33
+ path: string;
34
+ /** The doc with `slug: /`, or first doc in first sidebar */
35
+ mainDocId: string;
36
+ docs: GlobalDoc[];
37
+ /** Unversioned IDs. In development, this list is empty. */
38
+ draftIds: string[];
39
+ sidebars?: {
40
+ [sidebarId: string]: GlobalSidebar;
41
+ };
42
+ };
43
+ export declare type GlobalSidebar = {
44
+ link?: {
45
+ label: string;
46
+ path: string;
47
+ };
48
+ };
49
+ export declare type GlobalPluginData = {
50
+ path: string;
51
+ versions: GlobalVersion[];
52
+ breadcrumbs: boolean;
53
+ };
54
+ export declare type DocVersionSuggestions = {
55
+ /** Suggest the latest version */
56
+ latestVersionSuggestion: GlobalVersion;
57
+ /** Suggest the same doc, in latest version (if one exists) */
58
+ latestDocSuggestion?: GlobalDoc;
59
+ };
9
60
  export declare const useAllDocsData: () => {
10
61
  [pluginId: string]: GlobalPluginData;
11
62
  };
@@ -15,8 +66,16 @@ export declare function useActivePluginAndVersion(options?: UseDataOptions): {
15
66
  activePlugin: ActivePlugin;
16
67
  activeVersion: GlobalVersion | undefined;
17
68
  } | undefined;
69
+ /** Versions are returned ordered (most recent first). */
18
70
  export declare function useVersions(pluginId: string | undefined): GlobalVersion[];
19
71
  export declare function useLatestVersion(pluginId: string | undefined): GlobalVersion;
72
+ /**
73
+ * Returns `undefined` on doc-unrelated pages, because there's no version
74
+ * currently considered as active.
75
+ */
20
76
  export declare function useActiveVersion(pluginId: string | undefined): GlobalVersion | undefined;
21
77
  export declare function useActiveDocContext(pluginId: string | undefined): ActiveDocContext;
78
+ /**
79
+ * Useful to say "hey, you are not on the latest docs version, please switch"
80
+ */
22
81
  export declare function useDocVersionSuggestions(pluginId: string | undefined): DocVersionSuggestions;
@@ -34,6 +34,7 @@ export function useActivePluginAndVersion(options = {}) {
34
34
  activeVersion,
35
35
  };
36
36
  }
37
+ /** Versions are returned ordered (most recent first). */
37
38
  export function useVersions(pluginId) {
38
39
  const data = useDocsData(pluginId);
39
40
  return data.versions;
@@ -42,6 +43,10 @@ export function useLatestVersion(pluginId) {
42
43
  const data = useDocsData(pluginId);
43
44
  return getLatestVersion(data);
44
45
  }
46
+ /**
47
+ * Returns `undefined` on doc-unrelated pages, because there's no version
48
+ * currently considered as active.
49
+ */
45
50
  export function useActiveVersion(pluginId) {
46
51
  const data = useDocsData(pluginId);
47
52
  const { pathname } = useLocation();
@@ -52,6 +57,9 @@ export function useActiveDocContext(pluginId) {
52
57
  const { pathname } = useLocation();
53
58
  return getActiveDocContext(data, pathname);
54
59
  }
60
+ /**
61
+ * Useful to say "hey, you are not on the latest docs version, please switch"
62
+ */
55
63
  export function useDocVersionSuggestions(pluginId) {
56
64
  const data = useDocsData(pluginId);
57
65
  const { pathname } = useLocation();
package/lib/docs.d.ts CHANGED
@@ -8,8 +8,7 @@ import type { MetadataOptions, PluginOptions, CategoryIndexMatcher, DocMetadataB
8
8
  import type { LoadContext } from '@docusaurus/types';
9
9
  import type { SidebarsUtils } from './sidebars/utils';
10
10
  import type { DocFile } from './types';
11
- declare type LastUpdateOptions = Pick<PluginOptions, 'showLastUpdateAuthor' | 'showLastUpdateTime'>;
12
- export declare function readDocFile(versionMetadata: Pick<VersionMetadata, 'contentPath' | 'contentPathLocalized'>, source: string, options: LastUpdateOptions): Promise<DocFile>;
11
+ export declare function readDocFile(versionMetadata: Pick<VersionMetadata, 'contentPath' | 'contentPathLocalized'>, source: string): Promise<DocFile>;
13
12
  export declare function readVersionDocs(versionMetadata: VersionMetadata, options: Pick<PluginOptions, 'include' | 'exclude' | 'showLastUpdateAuthor' | 'showLastUpdateTime'>): Promise<DocFile[]>;
14
13
  export declare type DocEnv = 'production' | 'development';
15
14
  export declare function processDocMetadata(args: {
@@ -18,7 +17,7 @@ export declare function processDocMetadata(args: {
18
17
  context: LoadContext;
19
18
  options: MetadataOptions;
20
19
  env: DocEnv;
21
- }): DocMetadataBase;
20
+ }): Promise<DocMetadataBase>;
22
21
  export declare function addDocNavigation(docsBase: DocMetadataBase[], sidebarsUtils: SidebarsUtils, sidebarFilePath: string): LoadedVersion['docs'];
23
22
  /**
24
23
  * The "main doc" is the "version entry point"
@@ -44,4 +43,3 @@ export declare function createDocsByIdIndex<Doc extends {
44
43
  }>(docs: Doc[]): {
45
44
  [docId: string]: Doc;
46
45
  };
47
- export {};
package/lib/docs.js CHANGED
@@ -18,9 +18,18 @@ const constants_1 = require("./constants");
18
18
  const numberPrefix_1 = require("./numberPrefix");
19
19
  const frontMatter_1 = require("./frontMatter");
20
20
  const utils_2 = require("./sidebars/utils");
21
- async function readLastUpdateData(filePath, options) {
21
+ async function readLastUpdateData(filePath, options, lastUpdateFrontMatter) {
22
22
  const { showLastUpdateAuthor, showLastUpdateTime } = options;
23
23
  if (showLastUpdateAuthor || showLastUpdateTime) {
24
+ const frontMatterTimestamp = lastUpdateFrontMatter?.date
25
+ ? new Date(lastUpdateFrontMatter.date).getTime() / 1000
26
+ : undefined;
27
+ if (lastUpdateFrontMatter?.author && lastUpdateFrontMatter.date) {
28
+ return {
29
+ lastUpdatedAt: frontMatterTimestamp,
30
+ lastUpdatedBy: lastUpdateFrontMatter.author,
31
+ };
32
+ }
24
33
  // Use fake data in dev for faster development.
25
34
  const fileLastUpdateData = process.env.NODE_ENV === 'production'
26
35
  ? await (0, lastUpdate_1.getFileLastUpdate)(filePath)
@@ -28,24 +37,23 @@ async function readLastUpdateData(filePath, options) {
28
37
  author: 'Author',
29
38
  timestamp: 1539502055,
30
39
  };
31
- if (fileLastUpdateData) {
32
- const { author, timestamp } = fileLastUpdateData;
33
- return {
34
- lastUpdatedAt: showLastUpdateTime ? timestamp : undefined,
35
- lastUpdatedBy: showLastUpdateAuthor ? author : undefined,
36
- };
37
- }
40
+ const { author, timestamp } = fileLastUpdateData ?? {};
41
+ return {
42
+ lastUpdatedBy: showLastUpdateAuthor
43
+ ? lastUpdateFrontMatter?.author ?? author
44
+ : undefined,
45
+ lastUpdatedAt: showLastUpdateTime
46
+ ? frontMatterTimestamp ?? timestamp
47
+ : undefined,
48
+ };
38
49
  }
39
50
  return {};
40
51
  }
41
- async function readDocFile(versionMetadata, source, options) {
52
+ async function readDocFile(versionMetadata, source) {
42
53
  const contentPath = await (0, utils_1.getFolderContainingFile)((0, utils_1.getContentPathList)(versionMetadata), source);
43
54
  const filePath = path_1.default.join(contentPath, source);
44
- const [content, lastUpdate] = await Promise.all([
45
- fs_extra_1.default.readFile(filePath, 'utf-8'),
46
- readLastUpdateData(filePath, options),
47
- ]);
48
- return { source, content, lastUpdate, contentPath, filePath };
55
+ const content = await fs_extra_1.default.readFile(filePath, 'utf-8');
56
+ return { source, content, contentPath, filePath };
49
57
  }
50
58
  exports.readDocFile = readDocFile;
51
59
  async function readVersionDocs(versionMetadata, options) {
@@ -53,15 +61,15 @@ async function readVersionDocs(versionMetadata, options) {
53
61
  cwd: versionMetadata.contentPath,
54
62
  ignore: options.exclude,
55
63
  });
56
- return Promise.all(sources.map((source) => readDocFile(versionMetadata, source, options)));
64
+ return Promise.all(sources.map((source) => readDocFile(versionMetadata, source)));
57
65
  }
58
66
  exports.readVersionDocs = readVersionDocs;
59
67
  /** Docs with draft front matter are only considered draft in production. */
60
68
  function isDraftForEnvironment({ env, frontMatter, }) {
61
69
  return (env === 'production' && frontMatter.draft) ?? false;
62
70
  }
63
- function doProcessDocMetadata({ docFile, versionMetadata, context, options, env, }) {
64
- const { source, content, lastUpdate, contentPath, filePath } = docFile;
71
+ async function doProcessDocMetadata({ docFile, versionMetadata, context, options, env, }) {
72
+ const { source, content, contentPath, filePath } = docFile;
65
73
  const { siteDir, i18n } = context;
66
74
  const { frontMatter: unsafeFrontMatter, contentTitle, excerpt, } = (0, utils_1.parseMarkdownString)(content);
67
75
  const frontMatter = (0, frontMatter_1.validateDocFrontMatter)(unsafeFrontMatter);
@@ -69,7 +77,8 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, env,
69
77
  // Strip number prefixes by default
70
78
  // (01-MyFolder/01-MyDoc.md => MyFolder/MyDoc)
71
79
  // but allow to disable this behavior with front matter
72
- parse_number_prefixes: parseNumberPrefixes = true, } = frontMatter;
80
+ parse_number_prefixes: parseNumberPrefixes = true, last_update: lastUpdateFrontMatter, } = frontMatter;
81
+ const lastUpdate = await readLastUpdateData(filePath, options, lastUpdateFrontMatter);
73
82
  // E.g. api/plugins/myDoc -> myDoc; myDoc -> myDoc
74
83
  const sourceFileNameWithoutExtension = path_1.default.basename(source, path_1.default.extname(source));
75
84
  // E.g. api/plugins/myDoc -> api/plugins; myDoc -> .
@@ -142,6 +151,21 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, env,
142
151
  return undefined;
143
152
  }
144
153
  const draft = isDraftForEnvironment({ env, frontMatter });
154
+ const formatDate = (locale, date, calendar) => {
155
+ try {
156
+ return new Intl.DateTimeFormat(locale, {
157
+ day: 'numeric',
158
+ month: 'short',
159
+ year: 'numeric',
160
+ timeZone: 'UTC',
161
+ calendar,
162
+ }).format(date);
163
+ }
164
+ catch (err) {
165
+ logger_1.default.error `Can't format docs lastUpdatedAt date "${String(date)}"`;
166
+ throw err;
167
+ }
168
+ };
145
169
  // Assign all of object properties during instantiation (if possible) for
146
170
  // NodeJS optimization.
147
171
  // Adding properties to object after instantiation will cause hidden
@@ -162,9 +186,7 @@ function doProcessDocMetadata({ docFile, versionMetadata, context, options, env,
162
186
  lastUpdatedBy: lastUpdate.lastUpdatedBy,
163
187
  lastUpdatedAt: lastUpdate.lastUpdatedAt,
164
188
  formattedLastUpdatedAt: lastUpdate.lastUpdatedAt
165
- ? new Intl.DateTimeFormat(i18n.currentLocale, {
166
- calendar: i18n.localeConfigs[i18n.currentLocale].calendar,
167
- }).format(lastUpdate.lastUpdatedAt * 1000)
189
+ ? formatDate(i18n.currentLocale, new Date(lastUpdate.lastUpdatedAt * 1000), i18n.localeConfigs[i18n.currentLocale].calendar)
168
190
  : undefined,
169
191
  sidebarPosition,
170
192
  frontMatter,
@@ -8,6 +8,7 @@
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.validateDocFrontMatter = void 0;
10
10
  const utils_validation_1 = require("@docusaurus/utils-validation");
11
+ const FrontMatterLastUpdateErrorMessage = '{{#label}} does not look like a valid front matter FileChange object. Please use a FileChange object (with an author and/or date).';
11
12
  // NOTE: we don't add any default value on purpose here
12
13
  // We don't want default values to magically appear in doc metadata and props
13
14
  // While the user did not provide those values explicitly
@@ -36,6 +37,15 @@ const DocFrontMatterSchema = utils_validation_1.JoiFrontMatter.object({
36
37
  pagination_prev: utils_validation_1.JoiFrontMatter.string().allow(null),
37
38
  draft: utils_validation_1.JoiFrontMatter.boolean(),
38
39
  ...utils_validation_1.FrontMatterTOCHeadingLevels,
40
+ last_update: utils_validation_1.JoiFrontMatter.object({
41
+ author: utils_validation_1.JoiFrontMatter.string(),
42
+ date: utils_validation_1.JoiFrontMatter.date().raw(),
43
+ })
44
+ .or('author', 'date')
45
+ .messages({
46
+ 'object.missing': FrontMatterLastUpdateErrorMessage,
47
+ 'object.base': FrontMatterLastUpdateErrorMessage,
48
+ }),
39
49
  }).unknown();
40
50
  function validateDocFrontMatter(frontMatter) {
41
51
  return (0, utils_validation_1.validateFrontMatter)(frontMatter, DocFrontMatterSchema);
package/lib/index.js CHANGED
@@ -50,9 +50,7 @@ async function pluginContentDocs(context, options) {
50
50
  .command(command)
51
51
  .arguments('<version>')
52
52
  .description(commandDescription)
53
- .action((version) => {
54
- (0, cli_1.cliDocsVersionCommand)(version, options, context);
55
- });
53
+ .action((version) => (0, cli_1.cliDocsVersionCommand)(version, options, context));
56
54
  },
57
55
  getTranslationFiles({ content }) {
58
56
  return (0, translations_1.getLoadedContentTranslationFiles)(content);
@@ -212,10 +210,7 @@ async function pluginContentDocs(context, options) {
212
210
  sourceToPermalink: getSourceToPermalink(),
213
211
  versionsMetadata,
214
212
  onBrokenMarkdownLink: (brokenMarkdownLink) => {
215
- if (siteConfig.onBrokenMarkdownLinks === 'ignore') {
216
- return;
217
- }
218
- (0, utils_1.reportMessage)(`Docs markdown link couldn't be resolved: (${brokenMarkdownLink.link}) in ${brokenMarkdownLink.filePath} for version ${brokenMarkdownLink.contentPaths.versionName}`, siteConfig.onBrokenMarkdownLinks);
213
+ logger_1.default.report(siteConfig.onBrokenMarkdownLinks) `Docs markdown link couldn't be resolved: (url=${brokenMarkdownLink.link}) in path=${brokenMarkdownLink.filePath} for version number=${brokenMarkdownLink.contentPaths.versionName}`;
219
214
  },
220
215
  };
221
216
  function createMDXLoaderRule() {
@@ -230,6 +225,7 @@ async function pluginContentDocs(context, options) {
230
225
  {
231
226
  loader: require.resolve('@docusaurus/mdx-loader'),
232
227
  options: {
228
+ admonitions: options.admonitions,
233
229
  remarkPlugins,
234
230
  rehypePlugins,
235
231
  beforeDefaultRehypePlugins,
@@ -4,7 +4,7 @@
4
4
  * This source code is licensed under the MIT license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
- export declare function getFileLastUpdate(filePath?: string): Promise<{
7
+ export declare function getFileLastUpdate(filePath: string): Promise<{
8
8
  timestamp: number;
9
9
  author: string;
10
10
  } | null>;
package/lib/options.js CHANGED
@@ -11,7 +11,6 @@ const tslib_1 = require("tslib");
11
11
  const logger_1 = tslib_1.__importDefault(require("@docusaurus/logger"));
12
12
  const utils_validation_1 = require("@docusaurus/utils-validation");
13
13
  const utils_1 = require("@docusaurus/utils");
14
- const remark_admonitions_1 = tslib_1.__importDefault(require("remark-admonitions"));
15
14
  const generator_1 = require("./sidebars/generator");
16
15
  const numberPrefix_1 = require("./numberPrefix");
17
16
  exports.DEFAULT_OPTIONS = {
@@ -33,7 +32,7 @@ exports.DEFAULT_OPTIONS = {
33
32
  beforeDefaultRehypePlugins: [],
34
33
  showLastUpdateTime: false,
35
34
  showLastUpdateAuthor: false,
36
- admonitions: {},
35
+ admonitions: true,
37
36
  includeCurrentVersion: true,
38
37
  disableVersioning: false,
39
38
  lastVersion: undefined,
@@ -90,9 +89,7 @@ const OptionsSchema = utils_validation_1.Joi.object({
90
89
  rehypePlugins: utils_validation_1.RehypePluginsSchema.default(exports.DEFAULT_OPTIONS.rehypePlugins),
91
90
  beforeDefaultRemarkPlugins: utils_validation_1.RemarkPluginsSchema.default(exports.DEFAULT_OPTIONS.beforeDefaultRemarkPlugins),
92
91
  beforeDefaultRehypePlugins: utils_validation_1.RehypePluginsSchema.default(exports.DEFAULT_OPTIONS.beforeDefaultRehypePlugins),
93
- admonitions: utils_validation_1.Joi.alternatives()
94
- .try(utils_validation_1.AdmonitionsSchema, utils_validation_1.Joi.boolean().invalid(true))
95
- .default(exports.DEFAULT_OPTIONS.admonitions),
92
+ admonitions: utils_validation_1.AdmonitionsSchema.default(exports.DEFAULT_OPTIONS.admonitions),
96
93
  showLastUpdateTime: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.showLastUpdateTime),
97
94
  showLastUpdateAuthor: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.showLastUpdateAuthor),
98
95
  includeCurrentVersion: utils_validation_1.Joi.bool().default(exports.DEFAULT_OPTIONS.includeCurrentVersion),
@@ -123,11 +120,6 @@ function validateOptions({ validate, options: userOptions, }) {
123
120
  }
124
121
  }
125
122
  const normalizedOptions = validate(OptionsSchema, options);
126
- if (normalizedOptions.admonitions) {
127
- normalizedOptions.remarkPlugins = normalizedOptions.remarkPlugins.concat([
128
- [remark_admonitions_1.default, normalizedOptions.admonitions],
129
- ]);
130
- }
131
123
  return normalizedOptions;
132
124
  }
133
125
  exports.validateOptions = validateOptions;
package/lib/props.js CHANGED
@@ -43,10 +43,24 @@ Available document ids are:
43
43
  return undefined;
44
44
  }
45
45
  }
46
+ function getCategoryLinkCustomProps(link) {
47
+ switch (link?.type) {
48
+ case 'doc':
49
+ return getDocById(link.id).frontMatter.sidebar_custom_props;
50
+ default:
51
+ return undefined;
52
+ }
53
+ }
46
54
  function convertCategory(item) {
47
55
  const { link, ...rest } = item;
48
56
  const href = getCategoryLinkHref(link);
49
- return { ...rest, items: item.items.map(normalizeItem), ...(href && { href }) };
57
+ const customProps = item.customProps ?? getCategoryLinkCustomProps(link);
58
+ return {
59
+ ...rest,
60
+ items: item.items.map(normalizeItem),
61
+ ...(href && { href }),
62
+ ...(customProps && { customProps }),
63
+ };
50
64
  }
51
65
  function normalizeItem(item) {
52
66
  switch (item.type) {
@@ -30,6 +30,10 @@ function normalizeItem(item) {
30
30
  // This will never throw anyways
31
31
  return normalizeSidebar(item, 'sidebar items slice');
32
32
  }
33
+ if ((item.type === 'doc' || item.type === 'ref') &&
34
+ typeof item.label === 'string') {
35
+ return [{ ...item, translatable: true }];
36
+ }
33
37
  if (item.type === 'category') {
34
38
  const normalizedCategory = {
35
39
  ...item,
@@ -22,6 +22,11 @@ export declare type SidebarItemDoc = SidebarItemBase & {
22
22
  type: 'doc' | 'ref';
23
23
  label?: string;
24
24
  id: string;
25
+ /**
26
+ * This is an internal marker. Items with labels defined in the config needs
27
+ * to be translated with JSON
28
+ */
29
+ translatable?: true;
25
30
  };
26
31
  export declare type SidebarItemHtml = SidebarItemBase & {
27
32
  type: 'html';
@@ -73,7 +78,7 @@ export declare type SidebarItemCategoryConfig = Expand<Optional<SidebarItemCateg
73
78
  export declare type SidebarCategoriesShorthand = {
74
79
  [sidebarCategory: string]: SidebarCategoriesShorthand | SidebarItemConfig[];
75
80
  };
76
- export declare type SidebarItemConfig = SidebarItemDoc | SidebarItemHtml | SidebarItemLink | SidebarItemAutogenerated | SidebarItemCategoryConfig | string | SidebarCategoriesShorthand;
81
+ export declare type SidebarItemConfig = Omit<SidebarItemDoc, 'translatable'> | SidebarItemHtml | SidebarItemLink | SidebarItemAutogenerated | SidebarItemCategoryConfig | string | SidebarCategoriesShorthand;
77
82
  export declare type SidebarConfig = SidebarCategoriesShorthand | SidebarItemConfig[];
78
83
  export declare type SidebarsConfig = {
79
84
  [sidebarId: string]: SidebarConfig;
@@ -11,6 +11,7 @@ export declare function transformSidebarItems(sidebar: Sidebar, updateFn: (item:
11
11
  export declare function collectSidebarDocItems(sidebar: Sidebar): SidebarItemDoc[];
12
12
  export declare function collectSidebarCategories(sidebar: Sidebar): SidebarItemCategory[];
13
13
  export declare function collectSidebarLinks(sidebar: Sidebar): SidebarItemLink[];
14
+ export declare function collectSidebarRefs(sidebar: Sidebar): SidebarItemDoc[];
14
15
  export declare function collectSidebarDocIds(sidebar: Sidebar): string[];
15
16
  export declare function collectSidebarNavigation(sidebar: Sidebar): SidebarNavigationItem[];
16
17
  export declare function collectSidebarsDocIds(sidebars: Sidebars): {
@@ -6,7 +6,7 @@
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.toNavigationLink = exports.toDocNavigationLink = exports.createSidebarsUtils = exports.collectSidebarsNavigations = exports.collectSidebarsDocIds = exports.collectSidebarNavigation = exports.collectSidebarDocIds = exports.collectSidebarLinks = exports.collectSidebarCategories = exports.collectSidebarDocItems = exports.transformSidebarItems = exports.isCategoriesShorthand = void 0;
9
+ exports.toNavigationLink = exports.toDocNavigationLink = exports.createSidebarsUtils = exports.collectSidebarsNavigations = exports.collectSidebarsDocIds = exports.collectSidebarNavigation = exports.collectSidebarDocIds = exports.collectSidebarRefs = exports.collectSidebarLinks = exports.collectSidebarCategories = exports.collectSidebarDocItems = exports.transformSidebarItems = exports.isCategoriesShorthand = void 0;
10
10
  const tslib_1 = require("tslib");
11
11
  const lodash_1 = tslib_1.__importDefault(require("lodash"));
12
12
  const utils_1 = require("@docusaurus/utils");
@@ -55,6 +55,10 @@ function collectSidebarLinks(sidebar) {
55
55
  return collectSidebarItemsOfType('link', sidebar);
56
56
  }
57
57
  exports.collectSidebarLinks = collectSidebarLinks;
58
+ function collectSidebarRefs(sidebar) {
59
+ return collectSidebarItemsOfType('ref', sidebar);
60
+ }
61
+ exports.collectSidebarRefs = collectSidebarRefs;
58
62
  // /!\ docId order matters for navigation!
59
63
  function collectSidebarDocIds(sidebar) {
60
64
  return flattenSidebarItems(sidebar).flatMap((item) => {
@@ -26,6 +26,7 @@ const sidebarItemDocSchema = sidebarItemBaseSchema.append({
26
26
  type: utils_validation_1.Joi.string().valid('doc', 'ref').required(),
27
27
  id: utils_validation_1.Joi.string().required(),
28
28
  label: utils_validation_1.Joi.string(),
29
+ translatable: utils_validation_1.Joi.boolean(),
29
30
  });
30
31
  const sidebarItemHtmlSchema = sidebarItemBaseSchema.append({
31
32
  type: 'html',
@@ -71,7 +71,17 @@ function getSidebarTranslationFileContent(sidebar, sidebarName) {
71
71
  description: `The label for link ${link.label} in sidebar ${sidebarName}, linking to ${link.href}`,
72
72
  },
73
73
  ]));
74
- return (0, utils_1.mergeTranslations)([categoryContent, linksContent]);
74
+ const docs = (0, utils_2.collectSidebarDocItems)(sidebar)
75
+ .concat((0, utils_2.collectSidebarRefs)(sidebar))
76
+ .filter((item) => item.translatable);
77
+ const docLinksContent = Object.fromEntries(docs.map((doc) => [
78
+ `sidebar.${sidebarName}.doc.${doc.label}`,
79
+ {
80
+ message: doc.label,
81
+ description: `The label for the doc item ${doc.label} in sidebar ${sidebarName}, linking to the doc ${doc.id}`,
82
+ },
83
+ ]));
84
+ return (0, utils_1.mergeTranslations)([categoryContent, linksContent, docLinksContent]);
75
85
  }
76
86
  function translateSidebar({ sidebar, sidebarName, sidebarsTranslations, }) {
77
87
  function transformSidebarCategoryLink(category) {
@@ -106,6 +116,13 @@ function translateSidebar({ sidebar, sidebarName, sidebarsTranslations, }) {
106
116
  ?.message ?? item.label,
107
117
  };
108
118
  }
119
+ if ((item.type === 'doc' || item.type === 'ref') && item.translatable) {
120
+ return {
121
+ ...item,
122
+ label: sidebarsTranslations[`sidebar.${sidebarName}.doc.${item.label}`]
123
+ ?.message ?? item.label,
124
+ };
125
+ }
109
126
  return item;
110
127
  });
111
128
  }
package/lib/types.d.ts CHANGED
@@ -5,14 +5,13 @@
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
7
  import type { BrokenMarkdownLink, Tag } from '@docusaurus/utils';
8
- import type { VersionMetadata, LastUpdateData, LoadedVersion, CategoryGeneratedIndexMetadata } from '@docusaurus/plugin-content-docs';
8
+ import type { VersionMetadata, LoadedVersion, CategoryGeneratedIndexMetadata } from '@docusaurus/plugin-content-docs';
9
9
  import type { SidebarsUtils } from './sidebars/utils';
10
10
  export declare type DocFile = {
11
11
  contentPath: string;
12
12
  filePath: string;
13
13
  source: string;
14
14
  content: string;
15
- lastUpdate: LastUpdateData;
16
15
  };
17
16
  export declare type SourceToPermalink = {
18
17
  [source: string]: string;
@@ -10,9 +10,8 @@ import type { VersionContext } from './index';
10
10
  export declare function getVersionDocsDirPath(siteDir: string, pluginId: string, versionName: string): string;
11
11
  /** `[siteDir]/community_versioned_sidebars/version-1.0.0-sidebars.json` */
12
12
  export declare function getVersionSidebarsPath(siteDir: string, pluginId: string, versionName: string): string;
13
- export declare function getDocsDirPathLocalized({ siteDir, locale, pluginId, versionName, }: {
14
- siteDir: string;
15
- locale: string;
13
+ export declare function getDocsDirPathLocalized({ localizationDir, pluginId, versionName, }: {
14
+ localizationDir: string;
16
15
  pluginId: string;
17
16
  versionName: string;
18
17
  }): string;
@@ -29,10 +29,9 @@ function getVersionSidebarsPath(siteDir, pluginId, versionName) {
29
29
  return path_1.default.join(siteDir, addPluginIdPrefix(constants_1.VERSIONED_SIDEBARS_DIR, pluginId), `version-${versionName}-sidebars.json`);
30
30
  }
31
31
  exports.getVersionSidebarsPath = getVersionSidebarsPath;
32
- function getDocsDirPathLocalized({ siteDir, locale, pluginId, versionName, }) {
32
+ function getDocsDirPathLocalized({ localizationDir, pluginId, versionName, }) {
33
33
  return (0, utils_1.getPluginI18nPath)({
34
- siteDir,
35
- locale,
34
+ localizationDir,
36
35
  pluginName: 'docusaurus-plugin-content-docs',
37
36
  pluginId,
38
37
  subPaths: [
@@ -110,8 +109,7 @@ exports.readVersionNames = readVersionNames;
110
109
  async function getVersionMetadataPaths({ versionName, context, options, }) {
111
110
  const isCurrent = versionName === constants_1.CURRENT_VERSION_NAME;
112
111
  const contentPathLocalized = getDocsDirPathLocalized({
113
- siteDir: context.siteDir,
114
- locale: context.i18n.currentLocale,
112
+ localizationDir: context.localizationDir,
115
113
  pluginId: options.id,
116
114
  versionName,
117
115
  });
@@ -22,8 +22,7 @@ function getVersionEditUrls({ contentPath, contentPathLocalized, context, option
22
22
  const editDirPath = options.editCurrentVersion ? options.path : contentPath;
23
23
  const editDirPathLocalized = options.editCurrentVersion
24
24
  ? (0, files_1.getDocsDirPathLocalized)({
25
- siteDir: context.siteDir,
26
- locale: context.i18n.currentLocale,
25
+ localizationDir: context.localizationDir,
27
26
  versionName: constants_1.CURRENT_VERSION_NAME,
28
27
  pluginId: options.id,
29
28
  })