feat(docs,blog,pages): add support for "unlisted" front matter - hide md content in production (#8004)

Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com>
This commit is contained in:
Jody Heavener 2022-11-03 06:31:41 -07:00 committed by GitHub
parent 7a023a2c41
commit 683ba3d2a0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
131 changed files with 2449 additions and 303 deletions

View file

@ -0,0 +1,5 @@
---
unlisted: true
---
This is an unlisted document

View file

@ -1,5 +1,6 @@
---
custom_edit_url: null
pagination_next: doc-unlisted
---
Lorem ipsum.

View file

@ -0,0 +1,6 @@
---
id: unlisted-category-index
unlisted: true
---
This is an unlisted category index

View file

@ -0,0 +1,6 @@
---
id: unlisted-category-doc
unlisted: true
---
This is an unlisted category doc

View file

@ -4,7 +4,16 @@
{
"type": "category",
"label": "foo",
"items": ["foo/bar", "foo/baz"]
"items": ["foo/bar", "doc-unlisted", "foo/baz"]
},
{
"type": "category",
"label": "Unlisted category",
"link": {
"type": "doc",
"id": "unlisted-category/unlisted-category-index"
},
"items": ["unlisted-category/unlisted-category-doc"]
},
{
"type": "category",

View file

@ -10,11 +10,23 @@ exports[`docsVersion first time versioning 1`] = `
{
"items": [
"foo/bar",
"doc-unlisted",
"foo/baz",
],
"label": "foo",
"type": "category",
},
{
"items": [
"unlisted-category/unlisted-category-doc",
],
"label": "Unlisted category",
"link": {
"id": "unlisted-category/unlisted-category-index",
"type": "doc",
},
"type": "category",
},
{
"items": [
"rootAbsoluteSlug",

View file

@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`simple site custom pagination 1`] = `
exports[`simple site custom pagination - development 1`] = `
{
"pagination": [
{
@ -25,14 +25,25 @@ exports[`simple site custom pagination 1`] = `
{
"id": "doc-draft",
"next": {
"permalink": "/docs/foo/bar",
"title": "Bar",
"permalink": "/docs/doc-unlisted",
"title": "doc-unlisted",
},
"prev": {
"permalink": "/docs/doc with space",
"title": "Hoo hoo, if this path tricks you...",
},
},
{
"id": "doc-unlisted",
"next": {
"permalink": "/docs/foo/bar",
"title": "Bar",
},
"prev": {
"permalink": "/docs/doc-draft",
"title": "doc-draft",
},
},
{
"id": "foo/bar",
"next": undefined,
@ -74,9 +85,356 @@ exports[`simple site custom pagination 1`] = `
{
"id": "ipsum",
"next": {
"permalink": "/docs/doc-unlisted",
"title": "doc-unlisted",
},
"prev": {
"permalink": "/docs/",
"title": "Hello sidebar_label",
},
},
{
"id": "lastUpdateAuthorOnly",
"next": {
"permalink": "/docs/lastUpdateDateOnly",
"title": "Last Update Date Only",
},
"prev": {
"permalink": "/docs/ipsum",
"title": "ipsum",
},
},
{
"id": "lastUpdateDateOnly",
"next": {
"permalink": "/docs/lorem",
"title": "lorem",
},
"prev": {
"permalink": "/docs/lastUpdateAuthorOnly",
"title": "Last Update Author Only",
},
},
{
"id": "lorem",
"next": {
"permalink": "/docs/rootAbsoluteSlug",
"title": "rootAbsoluteSlug",
},
"prev": {
"permalink": "/docs/lastUpdateDateOnly",
"title": "Last Update Date Only",
},
},
{
"id": "rootAbsoluteSlug",
"next": {
"permalink": "/docs/headingAsTitle",
"title": "My heading as title",
},
"prev": {
"permalink": "/docs/foo/bazSlug.html",
"title": "baz pagination_label",
},
},
{
"id": "rootRelativeSlug",
"next": {
"permalink": "/docs/headingAsTitle",
"title": "My heading as title",
},
"prev": {
"permalink": "/docs/foo/bazSlug.html",
"title": "baz pagination_label",
},
},
{
"id": "rootResolvedSlug",
"next": {
"permalink": "/docs/headingAsTitle",
"title": "My heading as title",
},
"prev": {
"permalink": "/docs/foo/bazSlug.html",
"title": "baz pagination_label",
},
},
{
"id": "rootTryToEscapeSlug",
"next": {
"permalink": "/docs/headingAsTitle",
"title": "My heading as title",
},
"prev": {
"permalink": "/docs/foo/bazSlug.html",
"title": "baz pagination_label",
},
},
{
"id": "slugs/absoluteSlug",
"next": {
"permalink": "/docs/slugs/relativeSlug",
"title": "relativeSlug",
},
"prev": {
"permalink": "/docs/rootTryToEscapeSlug",
"title": "rootTryToEscapeSlug",
},
},
{
"id": "slugs/relativeSlug",
"next": {
"permalink": "/docs/slugs/hey/resolvedSlug",
"title": "resolvedSlug",
},
"prev": {
"permalink": "/docs/absoluteSlug",
"title": "absoluteSlug",
},
},
{
"id": "slugs/resolvedSlug",
"next": {
"permalink": "/docs/tryToEscapeSlug",
"title": "tryToEscapeSlug",
},
"prev": {
"permalink": "/docs/slugs/relativeSlug",
"title": "relativeSlug",
},
},
{
"id": "slugs/tryToEscapeSlug",
"next": {
"permalink": "/docs/unlisted-category/",
"title": "unlisted-category-index",
},
"prev": {
"permalink": "/docs/slugs/hey/resolvedSlug",
"title": "resolvedSlug",
},
},
{
"id": "unlisted-category/unlisted-category-doc",
"next": undefined,
"prev": {
"permalink": "/docs/unlisted-category/",
"title": "unlisted-category-index",
},
},
{
"id": "unlisted-category/unlisted-category-index",
"next": {
"permalink": "/docs/unlisted-category/unlisted-category-doc",
"title": "unlisted-category-doc",
},
"prev": {
"permalink": "/docs/tryToEscapeSlug",
"title": "tryToEscapeSlug",
},
},
],
"sidebars": {
"defaultSidebar": [
{
"id": "customLastUpdate",
"type": "doc",
},
{
"id": "doc with space",
"type": "doc",
},
{
"id": "doc-draft",
"type": "doc",
},
{
"id": "doc-unlisted",
"type": "doc",
},
{
"collapsed": false,
"collapsible": true,
"items": [
{
"id": "foo/bar",
"type": "doc",
},
{
"id": "foo/baz",
"type": "doc",
},
],
"label": "foo",
"link": undefined,
"type": "category",
},
{
"id": "headingAsTitle",
"type": "doc",
},
{
"id": "hello",
"label": "Hello sidebar_label",
"type": "doc",
},
{
"id": "ipsum",
"type": "doc",
},
{
"id": "lastUpdateAuthorOnly",
"type": "doc",
},
{
"id": "lastUpdateDateOnly",
"type": "doc",
},
{
"id": "lorem",
"type": "doc",
},
{
"id": "rootAbsoluteSlug",
"type": "doc",
},
{
"id": "rootRelativeSlug",
"type": "doc",
},
{
"id": "rootResolvedSlug",
"type": "doc",
},
{
"id": "rootTryToEscapeSlug",
"type": "doc",
},
{
"collapsed": false,
"collapsible": true,
"items": [
{
"id": "slugs/absoluteSlug",
"type": "doc",
},
{
"id": "slugs/relativeSlug",
"type": "doc",
},
{
"id": "slugs/resolvedSlug",
"type": "doc",
},
{
"id": "slugs/tryToEscapeSlug",
"type": "doc",
},
],
"label": "slugs",
"link": undefined,
"type": "category",
},
{
"collapsed": false,
"collapsible": true,
"items": [
{
"id": "unlisted-category/unlisted-category-doc",
"type": "doc",
},
],
"label": "unlisted-category-index",
"link": {
"id": "unlisted-category/unlisted-category-index",
"type": "doc",
},
"type": "category",
},
],
},
}
`;
exports[`simple site custom pagination - production 1`] = `
{
"pagination": [
{
"id": "customLastUpdate",
"next": {
"permalink": "/docs/doc with space",
"title": "Hoo hoo, if this path tricks you...",
},
"prev": undefined,
},
{
"id": "doc with space",
"next": {
"permalink": "/docs/doc-draft",
"title": "doc-draft",
},
"prev": {
"permalink": "/docs/customLastUpdate",
"title": "Custom Last Update",
},
},
{
"id": "doc-draft",
"next": {
"permalink": "/docs/foo/bar",
"title": "Bar",
},
"prev": {
"permalink": "/docs/doc with space",
"title": "Hoo hoo, if this path tricks you...",
},
},
{
"id": "doc-unlisted",
"next": undefined,
"prev": undefined,
},
{
"id": "foo/bar",
"next": undefined,
"prev": undefined,
},
{
"id": "foo/baz",
"next": {
"permalink": "/docs/headingAsTitle",
"title": "My heading as title",
},
"prev": {
"permalink": "/docs/foo/bar",
"title": "Bar",
},
},
{
"id": "headingAsTitle",
"next": {
"permalink": "/docs/",
"title": "Hello sidebar_label",
},
"prev": {
"permalink": "/docs/foo/bazSlug.html",
"title": "baz pagination_label",
},
},
{
"id": "hello",
"next": {
"permalink": "/docs/ipsum",
"title": "ipsum",
},
"prev": {
"permalink": "/docs/headingAsTitle",
"title": "My heading as title",
},
},
{
"id": "ipsum",
"next": undefined,
"prev": {
"permalink": "/docs/",
"title": "Hello sidebar_label",
@ -200,6 +558,16 @@ exports[`simple site custom pagination 1`] = `
"title": "resolvedSlug",
},
},
{
"id": "unlisted-category/unlisted-category-doc",
"next": undefined,
"prev": undefined,
},
{
"id": "unlisted-category/unlisted-category-index",
"next": undefined,
"prev": undefined,
},
],
"sidebars": {
"defaultSidebar": [
@ -215,6 +583,10 @@ exports[`simple site custom pagination 1`] = `
"id": "doc-draft",
"type": "doc",
},
{
"id": "doc-unlisted",
"type": "doc",
},
{
"collapsed": false,
"collapsible": true,
@ -298,6 +670,22 @@ exports[`simple site custom pagination 1`] = `
"link": undefined,
"type": "category",
},
{
"collapsed": false,
"collapsible": true,
"items": [
{
"id": "unlisted-category/unlisted-category-doc",
"type": "doc",
},
],
"label": "unlisted-category-index",
"link": {
"id": "unlisted-category/unlisted-category-index",
"type": "doc",
},
"type": "category",
},
],
},
}

