feat(content-docs): draft docs excluded from build & sidebars (#6457)

Co-authored-by: sebastienlorber <lorber.sebastien@gmail.com>
Co-authored-by: Joshua Chen <sidachen2003@gmail.com>
This commit is contained in:
Jody Heavener 2022-04-13 13:02:05 -03:00 committed by GitHub
parent ee4c984bc7
commit 5fb0a2e274
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 396 additions and 58 deletions

View file

@ -0,0 +1,5 @@
---
draft: true
---
This is a draft document

View file

@ -5,11 +5,22 @@ exports[`simple site custom pagination 1`] = `
"pagination": [ "pagination": [
{ {
"id": "doc with space", "id": "doc with space",
"next": {
"permalink": "/docs/doc-draft",
"title": "doc-draft",
},
"prev": undefined,
},
{
"id": "doc-draft",
"next": { "next": {
"permalink": "/docs/foo/bar", "permalink": "/docs/foo/bar",
"title": "Bar", "title": "Bar",
}, },
"prev": undefined, "prev": {
"permalink": "/docs/doc with space",
"title": "Hoo hoo, if this path tricks you...",
},
}, },
{ {
"id": "foo/bar", "id": "foo/bar",
@ -163,6 +174,10 @@ exports[`simple site custom pagination 1`] = `
"id": "doc with space", "id": "doc with space",
"type": "doc", "type": "doc",
}, },
{
"id": "doc-draft",
"type": "doc",
},
{ {
"collapsed": false, "collapsed": false,
"collapsible": true, "collapsible": true,

View file

@ -19,6 +19,9 @@ exports[`toGlobalDataVersion generates the right docs, sidebars, and metadata 1`
"sidebar": "tutorial", "sidebar": "tutorial",
}, },
], ],
"draftIds": [
"some-draft-id",
],
"isLast": true, "isLast": true,
"label": "Label", "label": "Label",
"mainDocId": "main", "mainDocId": "main",

View file