View file

@ -13,6 +13,12 @@ exports[`toGlobalDataVersion generates the right docs, sidebars, and metadata 1`
"path": "/current/doc",
"sidebar": "tutorial",
},
{
"id": "docNoSidebarUnlisted",
"path": "/current/docNoSidebarUnlisted",
"sidebar": undefined,
"unlisted": true,
},
{
"id": "/current/generated",
"path": "/current/generated",

View file

@ -153,7 +153,7 @@ function createTestUtils({
versionMetadata,
context,
options,
env: 'production',
env,
}),
),
);
@ -173,11 +173,11 @@ function createTestUtils({
const sidebarsUtils = createSidebarsUtils(sidebars);
return {
pagination: addDocNavigation(
rawDocs,
pagination: addDocNavigation({
docs: rawDocs,
sidebarsUtils,
versionMetadata.sidebarFilePath as string,
).map((doc) => ({prev: doc.previous, next: doc.next, id: doc.id})),
sidebarFilePath: versionMetadata.sidebarFilePath as string,
}).map((doc) => ({prev: doc.previous, next: doc.next, id: doc.id})),
sidebars,
};
}
@ -247,6 +247,7 @@ describe('simple site', () => {
'headingAsTitle.md',
'doc with space.md',
'doc-draft.md',
'doc-unlisted.md',
'customLastUpdate.md',
'lastUpdateAuthorOnly.md',
'lastUpdateDateOnly.md',
@ -256,6 +257,8 @@ describe('simple site', () => {
'slugs/relativeSlug.md',
'slugs/resolvedSlug.md',
'slugs/tryToEscapeSlug.md',
'unlisted-category/index.md',
'unlisted-category/unlisted-category-doc.md',
].sort(),
);
});
@ -279,6 +282,7 @@ describe('simple site', () => {
pagination_prev: null,
},
tags: [],
unlisted: false,
});
await defaultTestUtils.testMeta(path.join('hello.md'), {
version: 'current',
@ -306,6 +310,7 @@ describe('simple site', () => {
permalink: '/docs/tags/tag-3',
},
],
unlisted: false,
});
});
@ -356,6 +361,7 @@ describe('simple site', () => {
permalink: '/docs/tags/tag2-custom-permalink',
},
],
unlisted: false,
});
});
@ -377,6 +383,7 @@ describe('simple site', () => {
unrelated_front_matter: "won't be part of metadata",
},
tags: [],
unlisted: false,
});
});
@ -430,6 +437,7 @@ describe('simple site', () => {
permalink: '/docs/tags/tag2-custom-permalink',
},
],
unlisted: false,
});
expect(editUrlFunction).toHaveBeenCalledTimes(1);
@ -476,6 +484,7 @@ describe('simple site', () => {
formattedLastUpdatedAt: 'Oct 14, 2018',
lastUpdatedBy: 'Author',
tags: [],
unlisted: false,
});
});
@ -501,6 +510,44 @@ describe('simple site', () => {
});
});
it('docs with unlisted frontmatter', async () => {
const {createTestUtilsPartial} = await loadSite();
const baseMeta = {
version: 'current',
id: 'doc-unlisted',
unversionedId: 'doc-unlisted',
sourceDirName: '.',
permalink: '/docs/doc-unlisted',
slug: '/doc-unlisted',
title: 'doc-unlisted',
description: 'This is an unlisted document',
frontMatter: {
unlisted: true,
},
sidebarPosition: undefined,
tags: [],
};
const testUtilsProd = createTestUtilsPartial({
env: 'production',
});
await testUtilsProd.testMeta('doc-unlisted.md', {
...baseMeta,
unlisted: true,
});
const testUtilsDev = createTestUtilsPartial({
env: 'development',
});
await testUtilsDev.testMeta('doc-unlisted.md', {
...baseMeta,
unlisted: false,
});
});
it('docs with last_update front matter', async () => {
const {siteDir, context, options, currentVersion, createTestUtilsPartial} =
await loadSite({
@ -538,6 +585,7 @@ describe('simple site', () => {
lastUpdatedBy: 'Custom Author',
sidebarPosition: undefined,
tags: [],
unlisted: false,
});
});
@ -577,6 +625,7 @@ describe('simple site', () => {
lastUpdatedBy: 'Custom Author',
sidebarPosition: undefined,
tags: [],
unlisted: false,
});
});
@ -616,6 +665,7 @@ describe('simple site', () => {
lastUpdatedBy: 'Author',
sidebarPosition: undefined,
tags: [],
unlisted: false,
});
});
@ -656,6 +706,7 @@ describe('simple site', () => {
lastUpdatedBy: undefined,
sidebarPosition: undefined,
tags: [],
unlisted: false,
});
});
@ -718,12 +769,20 @@ describe('simple site', () => {
);
});
it('custom pagination', async () => {
const {defaultTestUtils, options, versionsMetadata} = await loadSite();
it('custom pagination - production', async () => {
const {createTestUtilsPartial, options, versionsMetadata} =
await loadSite();
const testUtils = createTestUtilsPartial({env: 'production'});
const docs = await readVersionDocs(versionsMetadata[0]!, options);
await expect(
defaultTestUtils.generateNavigation(docs),
).resolves.toMatchSnapshot();
await expect(testUtils.generateNavigation(docs)).resolves.toMatchSnapshot();
});
it('custom pagination - development', async () => {
const {createTestUtilsPartial, options, versionsMetadata} =
await loadSite();
const testUtils = createTestUtilsPartial({env: 'development'});
const docs = await readVersionDocs(versionsMetadata[0]!, options);
await expect(testUtils.generateNavigation(docs)).resolves.toMatchSnapshot();
});
it('bad pagination', async () => {
@ -847,6 +906,7 @@ describe('versioned site', () => {
permalink: '/docs/next/tags/barTag-3-permalink',
},
],
unlisted: false,
});
await currentVersionTestUtils.testMeta(path.join('hello.md'), {
id: 'hello',
@ -861,6 +921,7 @@ describe('versioned site', () => {
slug: '/',
},
tags: [],
unlisted: false,
});
});
@ -878,6 +939,7 @@ describe('versioned site', () => {
frontMatter: {slug: 'barSlug'},
version: '1.0.0',
tags: [],
unlisted: false,
});
await version100TestUtils.testMeta(path.join('hello.md'), {
id: 'version-1.0.0/hello',
@ -894,6 +956,7 @@ describe('versioned site', () => {
source:
'@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md',
tags: [],
unlisted: false,
});
await version101TestUtils.testMeta(path.join('foo', 'bar.md'), {
id: 'version-1.0.1/foo/bar',
@ -906,6 +969,7 @@ describe('versioned site', () => {
version: '1.0.1',
frontMatter: {},
tags: [],
unlisted: false,
});
await version101TestUtils.testMeta(path.join('hello.md'), {
id: 'version-1.0.1/hello',
@ -920,6 +984,7 @@ describe('versioned site', () => {
slug: '/',
},
tags: [],
unlisted: false,
});
});
@ -1016,6 +1081,7 @@ describe('versioned site', () => {
'@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md',
editUrl: hardcodedEditUrl,
tags: [],
unlisted: false,
});
expect(editUrlFunction).toHaveBeenCalledTimes(1);
@ -1059,6 +1125,7 @@ describe('versioned site', () => {
editUrl:
'https://github.com/facebook/docusaurus/edit/main/website/versioned_docs/version-1.0.0/hello.md',
tags: [],
unlisted: false,
});
});
@ -1094,6 +1161,7 @@ describe('versioned site', () => {
editUrl:
'https://github.com/facebook/docusaurus/edit/main/website/docs/hello.md',
tags: [],
unlisted: false,
});
});
@ -1130,6 +1198,7 @@ describe('versioned site', () => {
editUrl:
'https://github.com/facebook/docusaurus/edit/main/website/i18n/fr/docusaurus-plugin-content-docs/version-1.0.0/hello.md',
tags: [],
unlisted: false,
});
});
@ -1167,6 +1236,7 @@ describe('versioned site', () => {
editUrl:
'https://github.com/facebook/docusaurus/edit/main/website/i18n/fr/docusaurus-plugin-content-docs/current/hello.md',
tags: [],
unlisted: false,
});
});
});

View file

@ -44,15 +44,12 @@ function testField(params: {
params.invalidFrontMatters?.forEach(([frontMatter, message]) => {
try {
validateDocFrontMatter(frontMatter);
// eslint-disable-next-line jest/no-jasmine-globals
fail(
new Error(
`Doc front matter is expected to be rejected, but was accepted successfully:\n ${JSON.stringify(
frontMatter,
null,
2,
)}`,
),
throw new Error(
`Doc front matter is expected to be rejected, but was accepted successfully:\n ${JSON.stringify(
frontMatter,
null,
2,
)}`,
);
} catch (err) {
// eslint-disable-next-line jest/no-conditional-expect
@ -397,6 +394,41 @@ describe('validateDocFrontMatter draft', () => {
});
});
describe('validateDocFrontMatter unlisted', () => {
testField({
prefix: 'unlisted',
validFrontMatters: [{unlisted: true}, {unlisted: false}],
convertibleFrontMatter: [
[{unlisted: 'true'}, {unlisted: true}],
[{unlisted: 'false'}, {unlisted: false}],
],
invalidFrontMatters: [
[{unlisted: 'yes'}, 'must be a boolean'],
[{unlisted: 'no'}, 'must be a boolean'],
[{unlisted: ''}, 'must be a boolean'],
],
});
});
describe('validateDocFrontMatter draft XOR unlisted', () => {
testField({
prefix: 'draft XOR unlisted',
validFrontMatters: [
{draft: false},
{unlisted: false},
{draft: false, unlisted: false},
{draft: true, unlisted: false},
{draft: false, unlisted: true},
],
invalidFrontMatters: [
[
{draft: true, unlisted: true},
"Can't be draft and unlisted at the same time.",
],
],
});
});
describe('validateDocFrontMatter last_update', () => {
testField({
prefix: 'last_update',

View file

@ -19,12 +19,21 @@ describe('toGlobalDataVersion', () => {
permalink: '/current/main',
sidebar: 'tutorial',
frontMatter: {},
unlisted: false,
},
{
unversionedId: 'doc',
permalink: '/current/doc',
sidebar: 'tutorial',
frontMatter: {},
unlisted: undefined,
},
{
unversionedId: 'docNoSidebarUnlisted',
permalink: '/current/docNoSidebarUnlisted',
sidebar: undefined,
frontMatter: {},
unlisted: true,
},
] as DocMetadata[];
const sidebars: Sidebars = {

View file

@ -5,7 +5,7 @@
* LICENSE file in the root directory of this source tree.
*/
import {toTagDocListProp} from '../props';
import {toSidebarDocItemLinkProp, toTagDocListProp} from '../props';
describe('toTagDocListProp', () => {
type Params = Parameters<typeof toTagDocListProp>[0];
@ -61,3 +61,74 @@ describe('toTagDocListProp', () => {
});
});
});
describe('toSidebarDocItemLinkProp', () => {
type Params = Parameters<typeof toSidebarDocItemLinkProp>[0];
type Result = ReturnType<typeof toSidebarDocItemLinkProp>;
type DocSidebarItem = Params['item'];
type Doc = Params['doc'];
const id = 'some-doc-id';
const unversionedId = 'some-unversioned-doc-id';
const item: DocSidebarItem = {
type: 'doc',
id,
label: 'doc sidebar item label',
};
const doc: Doc = {
id,
unversionedId,
title: 'doc title',
permalink: '/docPermalink',
frontMatter: {},
unlisted: false,
};
it('works', () => {
const result = toSidebarDocItemLinkProp({
item,
doc,
});
expect(result).toEqual({
type: 'link',
docId: unversionedId,
unlisted: false,
label: item.label,
autoAddBaseUrl: undefined,
className: undefined,
href: doc.permalink,
customProps: undefined,
} as Result);
});
it('uses unlisted from metadata and ignores frontMatter', () => {
expect(
toSidebarDocItemLinkProp({
item,
doc: {
...doc,
unlisted: true,
frontMatter: {
unlisted: false,
},
},
}).unlisted,
).toBe(true);
expect(
toSidebarDocItemLinkProp({
item,
doc: {
...doc,
unlisted: false,
frontMatter: {
unlisted: true,
},
},
}).unlisted,
).toBe(false);
});
});