@ -23,6 +23,7 @@ These sidebar document ids do not exist:
Available document ids are: Available document ids are:
- doc with space - doc with space
- doc-draft
- foo/bar - foo/bar
- foo/baz - foo/baz
- headingAsTitle - headingAsTitle
@ -42,6 +43,7 @@ Available document ids are:
exports[`simple website content 1`] = ` exports[`simple website content 1`] = `
{ {
"description": "Images", "description": "Images",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -94,6 +96,7 @@ exports[`simple website content 1`] = `
exports[`simple website content 2`] = ` exports[`simple website content 2`] = `
{ {
"description": "Hi, Endilie here :)", "description": "Hi, Endilie here :)",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -139,6 +142,7 @@ exports[`simple website content 2`] = `
exports[`simple website content 3`] = ` exports[`simple website content 3`] = `
{ {
"description": "This is custom description", "description": "This is custom description",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -268,6 +272,11 @@ exports[`simple website content 5`] = `
"path": "/docs/doc with space", "path": "/docs/doc with space",
"sidebar": undefined, "sidebar": undefined,
}, },
{
"id": "doc-draft",
"path": "/docs/doc-draft",
"sidebar": undefined,
},
{ {
"id": "foo/bar", "id": "foo/bar",
"path": "/docs/foo/bar", "path": "/docs/foo/bar",
@ -344,6 +353,7 @@ exports[`simple website content 5`] = `
"sidebar": "docs", "sidebar": "docs",
}, },
], ],
"draftIds": [],
"isLast": true, "isLast": true,
"label": "Next", "label": "Next",
"mainDocId": "hello", "mainDocId": "hello",
@ -380,6 +390,22 @@ exports[`simple website content: data 1`] = `
"permalink": "/docs/rootAbsoluteSlug" "permalink": "/docs/rootAbsoluteSlug"
} }
} }
}",
"site-docs-doc-draft-md-584.json": "{
"unversionedId": "doc-draft",
"id": "doc-draft",
"title": "doc-draft",
"description": "This is a draft document",
"source": "@site/docs/doc-draft.md",
"sourceDirName": ".",
"slug": "/doc-draft",
"permalink": "/docs/doc-draft",
"draft": false,
"tags": [],
"version": "current",
"frontMatter": {
"draft": true
}
}", }",
"site-docs-doc-with-space-md-e90.json": "{ "site-docs-doc-with-space-md-e90.json": "{
"unversionedId": "doc with space", "unversionedId": "doc with space",
@ -390,6 +416,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/doc with space", "slug": "/doc with space",
"permalink": "/docs/doc with space", "permalink": "/docs/doc with space",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": {} "frontMatter": {}
@ -403,6 +430,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": "foo", "sourceDirName": "foo",
"slug": "/foo/bar", "slug": "/foo/bar",
"permalink": "/docs/foo/bar", "permalink": "/docs/foo/bar",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -423,6 +451,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": "foo", "sourceDirName": "foo",
"slug": "/foo/bazSlug.html", "slug": "/foo/bazSlug.html",
"permalink": "/docs/foo/bazSlug.html", "permalink": "/docs/foo/bazSlug.html",
"draft": false,
"tags": [ "tags": [
{ {
"label": "tag 1", "label": "tag 1",
@ -467,6 +496,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/headingAsTitle", "slug": "/headingAsTitle",
"permalink": "/docs/headingAsTitle", "permalink": "/docs/headingAsTitle",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": {}, "frontMatter": {},
@ -489,6 +519,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/", "slug": "/",
"permalink": "/docs/", "permalink": "/docs/",
"draft": false,
"tags": [ "tags": [
{ {
"label": "tag-1", "label": "tag-1",
@ -525,6 +556,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/ipsum", "slug": "/ipsum",
"permalink": "/docs/ipsum", "permalink": "/docs/ipsum",
"draft": false,
"editUrl": null, "editUrl": null,
"tags": [], "tags": [],
"version": "current", "version": "current",
@ -541,6 +573,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/lorem", "slug": "/lorem",
"permalink": "/docs/lorem", "permalink": "/docs/lorem",
"draft": false,
"editUrl": "https://github.com/customUrl/docs/lorem.md", "editUrl": "https://github.com/customUrl/docs/lorem.md",
"tags": [], "tags": [],
"version": "current", "version": "current",
@ -558,6 +591,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/rootAbsoluteSlug", "slug": "/rootAbsoluteSlug",
"permalink": "/docs/rootAbsoluteSlug", "permalink": "/docs/rootAbsoluteSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -584,6 +618,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/rootRelativeSlug", "slug": "/rootRelativeSlug",
"permalink": "/docs/rootRelativeSlug", "permalink": "/docs/rootRelativeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -610,6 +645,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/hey/rootResolvedSlug", "slug": "/hey/rootResolvedSlug",
"permalink": "/docs/hey/rootResolvedSlug", "permalink": "/docs/hey/rootResolvedSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -636,6 +672,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/rootTryToEscapeSlug", "slug": "/rootTryToEscapeSlug",
"permalink": "/docs/rootTryToEscapeSlug", "permalink": "/docs/rootTryToEscapeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -662,6 +699,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/absoluteSlug", "slug": "/absoluteSlug",
"permalink": "/docs/absoluteSlug", "permalink": "/docs/absoluteSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -677,6 +715,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/slugs/relativeSlug", "slug": "/slugs/relativeSlug",
"permalink": "/docs/slugs/relativeSlug", "permalink": "/docs/slugs/relativeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -692,6 +731,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/slugs/hey/resolvedSlug", "slug": "/slugs/hey/resolvedSlug",
"permalink": "/docs/slugs/hey/resolvedSlug", "permalink": "/docs/slugs/hey/resolvedSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -707,6 +747,7 @@ exports[`simple website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/tryToEscapeSlug", "slug": "/tryToEscapeSlug",
"permalink": "/docs/tryToEscapeSlug", "permalink": "/docs/tryToEscapeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -888,6 +929,11 @@ exports[`simple website content: data 1`] = `
"title": "Hoo hoo, if this path tricks you...", "title": "Hoo hoo, if this path tricks you...",
"description": "" "description": ""
}, },
"doc-draft": {
"id": "doc-draft",
"title": "doc-draft",
"description": "This is a draft document"
},
"foo/bar": { "foo/bar": {
"id": "foo/bar", "id": "foo/bar",
"title": "Bar", "title": "Bar",
@ -985,6 +1031,11 @@ exports[`simple website content: global data 1`] = `
"path": "/docs/doc with space", "path": "/docs/doc with space",
"sidebar": undefined, "sidebar": undefined,
}, },
{
"id": "doc-draft",
"path": "/docs/doc-draft",
"sidebar": undefined,
},
{ {
"id": "foo/bar", "id": "foo/bar",
"path": "/docs/foo/bar", "path": "/docs/foo/bar",
@ -1061,6 +1112,7 @@ exports[`simple website content: global data 1`] = `
"sidebar": "docs", "sidebar": "docs",
}, },
], ],
"draftIds": [],
"isLast": true, "isLast": true,
"label": "Next", "label": "Next",
"mainDocId": "hello", "mainDocId": "hello",
@ -1158,6 +1210,14 @@ exports[`simple website content: route config 1`] = `
}, },
"path": "/docs/doc with space", "path": "/docs/doc with space",
}, },
{
"component": "@theme/DocItem",
"exact": true,
"modules": {
"content": "@site/docs/doc-draft.md",
},
"path": "/docs/doc-draft",
},
{ {
"component": "@theme/DocItem", "component": "@theme/DocItem",
"exact": true, "exact": true,
@ -1562,6 +1622,7 @@ exports[`site with custom sidebar items generator sidebarItemsGenerator is calle
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 1`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 1`] = `
{ {
"description": "Getting started text", "description": "Getting started text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -1589,6 +1650,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 2`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 2`] = `
{ {
"description": "Installation text", "description": "Installation text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -1619,6 +1681,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 3`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 3`] = `
{ {
"description": "Guide 1 text", "description": "Guide 1 text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -1652,6 +1715,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 4`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 4`] = `
{ {
"description": "Guide 2 text", "description": "Guide 2 text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -1684,6 +1748,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 5`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 5`] = `
{ {
"description": "Guide 2.5 text", "description": "Guide 2.5 text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -1717,6 +1782,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 6`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 6`] = `
{ {
"description": "Guide 3 text", "description": "Guide 3 text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -1750,6 +1816,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 7`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 7`] = `
{ {
"description": "Guide 4 text", "description": "Guide 4 text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -1782,6 +1849,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 8`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 8`] = `
{ {
"description": "Guide 5 text", "description": "Guide 5 text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -1814,6 +1882,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 9`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 9`] = `
{ {
"description": "API Overview text", "description": "API Overview text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -1844,6 +1913,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 10`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 10`] = `
{ {
"description": "Client API text", "description": "Client API text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -1874,6 +1944,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 11`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 11`] = `
{ {
"description": "Server API text", "description": "Server API text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -1904,6 +1975,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 12`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 12`] = `
{ {
"description": "Plugin API text", "description": "Plugin API text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -1934,6 +2006,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 13`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 13`] = `
{ {
"description": "Theme API text", "description": "Theme API text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -1964,6 +2037,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 14`] = ` exports[`site with full autogenerated sidebar docs in fully generated sidebar have correct metadata 14`] = `
{ {
"description": "API End text", "description": "API End text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2143,6 +2217,7 @@ exports[`site with partial autogenerated sidebars 2 (fix #4638) sidebar is parti
exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 1`] = ` exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 1`] = `
{ {
"description": "API End text", "description": "API End text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2170,6 +2245,7 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 2`] = ` exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 2`] = `
{ {
"description": "API Overview text", "description": "API Overview text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2200,6 +2276,7 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 3`] = ` exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 3`] = `
{ {
"description": "Plugin API text", "description": "Plugin API text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2230,6 +2307,7 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 4`] = ` exports[`site with partial autogenerated sidebars docs in partially generated sidebar have correct metadata 4`] = `
{ {
"description": "Theme API text", "description": "Theme API text",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2289,6 +2367,7 @@ exports[`site with partial autogenerated sidebars sidebar is partially autogener
exports[`versioned website (community) content 1`] = ` exports[`versioned website (community) content 1`] = `
{ {
"description": "Team current version (translated)", "description": "Team current version (translated)",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -2315,6 +2394,7 @@ exports[`versioned website (community) content 1`] = `
exports[`versioned website (community) content 2`] = ` exports[`versioned website (community) content 2`] = `
{ {
"description": "Team 1.0.0", "description": "Team 1.0.0",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2369,6 +2449,7 @@ exports[`versioned website (community) content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/team", "slug": "/team",
"permalink": "/community/team", "permalink": "/community/team",
"draft": false,
"tags": [], "tags": [],
"version": "1.0.0", "version": "1.0.0",
"frontMatter": {}, "frontMatter": {},
@ -2383,6 +2464,7 @@ exports[`versioned website (community) content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/team", "slug": "/team",
"permalink": "/community/next/team", "permalink": "/community/next/team",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -2462,6 +2544,7 @@ exports[`versioned website (community) content: global data 1`] = `
"sidebar": "community", "sidebar": "community",
}, },
], ],
"draftIds": [],
"isLast": false, "isLast": false,
"label": "Next", "label": "Next",
"mainDocId": "team", "mainDocId": "team",
@ -2484,6 +2567,7 @@ exports[`versioned website (community) content: global data 1`] = `
"sidebar": "version-1.0.0/community", "sidebar": "version-1.0.0/community",
}, },
], ],
"draftIds": [],
"isLast": true, "isLast": true,
"label": "1.0.0", "label": "1.0.0",
"mainDocId": "team", "mainDocId": "team",
@ -2565,6 +2649,7 @@ exports[`versioned website (community) getPathToWatch 1`] = `
exports[`versioned website content 1`] = ` exports[`versioned website content 1`] = `
{ {
"description": "This is next version of bar.", "description": "This is next version of bar.",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -2615,6 +2700,7 @@ exports[`versioned website content 1`] = `
exports[`versioned website content 2`] = ` exports[`versioned website content 2`] = `
{ {
"description": "Bar 1.0.1 !", "description": "Bar 1.0.1 !",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2642,6 +2728,7 @@ exports[`versioned website content 2`] = `
exports[`versioned website content 3`] = ` exports[`versioned website content 3`] = `
{ {
"description": "Hello next !", "description": "Hello next !",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -2671,6 +2758,7 @@ exports[`versioned website content 3`] = `
exports[`versioned website content 4`] = ` exports[`versioned website content 4`] = `
{ {
"description": "Hello 1.0.1 !", "description": "Hello 1.0.1 !",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": { "frontMatter": {
@ -2700,6 +2788,7 @@ exports[`versioned website content 4`] = `
exports[`versioned website content 5`] = ` exports[`versioned website content 5`] = `
{ {
"description": "Baz 1.0.0 ! This will be deleted in next subsequent versions.", "description": "Baz 1.0.0 ! This will be deleted in next subsequent versions.",
"draft": false,
"editUrl": undefined, "editUrl": undefined,
"formattedLastUpdatedAt": undefined, "formattedLastUpdatedAt": undefined,
"frontMatter": {}, "frontMatter": {},
@ -2841,6 +2930,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "foo", "sourceDirName": "foo",
"slug": "/foo/barSlug", "slug": "/foo/barSlug",
"permalink": "/docs/next/foo/barSlug", "permalink": "/docs/next/foo/barSlug",
"draft": false,
"tags": [ "tags": [
{ {
"label": "barTag 1", "label": "barTag 1",
@ -2882,6 +2972,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/", "slug": "/",
"permalink": "/docs/next/", "permalink": "/docs/next/",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -2902,6 +2993,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/absoluteSlug", "slug": "/absoluteSlug",
"permalink": "/docs/next/absoluteSlug", "permalink": "/docs/next/absoluteSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -2917,6 +3009,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/slugs/relativeSlug", "slug": "/slugs/relativeSlug",
"permalink": "/docs/next/slugs/relativeSlug", "permalink": "/docs/next/slugs/relativeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -2932,6 +3025,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/slugs/hey/resolvedSlug", "slug": "/slugs/hey/resolvedSlug",
"permalink": "/docs/next/slugs/hey/resolvedSlug", "permalink": "/docs/next/slugs/hey/resolvedSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -2947,6 +3041,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/tryToEscapeSlug", "slug": "/tryToEscapeSlug",
"permalink": "/docs/next/tryToEscapeSlug", "permalink": "/docs/next/tryToEscapeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "current", "version": "current",
"frontMatter": { "frontMatter": {
@ -2962,6 +3057,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/", "slug": "/",
"permalink": "/docs/1.0.0/", "permalink": "/docs/1.0.0/",
"draft": false,
"tags": [], "tags": [],
"version": "1.0.0", "version": "1.0.0",
"frontMatter": { "frontMatter": {
@ -2982,6 +3078,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "foo", "sourceDirName": "foo",
"slug": "/foo/barSlug", "slug": "/foo/barSlug",
"permalink": "/docs/1.0.0/foo/barSlug", "permalink": "/docs/1.0.0/foo/barSlug",
"draft": false,
"tags": [], "tags": [],
"version": "1.0.0", "version": "1.0.0",
"frontMatter": { "frontMatter": {
@ -3002,6 +3099,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "foo", "sourceDirName": "foo",
"slug": "/foo/baz", "slug": "/foo/baz",
"permalink": "/docs/1.0.0/foo/baz", "permalink": "/docs/1.0.0/foo/baz",
"draft": false,
"tags": [], "tags": [],
"version": "1.0.0", "version": "1.0.0",
"frontMatter": {}, "frontMatter": {},
@ -3024,6 +3122,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "foo", "sourceDirName": "foo",
"slug": "/foo/bar", "slug": "/foo/bar",
"permalink": "/docs/foo/bar", "permalink": "/docs/foo/bar",
"draft": false,
"tags": [], "tags": [],
"version": "1.0.1", "version": "1.0.1",
"frontMatter": {}, "frontMatter": {},
@ -3042,6 +3141,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/", "slug": "/",
"permalink": "/docs/", "permalink": "/docs/",
"draft": false,
"tags": [], "tags": [],
"version": "1.0.1", "version": "1.0.1",
"frontMatter": { "frontMatter": {
@ -3062,6 +3162,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/rootAbsoluteSlug", "slug": "/rootAbsoluteSlug",
"permalink": "/docs/withSlugs/rootAbsoluteSlug", "permalink": "/docs/withSlugs/rootAbsoluteSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3078,6 +3179,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/rootRelativeSlug", "slug": "/rootRelativeSlug",
"permalink": "/docs/withSlugs/rootRelativeSlug", "permalink": "/docs/withSlugs/rootRelativeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3093,6 +3195,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/hey/rootResolvedSlug", "slug": "/hey/rootResolvedSlug",
"permalink": "/docs/withSlugs/hey/rootResolvedSlug", "permalink": "/docs/withSlugs/hey/rootResolvedSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3108,6 +3211,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": ".", "sourceDirName": ".",
"slug": "/rootTryToEscapeSlug", "slug": "/rootTryToEscapeSlug",
"permalink": "/docs/withSlugs/rootTryToEscapeSlug", "permalink": "/docs/withSlugs/rootTryToEscapeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3123,6 +3227,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/absoluteSlug", "slug": "/absoluteSlug",
"permalink": "/docs/withSlugs/absoluteSlug", "permalink": "/docs/withSlugs/absoluteSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3138,6 +3243,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/slugs/relativeSlug", "slug": "/slugs/relativeSlug",
"permalink": "/docs/withSlugs/slugs/relativeSlug", "permalink": "/docs/withSlugs/slugs/relativeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3153,6 +3259,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/slugs/hey/resolvedSlug", "slug": "/slugs/hey/resolvedSlug",
"permalink": "/docs/withSlugs/slugs/hey/resolvedSlug", "permalink": "/docs/withSlugs/slugs/hey/resolvedSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3168,6 +3275,7 @@ exports[`versioned website content: data 1`] = `
"sourceDirName": "slugs", "sourceDirName": "slugs",
"slug": "/tryToEscapeSlug", "slug": "/tryToEscapeSlug",
"permalink": "/docs/withSlugs/tryToEscapeSlug", "permalink": "/docs/withSlugs/tryToEscapeSlug",
"draft": false,
"tags": [], "tags": [],
"version": "withSlugs", "version": "withSlugs",
"frontMatter": { "frontMatter": {
@ -3543,6 +3651,7 @@ exports[`versioned website content: global data 1`] = `
"sidebar": undefined, "sidebar": undefined,
}, },
], ],
"draftIds": [],
"isLast": false, "isLast": false,
"label": "Next", "label": "Next",
"mainDocId": "hello", "mainDocId": "hello",
@ -3570,6 +3679,7 @@ exports[`versioned website content: global data 1`] = `
"sidebar": "VersionedSideBarNameDoesNotMatter/docs", "sidebar": "VersionedSideBarNameDoesNotMatter/docs",
}, },
], ],
"draftIds": [],
"isLast": true, "isLast": true,
"label": "1.0.1", "label": "1.0.1",
"mainDocId": "hello", "mainDocId": "hello",
@ -3602,6 +3712,7 @@ exports[`versioned website content: global data 1`] = `
"sidebar": "version-1.0.0/docs", "sidebar": "version-1.0.0/docs",
}, },
], ],
"draftIds": [],
"isLast": false, "isLast": false,
"label": "1.0.0", "label": "1.0.0",
"mainDocId": "hello", "mainDocId": "hello",
@ -3659,6 +3770,7 @@ exports[`versioned website content: global data 1`] = `
"sidebar": undefined, "sidebar": undefined,
}, },
], ],
"draftIds": [],
"isLast": false, "isLast": false,
"label": "withSlugs", "label": "withSlugs",
"mainDocId": "rootAbsoluteSlug", "mainDocId": "rootAbsoluteSlug",

View file

@ -14,6 +14,7 @@ import {
readDocFile, readDocFile,
addDocNavigation, addDocNavigation,
isCategoryIndex, isCategoryIndex,
type DocEnv,
} from '../docs'; } from '../docs';
import {loadSidebars} from '../sidebars'; import {loadSidebars} from '../sidebars';
import type {Sidebars} from '../sidebars/types'; import type {Sidebars} from '../sidebars/types';
@ -62,46 +63,51 @@ ${markdown}
}; };
}; };
type TestUtilsArg = {
siteDir: string;
context: LoadContext;
versionMetadata: VersionMetadata;
options: MetadataOptions;
env?: DocEnv;
};
function createTestUtils({ function createTestUtils({
siteDir, siteDir,
context, context,
versionMetadata, versionMetadata,
options, options,
}: { env = 'production',
siteDir: string; }: TestUtilsArg) {
context: LoadContext;
versionMetadata: VersionMetadata;
options: MetadataOptions;
}) {
async function readDoc(docFileSource: string) { async function readDoc(docFileSource: string) {
return readDocFile(versionMetadata, docFileSource, options); return readDocFile(versionMetadata, docFileSource, options);
} }
function processDocFile(docFile: DocFile) { async function processDocFile(docFileArg: DocFile | string) {
const docFile: DocFile =
typeof docFileArg === 'string' ? await readDoc(docFileArg) : docFileArg;
return processDocMetadata({ return processDocMetadata({
docFile, docFile,
versionMetadata, versionMetadata,
options, options,
context, context,
env,
}); });
} }
async function testMeta( async function testMeta(
docFileSource: string, docFileSource: string,
expectedMetadata: Optional< expectedMetadata: Optional<
DocMetadataBase, DocMetadataBase,
'source' | 'lastUpdatedBy' | 'lastUpdatedAt' | 'editUrl' 'source' | 'lastUpdatedBy' | 'lastUpdatedAt' | 'editUrl' | 'draft'
>, >,
) { ) {
const docFile = await readDoc(docFileSource); const docFile = await readDoc(docFileSource);
const metadata = await processDocMetadata({ const metadata = await processDocFile(docFile);
docFile,
versionMetadata,
context,
options,
});
expect(metadata).toEqual({ expect(metadata).toEqual({
lastUpdatedBy: undefined, lastUpdatedBy: undefined,
lastUpdatedAt: undefined, lastUpdatedAt: undefined,
editUrl: undefined, editUrl: undefined,
draft: false,
source: path.posix.join( source: path.posix.join(
'@site', '@site',
posixPath(path.relative(siteDir, versionMetadata.contentPath)), posixPath(path.relative(siteDir, versionMetadata.contentPath)),
@ -118,6 +124,7 @@ function createTestUtils({
versionMetadata, versionMetadata,
context, context,
options, options,
env,
}); });
expect(metadata.permalink).toEqual(expectedPermalink); expect(metadata.permalink).toEqual(expectedPermalink);
} }
@ -136,6 +143,7 @@ function createTestUtils({
versionMetadata, versionMetadata,
context, context,
options, options,
env: 'production',
}), }),
); );
const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, { const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, {
@ -143,6 +151,7 @@ function createTestUtils({
defaultSidebarItemsGenerator({...args}), defaultSidebarItemsGenerator({...args}),
numberPrefixParser: options.numberPrefixParser, numberPrefixParser: options.numberPrefixParser,
docs: rawDocs, docs: rawDocs,
drafts: [],
version: versionMetadata, version: versionMetadata,
sidebarOptions: { sidebarOptions: {
sidebarCollapsed: false, sidebarCollapsed: false,
@ -181,20 +190,27 @@ describe('simple site', () => {
options, options,
}); });
expect(versionsMetadata).toHaveLength(1); expect(versionsMetadata).toHaveLength(1);
const [currentVersion] = versionsMetadata; const currentVersion = versionsMetadata[0]!;
const defaultTestUtils = createTestUtils({ function createTestUtilsPartial(args: Partial<TestUtilsArg>) {
return createTestUtils({
siteDir, siteDir,
context, context,
options, options,
versionMetadata: currentVersion, versionMetadata: currentVersion,
...args,
}); });
}
const defaultTestUtils = createTestUtilsPartial({});
return { return {
siteDir, siteDir,
context, context,
options, options,
versionsMetadata, versionsMetadata,
defaultTestUtils, defaultTestUtils,
createTestUtilsPartial,
currentVersion, currentVersion,
}; };
} }
@ -213,6 +229,7 @@ describe('simple site', () => {
'rootTryToEscapeSlug.md', 'rootTryToEscapeSlug.md',
'headingAsTitle.md', 'headingAsTitle.md',
'doc with space.md', 'doc with space.md',
'doc-draft.md',
'foo/bar.md', 'foo/bar.md',
'foo/baz.md', 'foo/baz.md',
'slugs/absoluteSlug.md', 'slugs/absoluteSlug.md',
@ -273,13 +290,14 @@ describe('simple site', () => {
}); });
it('docs with editUrl', async () => { it('docs with editUrl', async () => {
const {siteDir, context, options, currentVersion} = await loadSite({ const {siteDir, context, options, currentVersion, createTestUtilsPartial} =
await loadSite({
options: { options: {
editUrl: 'https://github.com/facebook/docusaurus/edit/main/website', editUrl: 'https://github.com/facebook/docusaurus/edit/main/website',
}, },
}); });
const testUtilsLocal = createTestUtils({ const testUtilsLocal = createTestUtilsPartial({
siteDir, siteDir,
context, context,
options, options,
@ -347,13 +365,14 @@ describe('simple site', () => {
const editUrlFunction: EditUrlFunction = jest.fn(() => hardcodedEditUrl); const editUrlFunction: EditUrlFunction = jest.fn(() => hardcodedEditUrl);
const {siteDir, context, options, currentVersion} = await loadSite({ const {siteDir, context, options, currentVersion, createTestUtilsPartial} =
await loadSite({
options: { options: {
editUrl: editUrlFunction, editUrl: editUrlFunction,
}, },
}); });
const testUtilsLocal = createTestUtils({ const testUtilsLocal = createTestUtilsPartial({
siteDir, siteDir,
context, context,
options, options,
@ -404,14 +423,15 @@ describe('simple site', () => {
}); });
it('docs with last update time and author', async () => { it('docs with last update time and author', async () => {
const {siteDir, context, options, currentVersion} = await loadSite({ const {siteDir, context, options, currentVersion, createTestUtilsPartial} =
await loadSite({
options: { options: {
showLastUpdateAuthor: true, showLastUpdateAuthor: true,
showLastUpdateTime: true, showLastUpdateTime: true,
}, },
}); });
const testUtilsLocal = createTestUtils({ const testUtilsLocal = createTestUtilsPartial({
siteDir, siteDir,
context, context,
options, options,
@ -439,6 +459,28 @@ describe('simple site', () => {
}); });
}); });
it('docs with draft frontmatter', async () => {
const {createTestUtilsPartial} = await loadSite();
const testUtilsProd = createTestUtilsPartial({
env: 'production',
});
await expect(
testUtilsProd.processDocFile('doc-draft.md'),
).resolves.toMatchObject({
draft: true,
});
const testUtilsDev = createTestUtilsPartial({
env: 'development',
});
await expect(
testUtilsDev.processDocFile('doc-draft.md'),
).resolves.toMatchObject({
draft: false,
});
});
it('docs with slugs', async () => { it('docs with slugs', async () => {
const {defaultTestUtils} = await loadSite(); const {defaultTestUtils} = await loadSite();
@ -495,7 +537,7 @@ describe('simple site', () => {
it('custom pagination', async () => { it('custom pagination', async () => {
const {defaultTestUtils, options, versionsMetadata} = await loadSite(); const {defaultTestUtils, options, versionsMetadata} = await loadSite();
const docs = await readVersionDocs(versionsMetadata[0], options); const docs = await readVersionDocs(versionsMetadata[0]!, options);
await expect( await expect(
defaultTestUtils.generateNavigation(docs), defaultTestUtils.generateNavigation(docs),
).resolves.toMatchSnapshot(); ).resolves.toMatchSnapshot();
@ -503,7 +545,7 @@ describe('simple site', () => {
it('bad pagination', async () => { it('bad pagination', async () => {
const {defaultTestUtils, options, versionsMetadata} = await loadSite(); const {defaultTestUtils, options, versionsMetadata} = await loadSite();
const docs = await readVersionDocs(versionsMetadata[0], options); const docs = await readVersionDocs(versionsMetadata[0]!, options);
docs.push( docs.push(
createFakeDocFile({ createFakeDocFile({
source: 'bad', source: 'bad',
@ -539,8 +581,11 @@ describe('versioned site', () => {
options, options,
}); });
expect(versionsMetadata).toHaveLength(4); expect(versionsMetadata).toHaveLength(4);
const [currentVersion, version101, version100, versionWithSlugs] =
versionsMetadata; const currentVersion = versionsMetadata[0]!;
const version101 = versionsMetadata[1]!;
const version100 = versionsMetadata[2]!;
const versionWithSlugs = versionsMetadata[3]!;
const currentVersionTestUtils = createTestUtils({ const currentVersionTestUtils = createTestUtils({
siteDir, siteDir,

View file

@ -378,3 +378,19 @@ describe('toc min/max consistency', () => {
], ],
}); });
}); });
describe('validateDocFrontMatter draft', () => {
testField({
prefix: 'draft',
validFrontMatters: [{draft: true}, {draft: false}],
convertibleFrontMatter: [
[{draft: 'true'}, {draft: true}],
[{draft: 'false'}, {draft: false}],
],
invalidFrontMatters: [
[{draft: 'yes'}, 'must be a boolean'],
[{draft: 'no'}, 'must be a boolean'],
[{draft: ''}, 'must be a boolean'],
],
});
});

View file

@ -28,6 +28,13 @@ describe('toGlobalDataVersion', () => {
sidebar: 'tutorial', sidebar: 'tutorial',
}, },
], ],
drafts: [
{
unversionedId: 'some-draft-id',
permalink: '/current/draft',
sidebar: undefined,
},
],
sidebars: { sidebars: {
another: [ another: [
{ {

View file

@ -38,6 +38,7 @@ import type {
PropNavigationLink, PropNavigationLink,
LastUpdateData, LastUpdateData,
VersionMetadata, VersionMetadata,
DocFrontMatter,
} from '@docusaurus/plugin-content-docs'; } from '@docusaurus/plugin-content-docs';
type LastUpdateOptions = Pick< type LastUpdateOptions = Pick<
@ -110,16 +111,31 @@ export async function readVersionDocs(
); );
} }
export type DocEnv = 'production' | 'development';
/** Docs with draft front matter are only considered draft in production. */
function isDraftForEnvironment({
env,
frontMatter,
}: {
frontMatter: DocFrontMatter;
env: DocEnv;
}): boolean {
return (env === 'production' && frontMatter.draft) ?? false;
}
function doProcessDocMetadata({ function doProcessDocMetadata({
docFile, docFile,
versionMetadata, versionMetadata,
context, context,
options, options,
env,
}: { }: {
docFile: DocFile; docFile: DocFile;
versionMetadata: VersionMetadata; versionMetadata: VersionMetadata;
context: LoadContext; context: LoadContext;
options: MetadataOptions; options: MetadataOptions;
env: DocEnv;
}): DocMetadataBase { }): DocMetadataBase {
const {source, content, lastUpdate, contentPath, filePath} = docFile; const {source, content, lastUpdate, contentPath, filePath} = docFile;
const {siteDir, i18n} = context; const {siteDir, i18n} = context;
@ -235,6 +251,8 @@ function doProcessDocMetadata({
return undefined; return undefined;
} }
const draft = isDraftForEnvironment({env, frontMatter});
// Assign all of object properties during instantiation (if possible) for // Assign all of object properties during instantiation (if possible) for
// NodeJS optimization. // NodeJS optimization.
// Adding properties to object after instantiation will cause hidden // Adding properties to object after instantiation will cause hidden
@ -248,6 +266,7 @@ function doProcessDocMetadata({
sourceDirName, sourceDirName,
slug: docSlug, slug: docSlug,
permalink, permalink,
draft,
editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(), editUrl: customEditURL !== undefined ? customEditURL : getDocEditUrl(),
tags: normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags), tags: normalizeFrontMatterTags(versionMetadata.tagsPath, frontMatter.tags),
version: versionMetadata.versionName, version: versionMetadata.versionName,
@ -268,6 +287,7 @@ export function processDocMetadata(args: {
versionMetadata: VersionMetadata; versionMetadata: VersionMetadata;
context: LoadContext; context: LoadContext;
options: MetadataOptions; options: MetadataOptions;
env: DocEnv;
}): DocMetadataBase { }): DocMetadataBase {
try { try {
return doProcessDocMetadata(args); return doProcessDocMetadata(args);

View file

@ -38,6 +38,7 @@ const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
parse_number_prefixes: Joi.boolean(), parse_number_prefixes: Joi.boolean(),
pagination_next: Joi.string().allow(null), pagination_next: Joi.string().allow(null),
pagination_prev: Joi.string().allow(null), pagination_prev: Joi.string().allow(null),
draft: Joi.boolean(),
...FrontMatterTOCHeadingLevels, ...FrontMatterTOCHeadingLevels,
}).unknown(); }).unknown();

View file

@ -72,6 +72,7 @@ export function toGlobalDataVersion(version: LoadedVersion): GlobalVersion {
docs: version.docs docs: version.docs
.map(toGlobalDataDoc) .map(toGlobalDataDoc)
.concat(version.categoryGeneratedIndices.map(toGlobalDataGeneratedIndex)), .concat(version.categoryGeneratedIndices.map(toGlobalDataGeneratedIndex)),
draftIds: version.drafts.map((doc) => doc.unversionedId),
sidebars: toGlobalSidebars(version.sidebars, version), sidebars: toGlobalSidebars(version.sidebars, version),
}; };
} }

View file

@ -22,6 +22,7 @@ import {
import type {LoadContext, Plugin} from '@docusaurus/types'; import type {LoadContext, Plugin} from '@docusaurus/types';
import {loadSidebars, resolveSidebarPathOption} from './sidebars'; import {loadSidebars, resolveSidebarPathOption} from './sidebars';
import {CategoryMetadataFilenamePattern} from './sidebars/generator'; import {CategoryMetadataFilenamePattern} from './sidebars/generator';
import type {DocEnv} from './docs';
import { import {
readVersionDocs, readVersionDocs,
processDocMetadata, processDocMetadata,
@ -58,6 +59,7 @@ import type {
} from '@docusaurus/plugin-content-docs'; } from '@docusaurus/plugin-content-docs';
import {createSidebarsUtils} from './sidebars/utils'; import {createSidebarsUtils} from './sidebars/utils';
import {getCategoryGeneratedIndexMetadataList} from './categoryGeneratedIndex'; import {getCategoryGeneratedIndexMetadataList} from './categoryGeneratedIndex';
import _ from 'lodash';
export default async function pluginContentDocs( export default async function pluginContentDocs(
context: LoadContext, context: LoadContext,
@ -147,6 +149,7 @@ export default async function pluginContentDocs(
versionMetadata, versionMetadata,
context, context,
options, options,
env: process.env.NODE_ENV as DocEnv,
}); });
} }
return Promise.all(docFiles.map(processVersionDoc)); return Promise.all(docFiles.map(processVersionDoc));
@ -155,14 +158,17 @@ export default async function pluginContentDocs(
async function doLoadVersion( async function doLoadVersion(
versionMetadata: VersionMetadata, versionMetadata: VersionMetadata,
): Promise<LoadedVersion> { ): Promise<LoadedVersion> {
const docs: DocMetadataBase[] = await loadVersionDocsBase( const docsBase: DocMetadataBase[] = await loadVersionDocsBase(
versionMetadata, versionMetadata,
); );
const [drafts, docs] = _.partition(docsBase, (doc) => doc.draft);
const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, { const sidebars = await loadSidebars(versionMetadata.sidebarFilePath, {
sidebarItemsGenerator: options.sidebarItemsGenerator, sidebarItemsGenerator: options.sidebarItemsGenerator,
numberPrefixParser: options.numberPrefixParser, numberPrefixParser: options.numberPrefixParser,
docs, docs,
drafts,
version: versionMetadata, version: versionMetadata,
sidebarOptions: { sidebarOptions: {
sidebarCollapsed: options.sidebarCollapsed, sidebarCollapsed: options.sidebarCollapsed,
@ -180,6 +186,7 @@ export default async function pluginContentDocs(
sidebarsUtils, sidebarsUtils,
versionMetadata.sidebarFilePath as string, versionMetadata.sidebarFilePath as string,
), ),
drafts,
sidebars, sidebars,
mainDocId: getMainDocId({docs, sidebarsUtils}), mainDocId: getMainDocId({docs, sidebarsUtils}),
categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({ categoryGeneratedIndices: getCategoryGeneratedIndexMetadataList({

View file

@ -346,6 +346,8 @@ declare module '@docusaurus/plugin-content-docs' {
* @see {@link DocMetadata.prev} * @see {@link DocMetadata.prev}
*/ */
pagination_prev?: string | null; pagination_prev?: string | null;
/** Should this doc be excluded from production builds? */
draft?: boolean;
}; };
export type LastUpdateData = { export type LastUpdateData = {
@ -390,6 +392,10 @@ declare module '@docusaurus/plugin-content-docs' {
slug: string; slug: string;
/** Full URL to this doc, with base URL and version path. */ /** Full URL to this doc, with base URL and version path. */
permalink: string; permalink: string;
/**
* Draft docs will be excluded for production environment.
*/
draft: boolean;
/** /**
* Position in an autogenerated sidebar slice, acquired through front matter * Position in an autogenerated sidebar slice, acquired through front matter
* or number prefix. * or number prefix.
@ -597,6 +603,8 @@ declare module '@docusaurus/plugin-content-docs/client' {
/** The doc with `slug: /`, or first doc in first sidebar */ /** The doc with `slug: /`, or first doc in first sidebar */
mainDocId: string; mainDocId: string;
docs: GlobalDoc[]; docs: GlobalDoc[];
/** Unversioned IDs. In development, this list is empty. */
draftIds: string[];
sidebars?: {[sidebarId: string]: GlobalSidebar}; sidebars?: {[sidebarId: string]: GlobalSidebar};
}; };

View file

@ -247,6 +247,31 @@ exports[`loadSidebars sidebars with known sidebar item type 1`] = `
} }
`; `;
exports[`loadSidebars sidebars with some draft items 1`] = `
{
"docs": [
{
"collapsed": true,
"collapsible": true,
"items": [
{
"id": "foo/bar",
"type": "doc",
},
{
"href": "https://github.com",
"label": "GitHub",
"type": "link",
},
],
"label": "Test",
"link": undefined,
"type": "category",
},
],
}
`;
exports[`loadSidebars undefined path 1`] = ` exports[`loadSidebars undefined path 1`] = `
{ {
"defaultSidebar": [ "defaultSidebar": [

View file

@ -10,6 +10,7 @@ import path from 'path';
import {loadSidebars, DisabledSidebars} from '../index'; import {loadSidebars, DisabledSidebars} from '../index';
import type {SidebarProcessorParams} from '../types'; import type {SidebarProcessorParams} from '../types';
import {DefaultSidebarItemsGenerator} from '../generator'; import {DefaultSidebarItemsGenerator} from '../generator';
import type {DocMetadata} from '@docusaurus/plugin-content-docs';
describe('loadSidebars', () => { describe('loadSidebars', () => {
const fixtureDir = path.join(__dirname, '__fixtures__', 'sidebars'); const fixtureDir = path.join(__dirname, '__fixtures__', 'sidebars');
@ -24,6 +25,7 @@ describe('loadSidebars', () => {
frontMatter: {}, frontMatter: {},
}, },
], ],
drafts: [],
version: { version: {
contentPath: path.join(fixtureDir, 'docs'), contentPath: path.join(fixtureDir, 'docs'),
contentPathLocalized: path.join(fixtureDir, 'docs'), contentPathLocalized: path.join(fixtureDir, 'docs'),
@ -37,6 +39,16 @@ describe('loadSidebars', () => {
expect(result).toMatchSnapshot(); expect(result).toMatchSnapshot();
}); });
it('sidebars with some draft items', async () => {
const sidebarPath = path.join(fixtureDir, 'sidebars.json');
const paramsWithDrafts: SidebarProcessorParams = {
...params,
drafts: [{id: 'foo/baz'} as DocMetadata, {id: 'hello'} as DocMetadata],
};
const result = await loadSidebars(sidebarPath, paramsWithDrafts);
expect(result).toMatchSnapshot();
});
it('sidebars with deep level of category', async () => { it('sidebars with deep level of category', async () => {
const sidebarPath = path.join(fixtureDir, 'sidebars-category.js'); const sidebarPath = path.join(fixtureDir, 'sidebars-category.js');
const result = await loadSidebars(sidebarPath, params); const result = await loadSidebars(sidebarPath, params);

View file

@ -46,6 +46,7 @@ describe('processSidebars', () => {
const params: SidebarProcessorParams = { const params: SidebarProcessorParams = {
sidebarItemsGenerator: StaticSidebarItemsGenerator, sidebarItemsGenerator: StaticSidebarItemsGenerator,
docs: [], docs: [],
drafts: [],
version, version,
numberPrefixParser: DefaultNumberPrefixParser, numberPrefixParser: DefaultNumberPrefixParser,
categoryLabelSlugger: createSlugger(), categoryLabelSlugger: createSlugger(),

View file

@ -26,7 +26,7 @@ import {DefaultSidebarItemsGenerator} from './generator';
import {validateSidebars} from './validation'; import {validateSidebars} from './validation';
import _ from 'lodash'; import _ from 'lodash';
import combinePromises from 'combine-promises'; import combinePromises from 'combine-promises';
import {isCategoryIndex} from '../docs'; import {getDocIds, isCategoryIndex} from '../docs';
function toSidebarItemsGeneratorDoc( function toSidebarItemsGeneratorDoc(
doc: DocMetadataBase, doc: DocMetadataBase,
@ -55,7 +55,8 @@ async function processSidebar(
categoriesMetadata: {[filePath: string]: CategoryMetadataFile}, categoriesMetadata: {[filePath: string]: CategoryMetadataFile},
params: SidebarProcessorParams, params: SidebarProcessorParams,
): Promise<ProcessedSidebar> { ): Promise<ProcessedSidebar> {
const {sidebarItemsGenerator, numberPrefixParser, docs, version} = params; const {sidebarItemsGenerator, numberPrefixParser, docs, drafts, version} =
params;
// Just a minor lazy transformation optimization // Just a minor lazy transformation optimization
const getSidebarItemsGeneratorDocsAndVersion = _.memoize(() => ({ const getSidebarItemsGeneratorDocsAndVersion = _.memoize(() => ({
@ -81,6 +82,19 @@ async function processSidebar(
return processItems(generatedItems); return processItems(generatedItems);
} }
const draftIds = new Set(drafts.flatMap(getDocIds));
const isDraftItem = (item: NormalizedSidebarItem): boolean => {
if (item.type === 'doc' || item.type === 'ref') {
return draftIds.has(item.id);
}
// If a category only contains draft items, it should be filtered entirely.
if (item.type === 'category') {
return item.items.every(isDraftItem);
}
return false;
};
async function processItem( async function processItem(
item: NormalizedSidebarItem, item: NormalizedSidebarItem,
): Promise<ProcessedSidebarItem[]> { ): Promise<ProcessedSidebarItem[]> {
@ -88,7 +102,7 @@ async function processSidebar(
return [ return [
{ {
...item, ...item,
items: (await Promise.all(item.items.map(processItem))).flat(), items: await processItems(item.items),
}, },
]; ];
} }
@ -101,7 +115,9 @@ async function processSidebar(
async function processItems( async function processItems(
items: NormalizedSidebarItem[], items: NormalizedSidebarItem[],
): Promise<ProcessedSidebarItem[]> { ): Promise<ProcessedSidebarItem[]> {
return (await Promise.all(items.map(processItem))).flat(); return (
await Promise.all(items.filter((i) => !isDraftItem(i)).map(processItem))
).flat();
} }
const processedSidebar = await processItems(unprocessedSidebar); const processedSidebar = await processItems(unprocessedSidebar);

View file

@ -269,6 +269,7 @@ export type SidebarProcessorParams = {
sidebarItemsGenerator: SidebarItemsGeneratorOption; sidebarItemsGenerator: SidebarItemsGeneratorOption;
numberPrefixParser: NumberPrefixParser; numberPrefixParser: NumberPrefixParser;
docs: DocMetadataBase[]; docs: DocMetadataBase[];
drafts: DocMetadataBase[];
version: VersionMetadata; version: VersionMetadata;
categoryLabelSlugger: Slugger; categoryLabelSlugger: Slugger;
sidebarOptions: SidebarOptions; sidebarOptions: SidebarOptions;

View file

@ -40,6 +40,7 @@ export type VersionTags = {
export type LoadedVersion = VersionMetadata & { export type LoadedVersion = VersionMetadata & {
mainDocId: string; mainDocId: string;
docs: DocMetadata[]; docs: DocMetadata[];
drafts: DocMetadata[];
sidebars: Sidebars; sidebars: Sidebars;
categoryGeneratedIndices: CategoryGeneratedIndexMetadata[]; categoryGeneratedIndices: CategoryGeneratedIndexMetadata[];
}; };

View file

@ -796,7 +796,9 @@ declare module '@theme/NavbarItem/DocNavbarItem' {
readonly docsPluginId?: string; readonly docsPluginId?: string;
} }
export default function DocsSidebarNavbarItem(props: Props): JSX.Element; export default function DocsSidebarNavbarItem(
props: Props,
): JSX.Element | null;
} }
declare module '@theme/NavbarItem/DocSidebarNavbarItem' { declare module '@theme/NavbarItem/DocSidebarNavbarItem' {

View file

@ -18,9 +18,15 @@ export default function DocNavbarItem({
label: staticLabel, label: staticLabel,
docsPluginId, docsPluginId,
...props ...props
}: Props): JSX.Element { }: Props): JSX.Element | null {
const {activeDoc} = useActiveDocContext(docsPluginId); const {activeDoc} = useActiveDocContext(docsPluginId);
const doc = useLayoutDoc(docId, docsPluginId); const doc = useLayoutDoc(docId, docsPluginId);
// Draft items are not displayed in the navbar.
if (doc === null) {
return null;
}
const activeDocInfimaClassName = getInfimaActiveClassName(props.mobile); const activeDocInfimaClassName = getInfimaActiveClassName(props.mobile);
return ( return (

View file

@ -259,12 +259,22 @@ export function useLayoutDocsSidebar(
* *
* @throws This hook throws if a doc with said ID is not found. * @throws This hook throws if a doc with said ID is not found.
*/ */
export function useLayoutDoc(docId: string, docsPluginId?: string): GlobalDoc { export function useLayoutDoc(
docId: string,
docsPluginId?: string,
): GlobalDoc | null {
const versions = useDocsVersionCandidates(docsPluginId); const versions = useDocsVersionCandidates(docsPluginId);
return useMemo(() => { return useMemo(() => {
const allDocs = versions.flatMap((version) => version.docs); const allDocs = versions.flatMap((version) => version.docs);
const doc = allDocs.find((versionDoc) => versionDoc.id === docId); const doc = allDocs.find((versionDoc) => versionDoc.id === docId);
if (!doc) { if (!doc) {
const isDraft = versions
.flatMap((version) => version.draftIds)
.includes(docId);
// drafts should be silently filtered instead of throwing
if (isDraft) {
return null;
}
throw new Error( throw new Error(
`DocNavbarItem: couldn't find any doc with id "${docId}" in version${ `DocNavbarItem: couldn't find any doc with id "${docId}" in version${
versions.length > 1 ? 's' : '' versions.length > 1 ? 's' : ''

View file

@ -0,0 +1,9 @@
---
draft: true
---
# Test section
Welcome to the docs plugin test section
Note: this draft doc (and the navbar link) should only be visible in local development

View file

@ -0,0 +1,7 @@
---
draft: true
---
# Another Draft
This page should only be visible in local development

View file

@ -14,6 +14,7 @@ const sidebars = {
className: 'red', className: 'red',
label: 'Index', label: 'Index',
}, },
'test-draft',
'doc-without-sidebar', 'doc-without-sidebar',
'doc-with-another-sidebar', 'doc-with-another-sidebar',
{ {

View file

@ -174,7 +174,7 @@ Accepted fields:
| `title` | `string` | Markdown title | The blog post title. | | `title` | `string` | Markdown title | The blog post title. |
| `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. | | `date` | `string` | File name or file creation time | The blog post creation date. If not specified, this can be extracted from the file or folder name, e.g, `2021-04-15-blog-post.mdx`, `2021-04-15-blog-post/index.mdx`, `2021/04/15/blog-post.mdx`. Otherwise, it is the Markdown file creation time. |
| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. | | `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your post. |
| `draft` | `boolean` | `false` | A boolean flag to indicate that the blog post is work-in-progress and therefore should not be published yet. However, draft blog posts will be displayed during development. | | `draft` | `boolean` | `false` | A boolean flag to indicate that the blog post is work-in-progress. Draft blog posts will only be displayed during development. |
| `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. | | `hide_table_of_contents` | `boolean` | `false` | Whether to hide the table of contents to the right. |
| `toc_min_heading_level` | `number` | `2` | The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value. | | `toc_min_heading_level` | `number` | `2` | The minimum heading level shown in the table of contents. Must be between 2 and 6 and lower or equal to the max value. |
| `toc_max_heading_level` | `number` | `3` | The max heading level shown in the table of contents. Must be between 2 and 6. | | `toc_max_heading_level` | `number` | `3` | The max heading level shown in the table of contents. Must be between 2 and 6. |

View file

@ -262,6 +262,7 @@ Accepted fields:
| `image` | `string` | `undefined` | Cover or thumbnail image that will be used when displaying the link to your post. | | `image` | `string` | `undefined` | Cover or thumbnail image that will be used when displaying the link to your post. |
| `slug` | `string` | File path | Allows to customize the document url (`/<routeBasePath>/<slug>`). Support multiple patterns: `slug: my-doc`, `slug: /my/path/myDoc`, `slug: /`. | | `slug` | `string` | File path | Allows to customize the document url (`/<routeBasePath>/<slug>`). Support multiple patterns: `slug: my-doc`, `slug: /my/path/myDoc`, `slug: /`. |
| `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. | | `tags` | `Tag[]` | `undefined` | A list of strings or objects of two string fields `label` and `permalink` to tag to your docs. |
| `draft` | `boolean` | `false` | A boolean flag to indicate that a document is a work-in-progress. Draft documents will only be displayed during development. |
</APITable> </APITable>

View file

@ -97,15 +97,15 @@ const config = {
loader: require.resolve('swc-loader'), loader: require.resolve('swc-loader'),
options: { options: {
jsc: { jsc: {
"parser": { parser: {
"syntax": "typescript", syntax: 'typescript',
"tsx": true tsx: true,
}, },
target: 'es2017', target: 'es2017',
}, },
module: { module: {
type: isServer ? 'commonjs' : 'es6', type: isServer ? 'commonjs' : 'es6',
} },
}, },
}), }),
}, },
@ -407,6 +407,12 @@ const config = {
position: 'left', position: 'left',
activeBaseRegex: `/community/`, activeBaseRegex: `/community/`,
}, },
{
type: 'doc',
docId: 'test-draft',
label: 'Tests',
docsPluginId: 'docs-tests',
},
// right // right
{ {
type: 'docsVersionDropdown', type: 'docsVersionDropdown',