Compare commits
3 Commits
main
...
docusaurus
| Author | SHA1 | Date |
|---|---|---|
|
|
72dcd0d8c5 | |
|
|
7b1b89041f | |
|
|
a2e05d2118 |
|
|
@ -37,6 +37,5 @@
|
||||||
"*.min.*",
|
"*.min.*",
|
||||||
"jest/vendor"
|
"jest/vendor"
|
||||||
],
|
],
|
||||||
"ignoreRegExpList": ["Email", "Urls", "#[\\w-]*"],
|
"ignoreRegExpList": ["Email", "Urls", "#[\\w-]*"]
|
||||||
"enableFiletypes": ["mdx"]
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -85,14 +85,13 @@ module.exports = {
|
||||||
ignorePattern: '(eslint-disable|@)',
|
ignorePattern: '(eslint-disable|@)',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'arrow-body-style': OFF,
|
|
||||||
'no-await-in-loop': OFF,
|
'no-await-in-loop': OFF,
|
||||||
'no-case-declarations': WARNING,
|
'no-case-declarations': WARNING,
|
||||||
'no-console': OFF,
|
'no-console': OFF,
|
||||||
'no-constant-binary-expression': ERROR,
|
'no-constant-binary-expression': ERROR,
|
||||||
'no-continue': OFF,
|
'no-continue': OFF,
|
||||||
'no-control-regex': WARNING,
|
'no-control-regex': WARNING,
|
||||||
'no-else-return': OFF,
|
'no-else-return': [WARNING, {allowElseIf: true}],
|
||||||
'no-empty': [WARNING, {allowEmptyCatch: true}],
|
'no-empty': [WARNING, {allowEmptyCatch: true}],
|
||||||
'no-lonely-if': WARNING,
|
'no-lonely-if': WARNING,
|
||||||
'no-nested-ternary': WARNING,
|
'no-nested-ternary': WARNING,
|
||||||
|
|
@ -348,7 +347,10 @@ module.exports = {
|
||||||
ERROR,
|
ERROR,
|
||||||
{'ts-expect-error': 'allow-with-description'},
|
{'ts-expect-error': 'allow-with-description'},
|
||||||
],
|
],
|
||||||
'@typescript-eslint/consistent-indexed-object-style': OFF,
|
'@typescript-eslint/consistent-indexed-object-style': [
|
||||||
|
WARNING,
|
||||||
|
'index-signature',
|
||||||
|
],
|
||||||
'@typescript-eslint/consistent-type-imports': [
|
'@typescript-eslint/consistent-type-imports': [
|
||||||
WARNING,
|
WARNING,
|
||||||
{disallowTypeAnnotations: false},
|
{disallowTypeAnnotations: false},
|
||||||
|
|
|
||||||
|
|
@ -23,14 +23,14 @@ jobs:
|
||||||
# Argos is heavy to run
|
# Argos is heavy to run
|
||||||
# We only want to trigger Argos on PRs with the 'Argos' label
|
# We only want to trigger Argos on PRs with the 'Argos' label
|
||||||
# See https://stackoverflow.com/questions/62325286/run-github-actions-when-pull-requests-have-a-specific-label
|
# See https://stackoverflow.com/questions/62325286/run-github-actions-when-pull-requests-have-a-specific-label
|
||||||
if: ${{ (github.event_name != 'pull_request' && github.ref_name == 'main') || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'Argos')) }}
|
if: ${{ github.ref_name == 'main' || (github.event_name == 'pull_request' && contains(github.event.pull_request.labels.*.name, 'Argos')) }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Check out repository code
|
- name: Check out repository code
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
@ -60,7 +60,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
cache: yarn
|
cache: yarn
|
||||||
- name: Installation
|
- name: Installation
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ jobs:
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0 # Needed to get the commit number with "git rev-list --count HEAD"
|
fetch-depth: 0 # Needed to get the commit number with "git rev-list --count HEAD"
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
|
||||||
|
|
@ -15,4 +15,4 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Dependency Review
|
- name: Dependency Review
|
||||||
uses: actions/dependency-review-action@733dd5d4a5203f238c33806593ec0f5fc5343d8c # 4.2.4
|
uses: actions/dependency-review-action@6c5ccdad469c9f8a2996bfecaec55a631a347034 # 3.1.0
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ jobs:
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
|
|
||||||
- name: Use Node.js
|
- name: Use Node.js
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: 18
|
node-version: 18
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ jobs:
|
||||||
|
|
||||||
- name: Audit URLs using Lighthouse
|
- name: Audit URLs using Lighthouse
|
||||||
id: lighthouse_audit
|
id: lighthouse_audit
|
||||||
uses: treosh/lighthouse-ci-action@1b0e7c33270fbba31a18a0fbb1de7cc5256b6d39 # 11.4.0
|
uses: treosh/lighthouse-ci-action@03becbfc543944dd6e7534f7ff768abb8a296826 # 10.1.0
|
||||||
with:
|
with:
|
||||||
urls: |
|
urls: |
|
||||||
http://localhost:3000
|
http://localhost:3000
|
||||||
|
|
@ -52,7 +52,7 @@ jobs:
|
||||||
|
|
||||||
- name: Format lighthouse score
|
- name: Format lighthouse score
|
||||||
id: format_lighthouse_score
|
id: format_lighthouse_score
|
||||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # 7.0.1
|
uses: actions/github-script@d7906e4ad0b1822421a7e6a35d5ca353c962f410 # v6
|
||||||
with:
|
with:
|
||||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
script: |
|
script: |
|
||||||
|
|
@ -64,7 +64,7 @@ jobs:
|
||||||
|
|
||||||
- name: Add Lighthouse stats as comment
|
- name: Add Lighthouse stats as comment
|
||||||
id: comment_to_pr
|
id: comment_to_pr
|
||||||
uses: marocchino/sticky-pull-request-comment@331f8f5b4215f0445d3c07b4967662a32a2d3e31 # 2.9.0
|
uses: marocchino/sticky-pull-request-comment@efaaab3fd41a9c3de579aba759d2552635e590fd # 2.8.0
|
||||||
with:
|
with:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
number: ${{ github.event.pull_request.number }}
|
number: ${{ github.event.pull_request.number }}
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
|
||||||
|
|
@ -24,9 +24,9 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '20'
|
node-version: '16'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
- name: Installation
|
- name: Installation
|
||||||
run: yarn
|
run: yarn
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Use Node.js ${{ matrix.node }}
|
- name: Use Node.js ${{ matrix.node }}
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
@ -77,7 +77,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Use Node.js 18
|
- name: Use Node.js 18
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
@ -131,7 +131,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Use Node.js 18
|
- name: Use Node.js 18
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
@ -161,7 +161,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Use Node.js 18
|
- name: Use Node.js 18
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Set up Node
|
- name: Set up Node
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: '18'
|
node-version: '18'
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Use Node.js ${{ matrix.node }}
|
- name: Use Node.js ${{ matrix.node }}
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
- name: Installation
|
- name: Installation
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ jobs:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
|
||||||
- name: Use Node.js ${{ matrix.node }}
|
- name: Use Node.js ${{ matrix.node }}
|
||||||
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
|
uses: actions/setup-node@8f152de45cc393bb48ce5d89d36b731f54556e65 # v4.0.0
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
cache: yarn
|
cache: yarn
|
||||||
|
|
|
||||||
266
CHANGELOG.md
266
CHANGELOG.md
|
|
@ -1,271 +1,5 @@
|
||||||
# Docusaurus 2 Changelog
|
# Docusaurus 2 Changelog
|
||||||
|
|
||||||
## 3.2.0 (2024-03-29)
|
|
||||||
|
|
||||||
#### :rocket: New Feature
|
|
||||||
|
|
||||||
- `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-plugin-content-pages`, `docusaurus-plugin-sitemap`, `docusaurus-types`, `docusaurus-utils`, `docusaurus`
|
|
||||||
- [#9954](https://github.com/facebook/docusaurus/pull/9954) feat(sitemap): add support for "lastmod" ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-utils-validation`, `docusaurus-utils`
|
|
||||||
- [#9912](https://github.com/facebook/docusaurus/pull/9912) feat(blog): add LastUpdateAuthor & LastUpdateTime ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- `docusaurus-plugin-debug`, `docusaurus-types`, `docusaurus`
|
|
||||||
- [#9931](https://github.com/facebook/docusaurus/pull/9931) feat(core): add new plugin allContentLoaded lifecycle ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-theme-translations`
|
|
||||||
- [#9928](https://github.com/facebook/docusaurus/pull/9928) feat(theme-translations) Icelandic (is) ([@Hallinn](https://github.com/Hallinn))
|
|
||||||
- `docusaurus-plugin-content-blog`
|
|
||||||
- [#9886](https://github.com/facebook/docusaurus/pull/9886) feat(blog): allow processing blog posts through a processBlogPosts function ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- [#9838](https://github.com/facebook/docusaurus/pull/9838) feat(blog): add blog pageBasePath plugin option ([@ilg-ul](https://github.com/ilg-ul))
|
|
||||||
- `docusaurus`
|
|
||||||
- [#9681](https://github.com/facebook/docusaurus/pull/9681) feat(swizzle): ask user preferred language if no language CLI option provided ([@yixiaojiu](https://github.com/yixiaojiu))
|
|
||||||
- `create-docusaurus`, `docusaurus-utils`
|
|
||||||
- [#9442](https://github.com/facebook/docusaurus/pull/9442) feat(create-docusaurus): ask user for preferred language when no language CLI option provided ([@Rafael-Martins](https://github.com/Rafael-Martins))
|
|
||||||
- `docusaurus-plugin-vercel-analytics`
|
|
||||||
- [#9687](https://github.com/facebook/docusaurus/pull/9687) feat(plugin-vercel-analytics): add new vercel analytics plugin ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- `docusaurus-mdx-loader`
|
|
||||||
- [#9684](https://github.com/facebook/docusaurus/pull/9684) feat(mdx-loader): the table-of-contents should display toc/headings of imported MDX partials ([@anatolykopyl](https://github.com/anatolykopyl))
|
|
||||||
|
|
||||||
#### :bug: Bug Fix
|
|
||||||
|
|
||||||
- `docusaurus-mdx-loader`
|
|
||||||
- [#9999](https://github.com/facebook/docusaurus/pull/9999) fix(mdx-loader): Ignore contentTitle coming after Markdown thematicBreak ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-theme-search-algolia`
|
|
||||||
- [#9945](https://github.com/facebook/docusaurus/pull/9945) fix(a11y): move focus algolia-search focus back to search input on Escape ([@mxschmitt](https://github.com/mxschmitt))
|
|
||||||
- `docusaurus-plugin-content-blog`
|
|
||||||
- [#9920](https://github.com/facebook/docusaurus/pull/9920) fix(blog): apply trailing slash to blog feed ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- `docusaurus-theme-classic`
|
|
||||||
- [#9944](https://github.com/facebook/docusaurus/pull/9944) fix(theme): improve a11y of DocSidebarItemCategory expand/collapsed button ([@mxschmitt](https://github.com/mxschmitt))
|
|
||||||
- `docusaurus-theme-translations`
|
|
||||||
- [#9915](https://github.com/facebook/docusaurus/pull/9915) fix(theme-translations): complete and modify Japanese translations ([@Suenaga-Ryuya](https://github.com/Suenaga-Ryuya))
|
|
||||||
- [#9910](https://github.com/facebook/docusaurus/pull/9910) fix(theme-translations): add Japanese translations ([@Suenaga-Ryuya](https://github.com/Suenaga-Ryuya))
|
|
||||||
- [#9872](https://github.com/facebook/docusaurus/pull/9872) fix(theme-translations): complete and improve Spanish theme translations ([@4troDev](https://github.com/4troDev))
|
|
||||||
- [#9812](https://github.com/facebook/docusaurus/pull/9812) fix(i18n): add missing theme translations for fa locale ([@VahidNaderi](https://github.com/VahidNaderi))
|
|
||||||
- `docusaurus-utils`
|
|
||||||
- [#9897](https://github.com/facebook/docusaurus/pull/9897) fix(mdx-loader): mdx-code-block should support CRLF ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus`
|
|
||||||
- [#9878](https://github.com/facebook/docusaurus/pull/9878) fix(core): fix default i18n calendar used, infer it from locale if possible ([@slorber](https://github.com/slorber))
|
|
||||||
- [#9852](https://github.com/facebook/docusaurus/pull/9852) fix(core): ensure core error boundary is able to render theme layout ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-remark-plugin-npm2yarn`
|
|
||||||
- [#9861](https://github.com/facebook/docusaurus/pull/9861) fix(remark-npm2yarn): update npm-to-yarn from 2.0.0 to 2.2.1, fix pnpm extra args syntax ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- `docusaurus-theme-classic`, `docusaurus-theme-translations`
|
|
||||||
- [#9851](https://github.com/facebook/docusaurus/pull/9851) fix(theme-classic): should use plurals for category items description ([@baradusov](https://github.com/baradusov))
|
|
||||||
|
|
||||||
#### :running_woman: Performance
|
|
||||||
|
|
||||||
- `docusaurus-types`, `docusaurus-utils`, `docusaurus`
|
|
||||||
- [#9975](https://github.com/facebook/docusaurus/pull/9975) refactor(core): improve dev perf, fine-grained site reloads - part 3 ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-types`, `docusaurus`
|
|
||||||
- [#9968](https://github.com/facebook/docusaurus/pull/9968) refactor(core): improve dev perf, fine-grained site reloads - part2 ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-plugin-content-docs`, `docusaurus-plugin-content-pages`, `docusaurus-types`, `docusaurus`
|
|
||||||
- [#9903](https://github.com/facebook/docusaurus/pull/9903) refactor(core): improve dev perf, fine-grained site reloads - part1 ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-utils`
|
|
||||||
- [#9890](https://github.com/facebook/docusaurus/pull/9890) perf: optimize getFileCommitDate, make it async ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus`
|
|
||||||
- [#9798](https://github.com/facebook/docusaurus/pull/9798) refactor(core): internalize, simplify and optimize the SSG logic ([@slorber](https://github.com/slorber))
|
|
||||||
|
|
||||||
#### :nail_care: Polish
|
|
||||||
|
|
||||||
- `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-theme-classic`, `docusaurus-theme-common`
|
|
||||||
- [#9868](https://github.com/facebook/docusaurus/pull/9868) refactor(theme): dates should be formatted on the client-side instead of in nodejs code ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- `docusaurus-plugin-content-blog`, `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-types`
|
|
||||||
- [#9669](https://github.com/facebook/docusaurus/pull/9669) refactor(theme): use JSON-LD instead of microdata for blog structured data ([@johnnyreilly](https://github.com/johnnyreilly))
|
|
||||||
- `docusaurus-plugin-content-docs`
|
|
||||||
- [#9839](https://github.com/facebook/docusaurus/pull/9839) refactor(blog): improve doc global data hook error message + add doc warning to blogOnly mode ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
|
|
||||||
#### :memo: Documentation
|
|
||||||
|
|
||||||
- [#9937](https://github.com/facebook/docusaurus/pull/9937) docs: use official GitHub Action to deploy to GitHub Pages ([@vlad-nestorov](https://github.com/vlad-nestorov))
|
|
||||||
- [#9971](https://github.com/facebook/docusaurus/pull/9971) docs: replace VuePress by VitePress on tool comparison section ([@sunkanmii](https://github.com/sunkanmii))
|
|
||||||
- [#9914](https://github.com/facebook/docusaurus/pull/9914) docs: update legacy MDX v1 links to markdown links ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- [#9913](https://github.com/facebook/docusaurus/pull/9913) docs: update legacy MDX v1 links to markdown links ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- [#9906](https://github.com/facebook/docusaurus/pull/9906) docs: emphasize "index slug" convention ([@Josh-Cena](https://github.com/Josh-Cena))
|
|
||||||
- [#9877](https://github.com/facebook/docusaurus/pull/9877) docs: fix typos in deployment.mdx ([@Oreoxmt](https://github.com/Oreoxmt))
|
|
||||||
- [#9845](https://github.com/facebook/docusaurus/pull/9845) docs: typo ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- [#9816](https://github.com/facebook/docusaurus/pull/9816) docs: Add docs for Mermaid Component ([@Its-Just-Nans](https://github.com/Its-Just-Nans))
|
|
||||||
|
|
||||||
#### :robot: Dependencies
|
|
||||||
|
|
||||||
- [#9981](https://github.com/facebook/docusaurus/pull/9981) chore(deps): bump actions/dependency-review-action from 4.1.3 to 4.2.4 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9982](https://github.com/facebook/docusaurus/pull/9982) chore(deps): bump katex from 0.16.8 to 0.16.10 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9983](https://github.com/facebook/docusaurus/pull/9983) chore(deps): bump express from 4.18.2 to 4.19.2 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9977](https://github.com/facebook/docusaurus/pull/9977) chore(deps): bump webpack-dev-middleware from 5.3.3 to 5.3.4 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9958](https://github.com/facebook/docusaurus/pull/9958) chore(deps): bump follow-redirects from 1.15.4 to 1.15.6 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9892](https://github.com/facebook/docusaurus/pull/9892) chore(deps): bump actions/dependency-review-action from 4.1.2 to 4.1.3 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9869](https://github.com/facebook/docusaurus/pull/9869) chore(deps): bump actions/dependency-review-action from 4.0.0 to 4.1.2 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9874](https://github.com/facebook/docusaurus/pull/9874) chore(deps): bump ip from 2.0.0 to 2.0.1 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9843](https://github.com/facebook/docusaurus/pull/9843) chore(deps): bump actions/setup-node from 4.0.1 to 4.0.2 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9824](https://github.com/facebook/docusaurus/pull/9824) chore(deps): bump treosh/lighthouse-ci-action from 10.1.0 to 11.4.0 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
- [#9823](https://github.com/facebook/docusaurus/pull/9823) chore(deps): bump marocchino/sticky-pull-request-comment from 2.8.0 to 2.9.0 ([@dependabot[bot]](https://github.com/apps/dependabot))
|
|
||||||
|
|
||||||
#### :wrench: Maintenance
|
|
||||||
|
|
||||||
- `docusaurus-plugin-client-redirects`, `docusaurus-plugin-content-docs`, `docusaurus-utils-common`, `docusaurus-utils-validation`, `docusaurus-utils`, `docusaurus`
|
|
||||||
- [#9972](https://github.com/facebook/docusaurus/pull/9972) refactor(utils): remove duplicated function ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- Other
|
|
||||||
- [#9965](https://github.com/facebook/docusaurus/pull/9965) refactor(website): organise blog posts by year ([@GingerGeek](https://github.com/GingerGeek))
|
|
||||||
- [#9865](https://github.com/facebook/docusaurus/pull/9865) chore(website): update @crowdin/crowdin-api-client ([@chris-bateman](https://github.com/chris-bateman))
|
|
||||||
- `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-utils`
|
|
||||||
- [#9963](https://github.com/facebook/docusaurus/pull/9963) refactor(docs,blog): last update timestamp should be in milliseconds instead of seconds ([@slorber](https://github.com/slorber))
|
|
||||||
|
|
||||||
#### Committers: 22
|
|
||||||
|
|
||||||
- Aolin ([@Oreoxmt](https://github.com/Oreoxmt))
|
|
||||||
- Anatoly Kopyl ([@anatolykopyl](https://github.com/anatolykopyl))
|
|
||||||
- Chris Bateman ([@chris-bateman](https://github.com/chris-bateman))
|
|
||||||
- Fafowora Sunkanmi ([@sunkanmii](https://github.com/sunkanmii))
|
|
||||||
- Hallbjörn Magnússon ([@Hallinn](https://github.com/Hallinn))
|
|
||||||
- John Reilly ([@johnnyreilly](https://github.com/johnnyreilly))
|
|
||||||
- Joshua Chen ([@Josh-Cena](https://github.com/Josh-Cena))
|
|
||||||
- Josue [4tro] A ([@4troDev](https://github.com/4troDev))
|
|
||||||
- Liviu Ionescu ([@ilg-ul](https://github.com/ilg-ul))
|
|
||||||
- Max Schmitt ([@mxschmitt](https://github.com/mxschmitt))
|
|
||||||
- Rafael Martins ([@Rafael-Martins](https://github.com/Rafael-Martins))
|
|
||||||
- Sébastien Lorber ([@slorber](https://github.com/slorber))
|
|
||||||
- Vahid Naderi ([@VahidNaderi](https://github.com/VahidNaderi))
|
|
||||||
- Vlad Nestorov ([@vlad-nestorov](https://github.com/vlad-nestorov))
|
|
||||||
- Zed Spencer-Milnes ([@GingerGeek](https://github.com/GingerGeek))
|
|
||||||
- axel7083 ([@axel7083](https://github.com/axel7083))
|
|
||||||
- krinza.eth ([@kaymomin](https://github.com/kaymomin))
|
|
||||||
- n4n5 ([@Its-Just-Nans](https://github.com/Its-Just-Nans))
|
|
||||||
- ozaki ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- suenryu ([@Suenaga-Ryuya](https://github.com/Suenaga-Ryuya))
|
|
||||||
- Нуриль Барадусов ([@baradusov](https://github.com/baradusov))
|
|
||||||
- 翊小久 ([@yixiaojiu](https://github.com/yixiaojiu))
|
|
||||||
|
|
||||||
## 3.1.1 (2024-01-26)
|
|
||||||
|
|
||||||
#### :bug: Bug Fix
|
|
||||||
|
|
||||||
- `docusaurus-types`, `docusaurus`
|
|
||||||
- [#9791](https://github.com/facebook/docusaurus/pull/9791) fix(core): broken links optimization behaves differently than non-optimized logic ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus`
|
|
||||||
- [#9788](https://github.com/facebook/docusaurus/pull/9788) fix(core): links with target "\_blank" should no be checked by the broken link checker ([@slorber](https://github.com/slorber))
|
|
||||||
- [#9407](https://github.com/facebook/docusaurus/pull/9407) fix(core): conditionally include `hostname` parameter when using… ([@jack-robson](https://github.com/jack-robson))
|
|
||||||
- `docusaurus-utils`
|
|
||||||
- [#9776](https://github.com/facebook/docusaurus/pull/9776) fix(mdx-loader): allow spaces before `mdx-code-block` info string ([@eitsupi](https://github.com/eitsupi))
|
|
||||||
- `create-docusaurus`
|
|
||||||
- [#9783](https://github.com/facebook/docusaurus/pull/9783) fix(create-docusaurus): fix typo in init template sample docs ([@dawei-wang](https://github.com/dawei-wang))
|
|
||||||
- `docusaurus-theme-common`
|
|
||||||
- [#9727](https://github.com/facebook/docusaurus/pull/9727) fix(theme-common): fix missing code block MagicComments style in Visual Basic (.NET) 16 ([@tats-u](https://github.com/tats-u))
|
|
||||||
- `docusaurus-theme-classic`, `docusaurus-theme-mermaid`
|
|
||||||
- [#9733](https://github.com/facebook/docusaurus/pull/9733) fix: remove old useless mdx typedefs ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-module-type-aliases`, `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-utils`, `docusaurus`
|
|
||||||
- [#9732](https://github.com/facebook/docusaurus/pull/9732) fix(core): various broken anchor link fixes ([@slorber](https://github.com/slorber))
|
|
||||||
|
|
||||||
#### :running_woman: Performance
|
|
||||||
|
|
||||||
- `docusaurus`
|
|
||||||
- [#9778](https://github.com/facebook/docusaurus/pull/9778) perf(core): optimize broken links checker ([@slorber](https://github.com/slorber))
|
|
||||||
|
|
||||||
#### :nail_care: Polish
|
|
||||||
|
|
||||||
- `docusaurus-theme-classic`
|
|
||||||
- [#9470](https://github.com/facebook/docusaurus/pull/9470) polish(theme): MDX images should use async decoding ([@sanjaiyan-dev](https://github.com/sanjaiyan-dev))
|
|
||||||
|
|
||||||
#### Committers: 6
|
|
||||||
|
|
||||||
- Jack Robson ([@jack-robson](https://github.com/jack-robson))
|
|
||||||
- Sanjaiyan Parthipan ([@sanjaiyan-dev](https://github.com/sanjaiyan-dev))
|
|
||||||
- Sébastien Lorber ([@slorber](https://github.com/slorber))
|
|
||||||
- Tatsunori Uchino ([@tats-u](https://github.com/tats-u))
|
|
||||||
- [@dawei-wang](https://github.com/dawei-wang)
|
|
||||||
- [@eitsupi](https://github.com/eitsupi)
|
|
||||||
|
|
||||||
## 3.1.0 (2024-01-05)
|
|
||||||
|
|
||||||
#### :rocket: New Feature
|
|
||||||
|
|
||||||
- `docusaurus-mdx-loader`, `docusaurus-module-type-aliases`, `docusaurus-theme-classic`, `docusaurus-types`, `docusaurus-utils`, `docusaurus`
|
|
||||||
- [#9528](https://github.com/facebook/docusaurus/pull/9528) feat(core): make broken link checker detect broken anchors - add `onBrokenAnchors` config ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- `docusaurus-mdx-loader`, `docusaurus-types`, `docusaurus`
|
|
||||||
- [#9674](https://github.com/facebook/docusaurus/pull/9674) feat(mdx-loader): add support for siteConfig.markdown.remarkRehypeOptions ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-theme-common`
|
|
||||||
- [#9671](https://github.com/facebook/docusaurus/pull/9671) feat(theme-common): code block MagicComments support for (Visual) Basic/Batch/Fortran/COBOL/ML ([@tats-u](https://github.com/tats-u))
|
|
||||||
- `docusaurus-mdx-loader`, `docusaurus-plugin-content-blog`, `docusaurus-plugin-content-docs`, `docusaurus-plugin-content-pages`, `docusaurus-types`, `docusaurus-utils`, `docusaurus`
|
|
||||||
- [#9624](https://github.com/facebook/docusaurus/pull/9624) feat: siteConfig.markdown.parseFrontMatter hook ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-utils`
|
|
||||||
- [#9610](https://github.com/facebook/docusaurus/pull/9610) feat(core): enable port configuration via environment variable ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
|
|
||||||
#### :bug: Bug Fix
|
|
||||||
|
|
||||||
- `docusaurus-theme-classic`, `docusaurus-theme-live-codeblock`
|
|
||||||
- [#9704](https://github.com/facebook/docusaurus/pull/9704) fix(theme): allow empty code blocks and live playgrounds ([@slorber](https://github.com/slorber))
|
|
||||||
- `create-docusaurus`
|
|
||||||
- [#9696](https://github.com/facebook/docusaurus/pull/9696) fix(create-docusaurus): fix init template code blocks, and little improvements ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-plugin-pwa`
|
|
||||||
- [#9668](https://github.com/facebook/docusaurus/pull/9668) fix(pwa-plugin): upgrade workbox ([@SimenB](https://github.com/SimenB))
|
|
||||||
- `docusaurus`
|
|
||||||
- [#9648](https://github.com/facebook/docusaurus/pull/9648) fix(cli): output help when no conventional config + no subcommand ([@Josh-Cena](https://github.com/Josh-Cena))
|
|
||||||
- `docusaurus-theme-live-codeblock`
|
|
||||||
- [#9631](https://github.com/facebook/docusaurus/pull/9631) fix(live-codeblock): stabilize react-live transformCode callback, fix editor/preview desync ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-utils`
|
|
||||||
- [#9617](https://github.com/facebook/docusaurus/pull/9617) fix(utils): Markdown link replacement with <> but no spaces ([@Josh-Cena](https://github.com/Josh-Cena))
|
|
||||||
- `docusaurus-module-type-aliases`
|
|
||||||
- [#9612](https://github.com/facebook/docusaurus/pull/9612) fix(type-aliases): add `title` prop for imported inline SVG React components ([@axmmisaka](https://github.com/axmmisaka))
|
|
||||||
- `docusaurus-plugin-content-blog`
|
|
||||||
- [#9581](https://github.com/facebook/docusaurus/pull/9581) fix(content-blog): add baseUrl for author.image_url ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
- `docusaurus-theme-translations`
|
|
||||||
- [#9477](https://github.com/facebook/docusaurus/pull/9477) fix(i18n): complete translations for theme-common.json Brazilian Portuguese (pt-BR) ([@c0h1b4](https://github.com/c0h1b4))
|
|
||||||
|
|
||||||
#### :nail_care: Polish
|
|
||||||
|
|
||||||
- `docusaurus-theme-common`
|
|
||||||
- [#9335](https://github.com/facebook/docusaurus/pull/9335) refactor(theme-common): allow optional desktopBreakpoint param in useWindowSize ([@jgarrow](https://github.com/jgarrow))
|
|
||||||
|
|
||||||
#### :wrench: Maintenance
|
|
||||||
|
|
||||||
- `docusaurus-theme-search-algolia`
|
|
||||||
- [#9604](https://github.com/facebook/docusaurus/pull/9604) chore: add lint autofix CI job ([@slorber](https://github.com/slorber))
|
|
||||||
|
|
||||||
#### Committers: 8
|
|
||||||
|
|
||||||
- Janessa Garrow ([@jgarrow](https://github.com/jgarrow))
|
|
||||||
- Joshua Chen ([@Josh-Cena](https://github.com/Josh-Cena))
|
|
||||||
- Simen Bekkhus ([@SimenB](https://github.com/SimenB))
|
|
||||||
- Sébastien Lorber ([@slorber](https://github.com/slorber))
|
|
||||||
- Tatsunori Uchino ([@tats-u](https://github.com/tats-u))
|
|
||||||
- [@c0h1b4](https://github.com/c0h1b4)
|
|
||||||
- axmmisaka ([@axmmisaka](https://github.com/axmmisaka))
|
|
||||||
- ozaki ([@OzakIOne](https://github.com/OzakIOne))
|
|
||||||
|
|
||||||
## 3.0.1 (2023-11-30)
|
|
||||||
|
|
||||||
#### :bug: Bug Fix
|
|
||||||
|
|
||||||
- `docusaurus-utils`
|
|
||||||
- [#9570](https://github.com/facebook/docusaurus/pull/9570) fix: add v2 retrocompatible support for quoted admonitions ([@slorber](https://github.com/slorber))
|
|
||||||
- [#9535](https://github.com/facebook/docusaurus/pull/9535) fix: v3 admonitions should support v2 title syntax for nested admonitions ([@slorber](https://github.com/slorber))
|
|
||||||
- `create-docusaurus`, `docusaurus-theme-classic`, `docusaurus-theme-common`
|
|
||||||
- [#9567](https://github.com/facebook/docusaurus/pull/9567) fix(theme): upgrade prism-react-renderer, fix html script and style tag highlighting ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-theme-common`
|
|
||||||
- [#9531](https://github.com/facebook/docusaurus/pull/9531) fix(theme): docs html sidebar items should always be visible ([@slorber](https://github.com/slorber))
|
|
||||||
- `docusaurus-theme-classic`
|
|
||||||
- [#9530](https://github.com/facebook/docusaurus/pull/9530) fix(theme): fix firefox CSS :has() support bug ([@slorber](https://github.com/slorber))
|
|
||||||
- `create-docusaurus`
|
|
||||||
- [#9487](https://github.com/facebook/docusaurus/pull/9487) fix(create-docusaurus): fix readme docusaurus 2 ref ([@slorber](https://github.com/slorber))
|
|
||||||
|
|
||||||
#### :robot: Dependencies
|
|
||||||
|
|
||||||
- `docusaurus-plugin-debug`
|
|
||||||
- [#9566](https://github.com/facebook/docusaurus/pull/9566) chore(debug-plugin): migrate to a new maintained JSON Viewer ([@mcrstudio](https://github.com/mcrstudio))
|
|
||||||
- `create-docusaurus`, `docusaurus-theme-classic`, `docusaurus-theme-common`
|
|
||||||
- [#9572](https://github.com/facebook/docusaurus/pull/9572) chore: upgrade prism-react-renderer to 2.3.0 to avoid older clsx ([@harryzcy](https://github.com/harryzcy))
|
|
||||||
- [#9567](https://github.com/facebook/docusaurus/pull/9567) fix(theme): upgrade prism-react-renderer, fix html script and style tag highlighting ([@slorber](https://github.com/slorber))
|
|
||||||
- `create-docusaurus`, `docusaurus-plugin-pwa`, `docusaurus-theme-classic`, `docusaurus-theme-common`, `docusaurus-theme-live-codeblock`, `docusaurus-theme-search-algolia`
|
|
||||||
- [#9464](https://github.com/facebook/docusaurus/pull/9464) chore: Upgrade clsx to 2.0.0 ([@harryzcy](https://github.com/harryzcy))
|
|
||||||
- `docusaurus`
|
|
||||||
- [#9547](https://github.com/facebook/docusaurus/pull/9547) chore(core): replace `wait-on` dependency with custom lighter code ([@NickGerleman](https://github.com/NickGerleman))
|
|
||||||
- `docusaurus-plugin-pwa`, `docusaurus`
|
|
||||||
- [#9529](https://github.com/facebook/docusaurus/pull/9529) chore: ugrade babel dependencies to v7.23.3 ([@reece-white](https://github.com/reece-white))
|
|
||||||
|
|
||||||
#### Committers: 6
|
|
||||||
|
|
||||||
- Chongyi Zheng ([@harryzcy](https://github.com/harryzcy))
|
|
||||||
- MCR Studio ([@mcrstudio](https://github.com/mcrstudio))
|
|
||||||
- Nick Gerleman ([@NickGerleman](https://github.com/NickGerleman))
|
|
||||||
- Shreesh Nautiyal ([@Shreesh09](https://github.com/Shreesh09))
|
|
||||||
- Sébastien Lorber ([@slorber](https://github.com/slorber))
|
|
||||||
- [@reece-white](https://github.com/reece-white)
|
|
||||||
|
|
||||||
## 3.0.0 (2023-10-31)
|
## 3.0.0 (2023-10-31)
|
||||||
|
|
||||||
#### :boom: Breaking Change
|
#### :boom: Breaking Change
|
||||||
|
|
|
||||||
20
README.md
20
README.md
|
|
@ -1,13 +1,7 @@
|
||||||
<div align="center">
|
<h1 align="center">
|
||||||
<h1 align="center">
|
<p align="center">Docusaurus</p>
|
||||||
Docusaurus
|
<a href="https://docusaurus.io"><img src="https://docusaurus.io/img/slash-introducing.svg" alt="Docusaurus"></a>
|
||||||
<br />
|
</h1>
|
||||||
<br />
|
|
||||||
<a href="https://docusaurus.io">
|
|
||||||
<img src="https://docusaurus.io/img/slash-introducing.svg" alt="Docusaurus">
|
|
||||||
</a>
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://twitter.com/docusaurus"><img src="https://img.shields.io/twitter/follow/docusaurus.svg?style=social" align="right" alt="Twitter Follow" /></a>
|
<a href="https://twitter.com/docusaurus"><img src="https://img.shields.io/twitter/follow/docusaurus.svg?style=social" align="right" alt="Twitter Follow" /></a>
|
||||||
|
|
@ -20,13 +14,17 @@
|
||||||
<a href= "https://github.com/prettier/prettier"><img alt="code style: prettier" src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg"></a>
|
<a href= "https://github.com/prettier/prettier"><img alt="code style: prettier" src="https://img.shields.io/badge/code_style-prettier-ff69b4.svg"></a>
|
||||||
<a href="#license"><img src="https://img.shields.io/github/license/sourcerer-io/hall-of-fame.svg?colorB=ff0000"></a>
|
<a href="#license"><img src="https://img.shields.io/github/license/sourcerer-io/hall-of-fame.svg?colorB=ff0000"></a>
|
||||||
<a href="https://github.com/facebook/jest"><img src="https://img.shields.io/badge/tested_with-jest-99424f.svg" alt="Tested with Jest"></a>
|
<a href="https://github.com/facebook/jest"><img src="https://img.shields.io/badge/tested_with-jest-99424f.svg" alt="Tested with Jest"></a>
|
||||||
<a href="https://argos-ci.com" target="_blank" rel="noreferrer noopener" aria-label="Covered by Argos"><img src="https://argos-ci.com/badge.svg" alt="Covered by Argos" width="133" height="20" /></a>
|
|
||||||
<a href="https://gitpod.io/#https://github.com/facebook/docusaurus"><img src="https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod" alt="Gitpod Ready-to-Code"/></a>
|
<a href="https://gitpod.io/#https://github.com/facebook/docusaurus"><img src="https://img.shields.io/badge/Gitpod-Ready--to--Code-blue?logo=gitpod" alt="Gitpod Ready-to-Code"/></a>
|
||||||
<a href="https://app.netlify.com/sites/docusaurus-2/deploys"><img src="https://api.netlify.com/api/v1/badges/9e1ff559-4405-4ebe-8718-5e21c0774bc8/deploy-status" alt="Netlify Status"></a>
|
<a href="https://app.netlify.com/sites/docusaurus-2/deploys"><img src="https://api.netlify.com/api/v1/badges/9e1ff559-4405-4ebe-8718-5e21c0774bc8/deploy-status" alt="Netlify Status"></a>
|
||||||
|
<a href="https://meercode.io/facebook/docusaurus"><img src="https://meercode.io/badge/facebook/docusaurus?type=ci-score" alt="CI Score"></a>
|
||||||
<a href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Ffacebook%2Fdocusaurus%2Ftree%2Fmain%2Fexamples%2Fclassic&project-name=my-docusaurus-site&repo-name=my-docusaurus-site"><img src="https://vercel.com/button" alt="Deploy with Vercel"/></a>
|
<a href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Ffacebook%2Fdocusaurus%2Ftree%2Fmain%2Fexamples%2Fclassic&project-name=my-docusaurus-site&repo-name=my-docusaurus-site"><img src="https://vercel.com/button" alt="Deploy with Vercel"/></a>
|
||||||
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/slorber/docusaurus-starter"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify"></a>
|
<a href="https://app.netlify.com/start/deploy?repository=https://github.com/slorber/docusaurus-starter"><img src="https://www.netlify.com/img/deploy/button.svg" alt="Deploy to Netlify"></a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
> **We are working hard on Docusaurus v2. If you are new to Docusaurus, try using the new version instead of v1. See the [Docusaurus v2 website](https://docusaurus.io/) for more details.**
|
||||||
|
|
||||||
|
> Docusaurus v1 doc is available at [v1.docusaurus.io](https://v1.docusaurus.io) and code is available on branch [docusaurus-v1](https://github.com/facebook/docusaurus/tree/docusaurus-v1)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
Docusaurus is a project for building, deploying, and maintaining open source project websites easily.
|
Docusaurus is a project for building, deploying, and maintaining open source project websites easily.
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ const CookieName = 'DocusaurusPlaygroundName';
|
||||||
|
|
||||||
const PlaygroundConfigs = {
|
const PlaygroundConfigs = {
|
||||||
codesandbox:
|
codesandbox:
|
||||||
'https://codesandbox.io/p/sandbox/github/facebook/docusaurus/tree/main/examples/classic?file=%2FREADME.md&privacy=public',
|
'https://codesandbox.io/p/sandbox/github/facebook/docusaurus/tree/main/examples/classic?file=%2FREADME.md',
|
||||||
'codesandbox-ts':
|
'codesandbox-ts':
|
||||||
'https://codesandbox.io/p/sandbox/github/facebook/docusaurus/tree/main/examples/classic-typescript?file=%2FREADME.md&privacy=public',
|
'https://codesandbox.io/p/sandbox/github/facebook/docusaurus/tree/main/examples/classic-typescript?file=%2FREADME.md',
|
||||||
|
|
||||||
// Slow to load
|
// Slow to load
|
||||||
// stackblitz: 'https://stackblitz.com/github/facebook/docusaurus/tree/main/examples/classic',
|
// stackblitz: 'https://stackblitz.com/github/facebook/docusaurus/tree/main/examples/classic',
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "new.docusaurus.io",
|
"name": "new.docusaurus.io",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "npx --package netlify-cli netlify dev"
|
"start": "npx --package netlify-cli netlify dev"
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,7 @@ async function generateTemplateExample(template) {
|
||||||
// Run the docusaurus script to create the template in the examples folder
|
// Run the docusaurus script to create the template in the examples folder
|
||||||
const command = template.endsWith('-typescript')
|
const command = template.endsWith('-typescript')
|
||||||
? template.replace('-typescript', ' -- --typescript')
|
? template.replace('-typescript', ' -- --typescript')
|
||||||
: `${template} -- --javascript`;
|
: template;
|
||||||
|
|
||||||
shell.exec(
|
shell.exec(
|
||||||
// We use the published init script on purpose, because the local init is
|
// We use the published init script on purpose, because the local init is
|
||||||
// too new and could generate upcoming/unavailable config options.
|
// too new and could generate upcoming/unavailable config options.
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ git diff --name-only -- '*.json' | sed 's, ,\\&,g' | xargs git checkout --
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
# Build skeleton website with new version
|
# Build skeleton website with new version
|
||||||
npm_config_registry="$CUSTOM_REGISTRY_URL" npx create-docusaurus@"$NEW_VERSION" test-website classic --javascript $EXTRA_OPTS
|
npm_config_registry="$CUSTOM_REGISTRY_URL" npx create-docusaurus@"$NEW_VERSION" test-website classic $EXTRA_OPTS
|
||||||
|
|
||||||
# Stop Docker container
|
# Stop Docker container
|
||||||
if [[ -z "${KEEP_CONTAINER:-true}" ]] && ( $(docker container inspect "$CONTAINER_NAME" > /dev/null 2>&1) ); then
|
if [[ -z "${KEEP_CONTAINER:-true}" ]] && ( $(docker container inspect "$CONTAINER_NAME" > /dev/null 2>&1) ); then
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "argos",
|
"name": "argos",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Argos visual diff tests",
|
"description": "Argos visual diff tests",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|
@ -10,8 +10,8 @@
|
||||||
"report": "playwright show-report"
|
"report": "playwright show-report"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@argos-ci/playwright": "^1.9.3",
|
"@argos-ci/playwright": "^1.0.1",
|
||||||
"@playwright/test": "^1.41.2",
|
"@playwright/test": "^1.36.1",
|
||||||
"cheerio": "^1.0.0-rc.12"
|
"cheerio": "^1.0.0-rc.12"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ tags: [greetings]
|
||||||
|
|
||||||
Congratulations, you have made your first post!
|
Congratulations, you have made your first post!
|
||||||
|
|
||||||
Feel free to play around and edit this post as much as you like.
|
Feel free to play around and edit this post as much you like.
|
||||||
```
|
```
|
||||||
|
|
||||||
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
|
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,13 @@ You can reference images relative to the current file as well. This is particula
|
||||||
|
|
||||||
Markdown code blocks are supported with Syntax highlighting.
|
Markdown code blocks are supported with Syntax highlighting.
|
||||||
|
|
||||||
````md
|
```jsx title="src/components/HelloDocusaurus.js"
|
||||||
```jsx title="src/components/HelloDocusaurus.js"
|
function HelloDocusaurus() {
|
||||||
function HelloDocusaurus() {
|
return (
|
||||||
return <h1>Hello, Docusaurus!</h1>;
|
<h1>Hello, Docusaurus!</h1>
|
||||||
}
|
)
|
||||||
```
|
}
|
||||||
````
|
```
|
||||||
|
|
||||||
```jsx title="src/components/HelloDocusaurus.js"
|
```jsx title="src/components/HelloDocusaurus.js"
|
||||||
function HelloDocusaurus() {
|
function HelloDocusaurus() {
|
||||||
|
|
@ -79,19 +79,17 @@ function HelloDocusaurus() {
|
||||||
|
|
||||||
Docusaurus has a special syntax to create admonitions and callouts:
|
Docusaurus has a special syntax to create admonitions and callouts:
|
||||||
|
|
||||||
```md
|
:::tip My tip
|
||||||
:::tip My tip
|
|
||||||
|
|
||||||
Use this awesome feature option
|
Use this awesome feature option
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::danger Take care
|
:::danger Take care
|
||||||
|
|
||||||
This action is dangerous
|
This action is dangerous
|
||||||
|
|
||||||
:::
|
:::
|
||||||
```
|
|
||||||
|
|
||||||
:::tip My tip
|
:::tip My tip
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,18 +16,18 @@
|
||||||
"dev": "docusaurus start"
|
"dev": "docusaurus start"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.0.0",
|
||||||
"@docusaurus/preset-classic": "3.2.0",
|
"@docusaurus/preset-classic": "3.0.0",
|
||||||
"@mdx-js/react": "^3.0.0",
|
"@mdx-js/react": "^3.0.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^1.2.1",
|
||||||
"prism-react-renderer": "^2.3.0",
|
"prism-react-renderer": "^2.1.0",
|
||||||
"react": "^18.0.0",
|
"react": "^18.0.0",
|
||||||
"react-dom": "^18.0.0"
|
"react-dom": "^18.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "3.2.0",
|
"@docusaurus/module-type-aliases": "3.0.0",
|
||||||
"@docusaurus/tsconfig": "3.2.0",
|
"@docusaurus/tsconfig": "3.0.0",
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.0.0",
|
||||||
"typescript": "~5.2.2"
|
"typescript": "~5.2.2"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -28,7 +28,7 @@ tags: [greetings]
|
||||||
|
|
||||||
Congratulations, you have made your first post!
|
Congratulations, you have made your first post!
|
||||||
|
|
||||||
Feel free to play around and edit this post as much as you like.
|
Feel free to play around and edit this post as much you like.
|
||||||
```
|
```
|
||||||
|
|
||||||
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
|
A new blog post is now available at [http://localhost:3000/blog/greetings](http://localhost:3000/blog/greetings).
|
||||||
|
|
|
||||||
|
|
@ -61,13 +61,13 @@ You can reference images relative to the current file as well. This is particula
|
||||||
|
|
||||||
Markdown code blocks are supported with Syntax highlighting.
|
Markdown code blocks are supported with Syntax highlighting.
|
||||||
|
|
||||||
````md
|
```jsx title="src/components/HelloDocusaurus.js"
|
||||||
```jsx title="src/components/HelloDocusaurus.js"
|
function HelloDocusaurus() {
|
||||||
function HelloDocusaurus() {
|
return (
|
||||||
return <h1>Hello, Docusaurus!</h1>;
|
<h1>Hello, Docusaurus!</h1>
|
||||||
}
|
)
|
||||||
```
|
}
|
||||||
````
|
```
|
||||||
|
|
||||||
```jsx title="src/components/HelloDocusaurus.js"
|
```jsx title="src/components/HelloDocusaurus.js"
|
||||||
function HelloDocusaurus() {
|
function HelloDocusaurus() {
|
||||||
|
|
@ -79,19 +79,17 @@ function HelloDocusaurus() {
|
||||||
|
|
||||||
Docusaurus has a special syntax to create admonitions and callouts:
|
Docusaurus has a special syntax to create admonitions and callouts:
|
||||||
|
|
||||||
```md
|
:::tip My tip
|
||||||
:::tip My tip
|
|
||||||
|
|
||||||
Use this awesome feature option
|
Use this awesome feature option
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
:::danger Take care
|
:::danger Take care
|
||||||
|
|
||||||
This action is dangerous
|
This action is dangerous
|
||||||
|
|
||||||
:::
|
:::
|
||||||
```
|
|
||||||
|
|
||||||
:::tip My tip
|
:::tip My tip
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,17 +15,17 @@
|
||||||
"dev": "docusaurus start"
|
"dev": "docusaurus start"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.0.0",
|
||||||
"@docusaurus/preset-classic": "3.2.0",
|
"@docusaurus/preset-classic": "3.0.0",
|
||||||
"@mdx-js/react": "^3.0.0",
|
"@mdx-js/react": "^3.0.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^1.2.1",
|
||||||
"prism-react-renderer": "^2.3.0",
|
"prism-react-renderer": "^2.1.0",
|
||||||
"react": "^18.0.0",
|
"react": "^18.0.0",
|
||||||
"react-dom": "^18.0.0"
|
"react-dom": "^18.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "3.2.0",
|
"@docusaurus/module-type-aliases": "3.0.0",
|
||||||
"@docusaurus/types": "3.2.0"
|
"@docusaurus/types": "3.0.0"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"npmClient": "yarn",
|
"npmClient": "yarn",
|
||||||
"useWorkspaces": true,
|
"useWorkspaces": true,
|
||||||
"useNx": false,
|
"useNx": false,
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ For Docusaurus maintainers, templates can be tested with:
|
||||||
```bash
|
```bash
|
||||||
cd `git rev-parse --show-toplevel` # Back to repo root
|
cd `git rev-parse --show-toplevel` # Back to repo root
|
||||||
rm -rf test-website
|
rm -rf test-website
|
||||||
yarn create-docusaurus test-website classic --javascript
|
yarn create-docusaurus test-website classic
|
||||||
cd test-website
|
cd test-website
|
||||||
yarn start
|
yarn start
|
||||||
```
|
```
|
||||||
|
|
@ -37,7 +37,7 @@ Use the following to test the templates against local packages:
|
||||||
```bash
|
```bash
|
||||||
cd `git rev-parse --show-toplevel` # Back to repo root
|
cd `git rev-parse --show-toplevel` # Back to repo root
|
||||||
rm -rf test-website-in-workspace
|
rm -rf test-website-in-workspace
|
||||||
yarn create-docusaurus test-website-in-workspace classic --javascript
|
yarn create-docusaurus test-website-in-workspace classic
|
||||||
cd test-website-in-workspace
|
cd test-website-in-workspace
|
||||||
yarn build
|
yarn build
|
||||||
yarn start
|
yarn start
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,6 @@ program
|
||||||
'Do not run package manager immediately after scaffolding',
|
'Do not run package manager immediately after scaffolding',
|
||||||
)
|
)
|
||||||
.option('-t, --typescript', 'Use the TypeScript template variant')
|
.option('-t, --typescript', 'Use the TypeScript template variant')
|
||||||
.option('-j, --javascript', 'Use the JavaScript template variant')
|
|
||||||
.option(
|
.option(
|
||||||
'-g, --git-strategy <strategy>',
|
'-g, --git-strategy <strategy>',
|
||||||
`Only used if the template is a git repository.
|
`Only used if the template is a git repository.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "create-docusaurus",
|
"name": "create-docusaurus",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Create Docusaurus apps easily.",
|
"description": "Create Docusaurus apps easily.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
@ -22,8 +22,8 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/logger": "3.2.0",
|
"@docusaurus/logger": "3.1.1",
|
||||||
"@docusaurus/utils": "3.2.0",
|
"@docusaurus/utils": "3.1.1",
|
||||||
"commander": "^5.1.0",
|
"commander": "^5.1.0",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
|
|
||||||
|
|
@ -13,29 +13,15 @@ import logger from '@docusaurus/logger';
|
||||||
import shell from 'shelljs';
|
import shell from 'shelljs';
|
||||||
import prompts, {type Choice} from 'prompts';
|
import prompts, {type Choice} from 'prompts';
|
||||||
import supportsColor from 'supports-color';
|
import supportsColor from 'supports-color';
|
||||||
import {escapeShellArg, askPreferredLanguage} from '@docusaurus/utils';
|
import {escapeShellArg} from '@docusaurus/utils';
|
||||||
|
|
||||||
type LanguagesOptions = {
|
type CLIOptions = {
|
||||||
javascript?: boolean;
|
|
||||||
typescript?: boolean;
|
|
||||||
};
|
|
||||||
|
|
||||||
type CLIOptions = LanguagesOptions & {
|
|
||||||
packageManager?: PackageManager;
|
packageManager?: PackageManager;
|
||||||
skipInstall?: boolean;
|
skipInstall?: boolean;
|
||||||
|
typescript?: boolean;
|
||||||
gitStrategy?: GitStrategy;
|
gitStrategy?: GitStrategy;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getLanguage(options: LanguagesOptions) {
|
|
||||||
if (options.typescript) {
|
|
||||||
return 'typescript';
|
|
||||||
}
|
|
||||||
if (options.javascript) {
|
|
||||||
return 'javascript';
|
|
||||||
}
|
|
||||||
return askPreferredLanguage();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only used in the rare, rare case of running globally installed create +
|
// Only used in the rare, rare case of running globally installed create +
|
||||||
// using --skip-install. We need a default name to show the tip text
|
// using --skip-install. We need a default name to show the tip text
|
||||||
const defaultPackageManager = 'npm';
|
const defaultPackageManager = 'npm';
|
||||||
|
|
@ -167,14 +153,11 @@ async function readTemplates(): Promise<Template[]> {
|
||||||
async function copyTemplate(
|
async function copyTemplate(
|
||||||
template: Template,
|
template: Template,
|
||||||
dest: string,
|
dest: string,
|
||||||
language: 'javascript' | 'typescript',
|
typescript: boolean,
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
await fs.copy(path.join(templatesDir, 'shared'), dest);
|
await fs.copy(path.join(templatesDir, 'shared'), dest);
|
||||||
|
|
||||||
const sourcePath =
|
await fs.copy(typescript ? template.tsVariantPath! : template.path, dest, {
|
||||||
language === 'typescript' ? template.tsVariantPath! : template.path;
|
|
||||||
|
|
||||||
await fs.copy(sourcePath, dest, {
|
|
||||||
// Symlinks don't exist in published npm packages anymore, so this is only
|
// Symlinks don't exist in published npm packages anymore, so this is only
|
||||||
// to prevent errors during local testing
|
// to prevent errors during local testing
|
||||||
filter: async (filePath) => !(await fs.lstat(filePath)).isSymbolicLink(),
|
filter: async (filePath) => !(await fs.lstat(filePath)).isSymbolicLink(),
|
||||||
|
|
@ -200,33 +183,6 @@ function createTemplateChoices(templates: Template[]): Choice[] {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function askTemplateChoice({
|
|
||||||
templates,
|
|
||||||
cliOptions,
|
|
||||||
}: {
|
|
||||||
templates: Template[];
|
|
||||||
cliOptions: CLIOptions;
|
|
||||||
}) {
|
|
||||||
return cliOptions.gitStrategy
|
|
||||||
? 'Git repository'
|
|
||||||
: (
|
|
||||||
(await prompts(
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
name: 'template',
|
|
||||||
message: 'Select a template below...',
|
|
||||||
choices: createTemplateChoices(templates),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onCancel() {
|
|
||||||
logger.error('A choice is required.');
|
|
||||||
process.exit(1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)) as {template: Template | 'Git repository' | 'Local template'}
|
|
||||||
).template;
|
|
||||||
}
|
|
||||||
|
|
||||||
function isValidGitRepoUrl(gitRepoUrl: string): boolean {
|
function isValidGitRepoUrl(gitRepoUrl: string): boolean {
|
||||||
return ['https://', 'git@'].some((item) => gitRepoUrl.startsWith(item));
|
return ['https://', 'git@'].some((item) => gitRepoUrl.startsWith(item));
|
||||||
}
|
}
|
||||||
|
|
@ -304,7 +260,7 @@ type Source =
|
||||||
| {
|
| {
|
||||||
type: 'template';
|
type: 'template';
|
||||||
template: Template;
|
template: Template;
|
||||||
language: 'javascript' | 'typescript';
|
typescript: boolean;
|
||||||
}
|
}
|
||||||
| {
|
| {
|
||||||
type: 'git';
|
type: 'git';
|
||||||
|
|
@ -316,193 +272,166 @@ type Source =
|
||||||
path: string;
|
path: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function createTemplateSource({
|
|
||||||
template,
|
|
||||||
cliOptions,
|
|
||||||
}: {
|
|
||||||
template: Template;
|
|
||||||
cliOptions: CLIOptions;
|
|
||||||
}): Promise<Source> {
|
|
||||||
const language = await getLanguage(cliOptions);
|
|
||||||
if (language === 'typescript' && !template.tsVariantPath) {
|
|
||||||
logger.error`Template name=${template.name} doesn't provide a TypeScript variant.`;
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: 'template',
|
|
||||||
template,
|
|
||||||
language,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getTemplateSource({
|
|
||||||
templateName,
|
|
||||||
templates,
|
|
||||||
cliOptions,
|
|
||||||
}: {
|
|
||||||
templateName: string;
|
|
||||||
templates: Template[];
|
|
||||||
cliOptions: CLIOptions;
|
|
||||||
}): Promise<Source> {
|
|
||||||
const template = templates.find((t) => t.name === templateName);
|
|
||||||
if (!template) {
|
|
||||||
logger.error('Invalid template.');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
return createTemplateSource({template, cliOptions});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the template source explicitly requested by the user provided cli option
|
|
||||||
async function getUserProvidedSource({
|
|
||||||
reqTemplate,
|
|
||||||
templates,
|
|
||||||
cliOptions,
|
|
||||||
}: {
|
|
||||||
reqTemplate: string;
|
|
||||||
templates: Template[];
|
|
||||||
cliOptions: CLIOptions;
|
|
||||||
}): Promise<Source> {
|
|
||||||
if (isValidGitRepoUrl(reqTemplate)) {
|
|
||||||
if (
|
|
||||||
cliOptions.gitStrategy &&
|
|
||||||
!gitStrategies.includes(cliOptions.gitStrategy)
|
|
||||||
) {
|
|
||||||
logger.error`Invalid git strategy: name=${
|
|
||||||
cliOptions.gitStrategy
|
|
||||||
}. Value must be one of ${gitStrategies.join(', ')}.`;
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: 'git',
|
|
||||||
url: reqTemplate,
|
|
||||||
strategy: cliOptions.gitStrategy ?? 'deep',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (await fs.pathExists(path.resolve(reqTemplate))) {
|
|
||||||
return {
|
|
||||||
type: 'local',
|
|
||||||
path: path.resolve(reqTemplate),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return getTemplateSource({
|
|
||||||
templateName: reqTemplate,
|
|
||||||
templates,
|
|
||||||
cliOptions,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function askGitRepositorySource({
|
|
||||||
cliOptions,
|
|
||||||
}: {
|
|
||||||
cliOptions: CLIOptions;
|
|
||||||
}): Promise<Source> {
|
|
||||||
const {gitRepoUrl} = (await prompts(
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
name: 'gitRepoUrl',
|
|
||||||
validate: (url?: string) => {
|
|
||||||
if (url && isValidGitRepoUrl(url)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return logger.red('Invalid repository URL');
|
|
||||||
},
|
|
||||||
message: logger.interpolate`Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.
|
|
||||||
(e.g: url=${'https://github.com/ownerName/repoName.git'})`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onCancel() {
|
|
||||||
logger.error('A git repo URL is required.');
|
|
||||||
process.exit(1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)) as {gitRepoUrl: string};
|
|
||||||
let strategy = cliOptions.gitStrategy;
|
|
||||||
if (!strategy) {
|
|
||||||
({strategy} = (await prompts(
|
|
||||||
{
|
|
||||||
type: 'select',
|
|
||||||
name: 'strategy',
|
|
||||||
message: 'How should we clone this repo?',
|
|
||||||
choices: [
|
|
||||||
{title: 'Deep clone: preserve full history', value: 'deep'},
|
|
||||||
{title: 'Shallow clone: clone with --depth=1', value: 'shallow'},
|
|
||||||
{
|
|
||||||
title: 'Copy: do a shallow clone, but do not create a git repo',
|
|
||||||
value: 'copy',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Custom: enter your custom git clone command',
|
|
||||||
value: 'custom',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onCancel() {
|
|
||||||
logger.info`Falling back to name=${'deep'}`;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)) as {strategy?: GitStrategy});
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
type: 'git',
|
|
||||||
url: gitRepoUrl,
|
|
||||||
strategy: strategy ?? 'deep',
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function askLocalSource(): Promise<Source> {
|
|
||||||
const {templateDir} = (await prompts(
|
|
||||||
{
|
|
||||||
type: 'text',
|
|
||||||
name: 'templateDir',
|
|
||||||
validate: async (dir?: string) => {
|
|
||||||
if (dir) {
|
|
||||||
const fullDir = path.resolve(dir);
|
|
||||||
if (await fs.pathExists(fullDir)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return logger.red(
|
|
||||||
logger.interpolate`path=${fullDir} does not exist.`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return logger.red('Please enter a valid path.');
|
|
||||||
},
|
|
||||||
message:
|
|
||||||
'Enter a local folder path, relative to the current working directory.',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
onCancel() {
|
|
||||||
logger.error('A file path is required.');
|
|
||||||
process.exit(1);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
)) as {templateDir: string};
|
|
||||||
return {
|
|
||||||
type: 'local',
|
|
||||||
path: templateDir,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getSource(
|
async function getSource(
|
||||||
reqTemplate: string | undefined,
|
reqTemplate: string | undefined,
|
||||||
templates: Template[],
|
templates: Template[],
|
||||||
cliOptions: CLIOptions,
|
cliOptions: CLIOptions,
|
||||||
): Promise<Source> {
|
): Promise<Source> {
|
||||||
if (reqTemplate) {
|
if (reqTemplate) {
|
||||||
return getUserProvidedSource({reqTemplate, templates, cliOptions});
|
if (isValidGitRepoUrl(reqTemplate)) {
|
||||||
|
if (
|
||||||
|
cliOptions.gitStrategy &&
|
||||||
|
!gitStrategies.includes(cliOptions.gitStrategy)
|
||||||
|
) {
|
||||||
|
logger.error`Invalid git strategy: name=${
|
||||||
|
cliOptions.gitStrategy
|
||||||
|
}. Value must be one of ${gitStrategies.join(', ')}.`;
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'git',
|
||||||
|
url: reqTemplate,
|
||||||
|
strategy: cliOptions.gitStrategy ?? 'deep',
|
||||||
|
};
|
||||||
|
} else if (await fs.pathExists(path.resolve(reqTemplate))) {
|
||||||
|
return {
|
||||||
|
type: 'local',
|
||||||
|
path: path.resolve(reqTemplate),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
const template = templates.find((t) => t.name === reqTemplate);
|
||||||
|
if (!template) {
|
||||||
|
logger.error('Invalid template.');
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
if (cliOptions.typescript && !template.tsVariantPath) {
|
||||||
|
logger.error`Template name=${reqTemplate} doesn't provide the TypeScript variant.`;
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'template',
|
||||||
|
template,
|
||||||
|
typescript: cliOptions.typescript ?? false,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
const template = cliOptions.gitStrategy
|
||||||
const template = await askTemplateChoice({templates, cliOptions});
|
? 'Git repository'
|
||||||
|
: (
|
||||||
|
(await prompts(
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'template',
|
||||||
|
message: 'Select a template below...',
|
||||||
|
choices: createTemplateChoices(templates),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel() {
|
||||||
|
logger.error('A choice is required.');
|
||||||
|
process.exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)) as {template: Template | 'Git repository' | 'Local template'}
|
||||||
|
).template;
|
||||||
if (template === 'Git repository') {
|
if (template === 'Git repository') {
|
||||||
return askGitRepositorySource({cliOptions});
|
const {gitRepoUrl} = (await prompts(
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name: 'gitRepoUrl',
|
||||||
|
validate: (url?: string) => {
|
||||||
|
if (url && isValidGitRepoUrl(url)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return logger.red('Invalid repository URL');
|
||||||
|
},
|
||||||
|
message: logger.interpolate`Enter a repository URL from GitHub, Bitbucket, GitLab, or any other public repo.
|
||||||
|
(e.g: url=${'https://github.com/ownerName/repoName.git'})`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel() {
|
||||||
|
logger.error('A git repo URL is required.');
|
||||||
|
process.exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)) as {gitRepoUrl: string};
|
||||||
|
let strategy = cliOptions.gitStrategy;
|
||||||
|
if (!strategy) {
|
||||||
|
({strategy} = (await prompts(
|
||||||
|
{
|
||||||
|
type: 'select',
|
||||||
|
name: 'strategy',
|
||||||
|
message: 'How should we clone this repo?',
|
||||||
|
choices: [
|
||||||
|
{title: 'Deep clone: preserve full history', value: 'deep'},
|
||||||
|
{title: 'Shallow clone: clone with --depth=1', value: 'shallow'},
|
||||||
|
{
|
||||||
|
title: 'Copy: do a shallow clone, but do not create a git repo',
|
||||||
|
value: 'copy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Custom: enter your custom git clone command',
|
||||||
|
value: 'custom',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel() {
|
||||||
|
logger.info`Falling back to name=${'deep'}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)) as {strategy?: GitStrategy});
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
type: 'git',
|
||||||
|
url: gitRepoUrl,
|
||||||
|
strategy: strategy ?? 'deep',
|
||||||
|
};
|
||||||
|
} else if (template === 'Local template') {
|
||||||
|
const {templateDir} = (await prompts(
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name: 'templateDir',
|
||||||
|
validate: async (dir?: string) => {
|
||||||
|
if (dir) {
|
||||||
|
const fullDir = path.resolve(dir);
|
||||||
|
if (await fs.pathExists(fullDir)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return logger.red(
|
||||||
|
logger.interpolate`path=${fullDir} does not exist.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return logger.red('Please enter a valid path.');
|
||||||
|
},
|
||||||
|
message:
|
||||||
|
'Enter a local folder path, relative to the current working directory.',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
onCancel() {
|
||||||
|
logger.error('A file path is required.');
|
||||||
|
process.exit(1);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)) as {templateDir: string};
|
||||||
|
return {
|
||||||
|
type: 'local',
|
||||||
|
path: templateDir,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
if (template === 'Local template') {
|
let useTS = cliOptions.typescript;
|
||||||
return askLocalSource();
|
if (!useTS && template.tsVariantPath) {
|
||||||
|
({useTS} = (await prompts({
|
||||||
|
type: 'confirm',
|
||||||
|
name: 'useTS',
|
||||||
|
message:
|
||||||
|
'This template is available in TypeScript. Do you want to use the TS variant?',
|
||||||
|
initial: false,
|
||||||
|
})) as {useTS?: boolean});
|
||||||
}
|
}
|
||||||
return createTemplateSource({
|
return {
|
||||||
|
type: 'template',
|
||||||
template,
|
template,
|
||||||
cliOptions,
|
typescript: useTS ?? false,
|
||||||
});
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updatePkg(pkgPath: string, obj: {[key: string]: unknown}) {
|
async function updatePkg(pkgPath: string, obj: {[key: string]: unknown}) {
|
||||||
|
|
@ -523,7 +452,6 @@ export default async function init(
|
||||||
getSiteName(reqName, rootDir),
|
getSiteName(reqName, rootDir),
|
||||||
]);
|
]);
|
||||||
const dest = path.resolve(rootDir, siteName);
|
const dest = path.resolve(rootDir, siteName);
|
||||||
|
|
||||||
const source = await getSource(reqTemplate, templates, cliOptions);
|
const source = await getSource(reqTemplate, templates, cliOptions);
|
||||||
|
|
||||||
logger.info('Creating new Docusaurus project...');
|
logger.info('Creating new Docusaurus project...');
|
||||||
|
|
@ -542,7 +470,7 @@ export default async function init(
|
||||||
}
|
}
|
||||||
} else if (source.type === 'template') {
|
} else if (source.type === 'template') {
|
||||||
try {
|
try {
|
||||||
await copyTemplate(source.template, dest, source.language);
|
await copyTemplate(source.template, dest, source.typescript);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error`Copying Docusaurus template name=${source.template.name} failed!`;
|
logger.error`Copying Docusaurus template name=${source.template.name} failed!`;
|
||||||
throw err;
|
throw err;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "docusaurus-2-classic-typescript-template",
|
"name": "docusaurus-2-classic-typescript-template",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"docusaurus": "docusaurus",
|
"docusaurus": "docusaurus",
|
||||||
|
|
@ -15,8 +15,8 @@
|
||||||
"typecheck": "tsc"
|
"typecheck": "tsc"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.1.1",
|
||||||
"@docusaurus/preset-classic": "3.2.0",
|
"@docusaurus/preset-classic": "3.1.1",
|
||||||
"@mdx-js/react": "^3.0.0",
|
"@mdx-js/react": "^3.0.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"prism-react-renderer": "^2.3.0",
|
"prism-react-renderer": "^2.3.0",
|
||||||
|
|
@ -24,9 +24,9 @@
|
||||||
"react-dom": "^18.0.0"
|
"react-dom": "^18.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "3.2.0",
|
"@docusaurus/module-type-aliases": "3.1.1",
|
||||||
"@docusaurus/tsconfig": "3.2.0",
|
"@docusaurus/tsconfig": "3.1.1",
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.1.1",
|
||||||
"typescript": "~5.2.2"
|
"typescript": "~5.2.2"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "docusaurus-2-classic-template",
|
"name": "docusaurus-2-classic-template",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"docusaurus": "docusaurus",
|
"docusaurus": "docusaurus",
|
||||||
|
|
@ -14,8 +14,8 @@
|
||||||
"write-heading-ids": "docusaurus write-heading-ids"
|
"write-heading-ids": "docusaurus write-heading-ids"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.1.1",
|
||||||
"@docusaurus/preset-classic": "3.2.0",
|
"@docusaurus/preset-classic": "3.1.1",
|
||||||
"@mdx-js/react": "^3.0.0",
|
"@mdx-js/react": "^3.0.0",
|
||||||
"clsx": "^2.0.0",
|
"clsx": "^2.0.0",
|
||||||
"prism-react-renderer": "^2.3.0",
|
"prism-react-renderer": "^2.3.0",
|
||||||
|
|
@ -23,8 +23,8 @@
|
||||||
"react-dom": "^18.0.0"
|
"react-dom": "^18.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/module-type-aliases": "3.2.0",
|
"@docusaurus/module-type-aliases": "3.1.1",
|
||||||
"@docusaurus/types": "3.2.0"
|
"@docusaurus/types": "3.1.1"
|
||||||
},
|
},
|
||||||
"browserslist": {
|
"browserslist": {
|
||||||
"production": [
|
"production": [
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/cssnano-preset",
|
"name": "@docusaurus/cssnano-preset",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Advanced cssnano preset for maximum optimization.",
|
"description": "Advanced cssnano preset for maximum optimization.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/logger",
|
"name": "@docusaurus/logger",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "An encapsulated logger for semantically formatting console messages.",
|
"description": "An encapsulated logger for semantically formatting console messages.",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/mdx-loader",
|
"name": "@docusaurus/mdx-loader",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Docusaurus Loader for MDX",
|
"description": "Docusaurus Loader for MDX",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
|
|
@ -18,9 +18,11 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/logger": "3.2.0",
|
"@babel/parser": "^7.22.7",
|
||||||
"@docusaurus/utils": "3.2.0",
|
"@babel/traverse": "^7.22.8",
|
||||||
"@docusaurus/utils-validation": "3.2.0",
|
"@docusaurus/logger": "3.1.1",
|
||||||
|
"@docusaurus/utils": "3.1.1",
|
||||||
|
"@docusaurus/utils-validation": "3.1.1",
|
||||||
"@mdx-js/mdx": "^3.0.0",
|
"@mdx-js/mdx": "^3.0.0",
|
||||||
"@slorber/remark-comment": "^1.0.0",
|
"@slorber/remark-comment": "^1.0.0",
|
||||||
"escape-html": "^1.0.3",
|
"escape-html": "^1.0.3",
|
||||||
|
|
@ -44,7 +46,7 @@
|
||||||
"webpack": "^5.88.1"
|
"webpack": "^5.88.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.1.1",
|
||||||
"@types/escape-html": "^1.0.2",
|
"@types/escape-html": "^1.0.2",
|
||||||
"@types/mdast": "^4.0.2",
|
"@types/mdast": "^4.0.2",
|
||||||
"@types/stringify-object": "^3.3.1",
|
"@types/stringify-object": "^3.3.1",
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
import {mdxLoader} from './loader';
|
import {mdxLoader} from './loader';
|
||||||
|
|
||||||
import type {TOCItem as TOCItemImported} from './remark/toc/types';
|
import type {TOCItem as TOCItemImported} from './remark/toc';
|
||||||
|
|
||||||
export default mdxLoader;
|
export default mdxLoader;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,21 +71,6 @@ some **markdown** *content*
|
||||||
expect(result.data.contentTitle).toBeUndefined();
|
expect(result.data.contentTitle).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('ignore contentTitle if after thematic break', async () => {
|
|
||||||
const result = await process(`
|
|
||||||
|
|
||||||
Hey
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
# contentTitle 1
|
|
||||||
|
|
||||||
some **markdown** *content*
|
|
||||||
`);
|
|
||||||
|
|
||||||
expect(result.data.contentTitle).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is able to decently serialize Markdown syntax', async () => {
|
it('is able to decently serialize Markdown syntax', async () => {
|
||||||
const result = await process(`
|
const result = await process(`
|
||||||
# some **markdown** \`content\` _italic_
|
# some **markdown** \`content\` _italic_
|
||||||
|
|
|
||||||
|
|
@ -34,24 +34,17 @@ const plugin: Plugin = function plugin(
|
||||||
const {toString} = await import('mdast-util-to-string');
|
const {toString} = await import('mdast-util-to-string');
|
||||||
const {visit, EXIT} = await import('unist-util-visit');
|
const {visit, EXIT} = await import('unist-util-visit');
|
||||||
|
|
||||||
visit(root, ['heading', 'thematicBreak'], (node, index, parent) => {
|
visit(root, 'heading', (headingNode: Heading, index, parent) => {
|
||||||
if (node.type === 'heading') {
|
if (headingNode.depth === 1) {
|
||||||
const headingNode = node as Heading;
|
vfile.data.contentTitle = toString(headingNode);
|
||||||
if (headingNode.depth === 1) {
|
if (removeContentTitle) {
|
||||||
vfile.data.contentTitle = toString(headingNode);
|
// @ts-expect-error: TODO how to fix?
|
||||||
if (removeContentTitle) {
|
parent!.children.splice(index, 1);
|
||||||
// @ts-expect-error: TODO how to fix?
|
|
||||||
parent!.children.splice(index, 1);
|
|
||||||
}
|
|
||||||
return EXIT; // We only handle the very first heading
|
|
||||||
}
|
|
||||||
// We only handle contentTitle if it's the very first heading found
|
|
||||||
if (headingNode.depth >= 1) {
|
|
||||||
return EXIT;
|
|
||||||
}
|
}
|
||||||
|
return EXIT; // We only handle the very first heading
|
||||||
}
|
}
|
||||||
// We only handle contentTitle when it's above the first thematic break
|
// We only handle contentTitle if it's the very first heading found
|
||||||
if (node.type === 'thematicBreak') {
|
if (headingNode.depth >= 1) {
|
||||||
return EXIT;
|
return EXIT;
|
||||||
}
|
}
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
export default function SomeComponent() {
|
|
||||||
return <div>Some component</div>;
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
## Partial 1
|
|
||||||
|
|
||||||
Partial 1
|
|
||||||
|
|
||||||
### Partial 1 Sub Heading
|
|
||||||
|
|
||||||
Content
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
## Partial 2 Nested
|
|
||||||
|
|
||||||
Partial 2 Nested
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
## Partial 2
|
|
||||||
|
|
||||||
Partial 2
|
|
||||||
|
|
||||||
### Partial 2 Sub Heading
|
|
||||||
|
|
||||||
Content
|
|
||||||
|
|
||||||
import Partial2Nested from './partial2-nested.md';
|
|
||||||
|
|
||||||
<Partial2Nested />
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
## Partial 3
|
|
||||||
|
|
||||||
Partial 3
|
|
||||||
|
|
||||||
### Partial 3 Sub Heading
|
|
||||||
|
|
||||||
Content
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
import Partial1 from './_partial1.md';
|
|
||||||
|
|
||||||
import SomeComponent from './SomeComponent';
|
|
||||||
|
|
||||||
# Index
|
|
||||||
|
|
||||||
Some text
|
|
||||||
|
|
||||||
import Partial2 from './_partial2.md';
|
|
||||||
|
|
||||||
## Index section 1
|
|
||||||
|
|
||||||
Foo
|
|
||||||
|
|
||||||
<Partial1 />
|
|
||||||
|
|
||||||
Some text
|
|
||||||
|
|
||||||
<SomeComponent />
|
|
||||||
|
|
||||||
## Index section 2
|
|
||||||
|
|
||||||
<Partial2 />
|
|
||||||
|
|
||||||
## Unused partials
|
|
||||||
|
|
||||||
Unused partials (that are only imported but not rendered) shouldn't alter the TOC
|
|
||||||
|
|
||||||
import UnusedPartialImport from './_partial3.md';
|
|
||||||
|
|
||||||
## NonExisting Partials
|
|
||||||
|
|
||||||
Partials that do not exist should alter the TOC
|
|
||||||
|
|
||||||
It's not the responsibility of the Remark plugin to check for their existence
|
|
||||||
|
|
||||||
import DoesNotExist from './_doesNotExist.md';
|
|
||||||
|
|
||||||
<DoesNotExist />
|
|
||||||
|
|
||||||
## Duplicate partials
|
|
||||||
|
|
||||||
It's fine if we use partials at the end
|
|
||||||
|
|
||||||
<Partial1 />
|
|
||||||
|
|
||||||
And we can use the partial multiple times!
|
|
||||||
|
|
||||||
<Partial1 />
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
# Partial used before import
|
|
||||||
|
|
||||||
While it looks weird to import after usage, this remains valid MDX usage.
|
|
||||||
|
|
||||||
<Partial />
|
|
||||||
|
|
||||||
import Partial from './_partial.md';
|
|
||||||
|
|
@ -1,601 +1,238 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`toc remark plugin does not overwrite TOC var if no TOC 1`] = `
|
exports[`toc remark plugin does not overwrite TOC var if no TOC 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"foo
|
||||||
|
|
||||||
|
\`bar\`
|
||||||
|
|
||||||
|
\`\`\`js
|
||||||
|
baz
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
export const toc = 1;
|
export const toc = 1;
|
||||||
function _createMdxContent(props) {
|
|
||||||
const _components = {
|
|
||||||
code: "code",
|
|
||||||
p: "p",
|
|
||||||
pre: "pre",
|
|
||||||
...props.components
|
|
||||||
};
|
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.p, {
|
|
||||||
children: "foo"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "bar"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.pre, {
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
className: "language-js",
|
|
||||||
children: "baz/n"
|
|
||||||
})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toc remark plugin escapes inline code 1`] = `
|
exports[`toc remark plugin escapes inline code 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"export const toc = [
|
||||||
export const toc = [{
|
{
|
||||||
"value": "<code><Head /></code>",
|
value: '<code><Head /></code>',
|
||||||
"id": "head-",
|
id: 'head-',
|
||||||
"level": 2
|
level: 2
|
||||||
}, {
|
},
|
||||||
"value": "<code><Head>Test</Head></code>",
|
{
|
||||||
"id": "headtesthead",
|
value: '<code><Head>Test</Head></code>',
|
||||||
"level": 3
|
id: 'headtesthead',
|
||||||
}, {
|
level: 3
|
||||||
"value": "<code><div /></code>",
|
},
|
||||||
"id": "div-",
|
{
|
||||||
"level": 2
|
value: '<code><div /></code>',
|
||||||
}, {
|
id: 'div-',
|
||||||
"value": "<code><div> Test </div></code>",
|
level: 2
|
||||||
"id": "div-test-div",
|
},
|
||||||
"level": 2
|
{
|
||||||
}, {
|
value: '<code><div> Test </div></code>',
|
||||||
"value": "<code><div><i>Test</i></div></code>",
|
id: 'div-test-div',
|
||||||
"id": "divitestidiv",
|
level: 2
|
||||||
"level": 2
|
},
|
||||||
}, {
|
{
|
||||||
"value": "<code><div><i>Test</i></div></code>",
|
value: '<code><div><i>Test</i></div></code>',
|
||||||
"id": "divitestidiv-1",
|
id: 'divitestidiv',
|
||||||
"level": 2
|
level: 2
|
||||||
}];
|
},
|
||||||
function _createMdxContent(props) {
|
{
|
||||||
const _components = {
|
value: '<code><div><i>Test</i></div></code>',
|
||||||
a: "a",
|
id: 'divitestidiv-1',
|
||||||
code: "code",
|
level: 2
|
||||||
h2: "h2",
|
}
|
||||||
h3: "h3",
|
]
|
||||||
...props.components
|
|
||||||
};
|
## \`<Head />\`
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h2, {
|
### \`<Head>Test</Head>\`
|
||||||
id: "head-",
|
|
||||||
children: _jsx(_components.code, {
|
## \`<div />\`
|
||||||
children: "<Head />"
|
|
||||||
})
|
## \`<div> Test </div>\`
|
||||||
}), "/n", _jsx(_components.h3, {
|
|
||||||
id: "headtesthead",
|
## \`<div><i>Test</i></div>\`
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "<Head>Test</Head>"
|
## [\`<div><i>Test</i></div>\`](/some/link)
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "div-",
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "<div />"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "div-test-div",
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "<div> Test </div>"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "divitestidiv",
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "<div><i>Test</i></div>"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "divitestidiv-1",
|
|
||||||
children: _jsx(_components.a, {
|
|
||||||
href: "/some/link",
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "<div><i>Test</i></div>"
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toc remark plugin exports even with existing name 1`] = `
|
exports[`toc remark plugin exports even with existing name 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"export const toc = [
|
||||||
export const toc = ['replaceMe'];
|
{
|
||||||
function _createMdxContent(props) {
|
value: 'Thanos',
|
||||||
const _components = {
|
id: 'thanos',
|
||||||
h2: "h2",
|
level: 2
|
||||||
h3: "h3",
|
},
|
||||||
...props.components
|
{
|
||||||
};
|
value: 'Tony Stark',
|
||||||
return _jsxs(_Fragment, {
|
id: 'tony-stark',
|
||||||
children: [_jsx(_components.h2, {
|
level: 2
|
||||||
id: "thanos",
|
},
|
||||||
children: "Thanos"
|
{
|
||||||
}), "/n", _jsx(_components.h2, {
|
value: 'Avengers',
|
||||||
id: "tony-stark",
|
id: 'avengers',
|
||||||
children: "Tony Stark"
|
level: 3
|
||||||
}), "/n", _jsx(_components.h3, {
|
}
|
||||||
id: "avengers",
|
]
|
||||||
children: "Avengers"
|
|
||||||
})]
|
## Thanos
|
||||||
});
|
|
||||||
}
|
## Tony Stark
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
### Avengers
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toc remark plugin handles empty headings 1`] = `
|
exports[`toc remark plugin handles empty headings 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"export const toc = []
|
||||||
export const toc = [];
|
|
||||||
function _createMdxContent(props) {
|
# Ignore this
|
||||||
const _components = {
|
|
||||||
h1: "h1",
|
##
|
||||||
h2: "h2",
|
|
||||||
img: "img",
|
## 
|
||||||
...props.components
|
|
||||||
};
|
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h1, {
|
|
||||||
id: "ignore-this",
|
|
||||||
children: "Ignore this"
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: ""
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "-1",
|
|
||||||
children: _jsx(_components.img, {
|
|
||||||
src: "an-image.svg",
|
|
||||||
alt: ""
|
|
||||||
})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toc remark plugin inserts below imports 1`] = `
|
exports[`toc remark plugin inserts below imports 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"import something from 'something';
|
||||||
import something from 'something';
|
|
||||||
import somethingElse from 'something-else';
|
import somethingElse from 'something-else';
|
||||||
export const toc = [{
|
|
||||||
"value": "Title",
|
export const toc = [
|
||||||
"id": "title",
|
{
|
||||||
"level": 2
|
value: 'Title',
|
||||||
}, {
|
id: 'title',
|
||||||
"value": "Test",
|
level: 2
|
||||||
"id": "test",
|
},
|
||||||
"level": 2
|
{
|
||||||
}, {
|
value: 'Test',
|
||||||
"value": "Again",
|
id: 'test',
|
||||||
"id": "again",
|
level: 2
|
||||||
"level": 3
|
},
|
||||||
}];
|
{
|
||||||
function _createMdxContent(props) {
|
value: 'Again',
|
||||||
const _components = {
|
id: 'again',
|
||||||
h2: "h2",
|
level: 3
|
||||||
h3: "h3",
|
}
|
||||||
p: "p",
|
]
|
||||||
...props.components
|
|
||||||
};
|
## Title
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h2, {
|
## Test
|
||||||
id: "title",
|
|
||||||
children: "Title"
|
### Again
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "test",
|
Content.
|
||||||
children: "Test"
|
|
||||||
}), "/n", _jsx(_components.h3, {
|
|
||||||
id: "again",
|
|
||||||
children: "Again"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Content."
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toc remark plugin outputs empty array for no TOC 1`] = `
|
exports[`toc remark plugin outputs empty array for no TOC 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"export const toc = []
|
||||||
export const toc = [];
|
|
||||||
function _createMdxContent(props) {
|
foo
|
||||||
const _components = {
|
|
||||||
code: "code",
|
\`bar\`
|
||||||
p: "p",
|
|
||||||
pre: "pre",
|
\`\`\`js
|
||||||
...props.components
|
baz
|
||||||
};
|
\`\`\`
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.p, {
|
|
||||||
children: "foo"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "bar"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.pre, {
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
className: "language-js",
|
|
||||||
children: "baz/n"
|
|
||||||
})
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toc remark plugin works on non text phrasing content 1`] = `
|
exports[`toc remark plugin works on non text phrasing content 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"export const toc = [
|
||||||
export const toc = [{
|
{
|
||||||
"value": "<em>Emphasis</em>",
|
value: '<em>Emphasis</em>',
|
||||||
"id": "emphasis",
|
id: 'emphasis',
|
||||||
"level": 2
|
level: 2
|
||||||
}, {
|
},
|
||||||
"value": "<strong>Importance</strong>",
|
{
|
||||||
"id": "importance",
|
value: '<strong>Importance</strong>',
|
||||||
"level": 3
|
id: 'importance',
|
||||||
}, {
|
level: 3
|
||||||
"value": "<del>Strikethrough</del>",
|
},
|
||||||
"id": "strikethrough",
|
{
|
||||||
"level": 2
|
value: '<del>Strikethrough</del>',
|
||||||
}, {
|
id: 'strikethrough',
|
||||||
"value": "<i>HTML</i>",
|
level: 2
|
||||||
"id": "html",
|
},
|
||||||
"level": 2
|
{
|
||||||
}, {
|
value: '<i>HTML</i>',
|
||||||
"value": "<code>inline.code()</code>",
|
id: 'html',
|
||||||
"id": "inlinecode",
|
level: 2
|
||||||
"level": 2
|
},
|
||||||
}, {
|
{
|
||||||
"value": "some <span class=\\"some-class\\">styled</span> <strong>heading</strong> <span class=\\"myClassName <> weird char\\"></span> test",
|
value: '<code>inline.code()</code>',
|
||||||
"id": "some-styled-heading--test",
|
id: 'inlinecode',
|
||||||
"level": 2
|
level: 2
|
||||||
}];
|
},
|
||||||
function _createMdxContent(props) {
|
{
|
||||||
const _components = {
|
value: 'some <span class="some-class">styled</span> <strong>heading</strong> <span class="myClassName <> weird char"></span> test',
|
||||||
code: "code",
|
id: 'some-styled-heading--test',
|
||||||
del: "del",
|
level: 2
|
||||||
em: "em",
|
}
|
||||||
h2: "h2",
|
]
|
||||||
h3: "h3",
|
|
||||||
strong: "strong",
|
## *Emphasis*
|
||||||
...props.components
|
|
||||||
};
|
### **Importance**
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h2, {
|
## ~~Strikethrough~~
|
||||||
id: "emphasis",
|
|
||||||
children: _jsx(_components.em, {
|
## <i>HTML</i>
|
||||||
children: "Emphasis"
|
|
||||||
})
|
## \`inline.code()\`
|
||||||
}), "/n", _jsx(_components.h3, {
|
|
||||||
id: "importance",
|
## some <span className="some-class" style={{border: "solid"}}>styled</span> <strong>heading</strong> <span class="myClass" className="myClassName <> weird char" data-random-attr="456" /> test
|
||||||
children: _jsx(_components.strong, {
|
|
||||||
children: "Importance"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "strikethrough",
|
|
||||||
children: _jsx(_components.del, {
|
|
||||||
children: "Strikethrough"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "html",
|
|
||||||
children: _jsx("i", {
|
|
||||||
children: "HTML"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "inlinecode",
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
children: "inline.code()"
|
|
||||||
})
|
|
||||||
}), "/n", _jsxs(_components.h2, {
|
|
||||||
id: "some-styled-heading--test",
|
|
||||||
children: ["some ", _jsx("span", {
|
|
||||||
className: "some-class",
|
|
||||||
style: {
|
|
||||||
border: "solid"
|
|
||||||
},
|
|
||||||
children: "styled"
|
|
||||||
}), " ", _jsx("strong", {
|
|
||||||
children: "heading"
|
|
||||||
}), " ", _jsx("span", {
|
|
||||||
class: "myClass",
|
|
||||||
className: "myClassName <> weird char",
|
|
||||||
"data-random-attr": "456"
|
|
||||||
}), " test"]
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`toc remark plugin works on text content 1`] = `
|
exports[`toc remark plugin works on text content 1`] = `
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
"export const toc = [
|
||||||
|
{
|
||||||
|
value: 'Endi',
|
||||||
|
id: 'endi',
|
||||||
|
level: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Endi',
|
||||||
|
id: 'endi-1',
|
||||||
|
level: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Yangshun',
|
||||||
|
id: 'yangshun',
|
||||||
|
level: 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'I ♥ unicode.',
|
||||||
|
id: 'i--unicode',
|
||||||
|
level: 2
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
### Endi
|
||||||
|
|
||||||
|
\`\`\`md
|
||||||
|
## This is ignored
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Endi
|
||||||
|
|
||||||
|
Lorem ipsum
|
||||||
|
|
||||||
|
### Yangshun
|
||||||
|
|
||||||
|
Some content here
|
||||||
|
|
||||||
|
## I ♥ unicode.
|
||||||
|
|
||||||
export const c = 1;
|
export const c = 1;
|
||||||
export const toc = [{
|
|
||||||
"value": "Endi",
|
|
||||||
"id": "endi",
|
|
||||||
"level": 3
|
|
||||||
}, {
|
|
||||||
"value": "Endi",
|
|
||||||
"id": "endi-1",
|
|
||||||
"level": 2
|
|
||||||
}, {
|
|
||||||
"value": "Yangshun",
|
|
||||||
"id": "yangshun",
|
|
||||||
"level": 3
|
|
||||||
}, {
|
|
||||||
"value": "I ♥ unicode.",
|
|
||||||
"id": "i--unicode",
|
|
||||||
"level": 2
|
|
||||||
}];
|
|
||||||
function _createMdxContent(props) {
|
|
||||||
const _components = {
|
|
||||||
code: "code",
|
|
||||||
h2: "h2",
|
|
||||||
h3: "h3",
|
|
||||||
p: "p",
|
|
||||||
pre: "pre",
|
|
||||||
...props.components
|
|
||||||
};
|
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h3, {
|
|
||||||
id: "endi",
|
|
||||||
children: "Endi"
|
|
||||||
}), "/n", _jsx(_components.pre, {
|
|
||||||
children: _jsx(_components.code, {
|
|
||||||
className: "language-md",
|
|
||||||
children: "## This is ignored/n"
|
|
||||||
})
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "endi-1",
|
|
||||||
children: "Endi"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Lorem ipsum"
|
|
||||||
}), "/n", _jsx(_components.h3, {
|
|
||||||
id: "yangshun",
|
|
||||||
children: "Yangshun"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Some content here"
|
|
||||||
}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "i--unicode",
|
|
||||||
children: "I ♥ unicode."
|
|
||||||
})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`toc remark plugin works with imported markdown 1`] = `
|
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
|
||||||
import Partial1, {toc as __tocPartial1} from './_partial1.md';
|
|
||||||
import SomeComponent from './SomeComponent';
|
|
||||||
import Partial2, {toc as __tocPartial2} from './_partial2.md';
|
|
||||||
import UnusedPartialImport from './_partial3.md';
|
|
||||||
import DoesNotExist, {toc as __tocDoesNotExist} from './_doesNotExist.md';
|
|
||||||
export const toc = [{
|
|
||||||
"value": "Index section 1",
|
|
||||||
"id": "index-section-1",
|
|
||||||
"level": 2
|
|
||||||
}, ...__tocPartial1, {
|
|
||||||
"value": "Index section 2",
|
|
||||||
"id": "index-section-2",
|
|
||||||
"level": 2
|
|
||||||
}, ...__tocPartial2, {
|
|
||||||
"value": "Unused partials",
|
|
||||||
"id": "unused-partials",
|
|
||||||
"level": 2
|
|
||||||
}, {
|
|
||||||
"value": "NonExisting Partials",
|
|
||||||
"id": "nonexisting-partials",
|
|
||||||
"level": 2
|
|
||||||
}, ...__tocDoesNotExist, {
|
|
||||||
"value": "Duplicate partials",
|
|
||||||
"id": "duplicate-partials",
|
|
||||||
"level": 2
|
|
||||||
}, ...__tocPartial1, ...__tocPartial1];
|
|
||||||
function _createMdxContent(props) {
|
|
||||||
const _components = {
|
|
||||||
h1: "h1",
|
|
||||||
h2: "h2",
|
|
||||||
p: "p",
|
|
||||||
...props.components
|
|
||||||
};
|
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h1, {
|
|
||||||
id: "index",
|
|
||||||
children: "Index"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Some text"
|
|
||||||
}), "/n", "/n", _jsx(_components.h2, {
|
|
||||||
id: "index-section-1",
|
|
||||||
children: "Index section 1"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Foo"
|
|
||||||
}), "/n", _jsx(Partial1, {}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Some text"
|
|
||||||
}), "/n", _jsx(SomeComponent, {}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "index-section-2",
|
|
||||||
children: "Index section 2"
|
|
||||||
}), "/n", _jsx(Partial2, {}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "unused-partials",
|
|
||||||
children: "Unused partials"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Unused partials (that are only imported but not rendered) shouldn't alter the TOC"
|
|
||||||
}), "/n", "/n", _jsx(_components.h2, {
|
|
||||||
id: "nonexisting-partials",
|
|
||||||
children: "NonExisting Partials"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Partials that do not exist should alter the TOC"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "It's not the responsibility of the Remark plugin to check for their existence"
|
|
||||||
}), "/n", "/n", _jsx(DoesNotExist, {}), "/n", _jsx(_components.h2, {
|
|
||||||
id: "duplicate-partials",
|
|
||||||
children: "Duplicate partials"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "It's fine if we use partials at the end"
|
|
||||||
}), "/n", _jsx(Partial1, {}), "/n", _jsx(_components.p, {
|
|
||||||
children: "And we can use the partial multiple times!"
|
|
||||||
}), "/n", _jsx(Partial1, {})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`toc remark plugin works with partial imported after its usage 1`] = `
|
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
|
||||||
import Partial, {toc as __tocPartial} from './_partial.md';
|
|
||||||
export const toc = [...__tocPartial];
|
|
||||||
function _createMdxContent(props) {
|
|
||||||
const _components = {
|
|
||||||
h1: "h1",
|
|
||||||
p: "p",
|
|
||||||
...props.components
|
|
||||||
};
|
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h1, {
|
|
||||||
id: "partial-used-before-import",
|
|
||||||
children: "Partial used before import"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "While it looks weird to import after usage, this remains valid MDX usage."
|
|
||||||
}), "/n", _jsx(Partial, {})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`toc remark plugin works with partials importing other partials 1`] = `
|
|
||||||
"import {Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs} from "react/jsx-runtime";
|
|
||||||
import Partial2Nested, {toc as __tocPartial2Nested} from './partial2-nested.md';
|
|
||||||
export const toc = [{
|
|
||||||
"value": "Partial 2",
|
|
||||||
"id": "partial-2",
|
|
||||||
"level": 2
|
|
||||||
}, {
|
|
||||||
"value": "Partial 2 Sub Heading",
|
|
||||||
"id": "partial-2-sub-heading",
|
|
||||||
"level": 3
|
|
||||||
}, ...__tocPartial2Nested];
|
|
||||||
function _createMdxContent(props) {
|
|
||||||
const _components = {
|
|
||||||
h2: "h2",
|
|
||||||
h3: "h3",
|
|
||||||
p: "p",
|
|
||||||
...props.components
|
|
||||||
};
|
|
||||||
return _jsxs(_Fragment, {
|
|
||||||
children: [_jsx(_components.h2, {
|
|
||||||
id: "partial-2",
|
|
||||||
children: "Partial 2"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Partial 2"
|
|
||||||
}), "/n", _jsx(_components.h3, {
|
|
||||||
id: "partial-2-sub-heading",
|
|
||||||
children: "Partial 2 Sub Heading"
|
|
||||||
}), "/n", _jsx(_components.p, {
|
|
||||||
children: "Content"
|
|
||||||
}), "/n", "/n", _jsx(Partial2Nested, {})]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
export default function MDXContent(props = {}) {
|
|
||||||
const {wrapper: MDXLayout} = props.components || ({});
|
|
||||||
return MDXLayout ? _jsx(MDXLayout, {
|
|
||||||
...props,
|
|
||||||
children: _jsx(_createMdxContent, {
|
|
||||||
...props
|
|
||||||
})
|
|
||||||
}) : _createMdxContent(props);
|
|
||||||
}
|
|
||||||
"
|
"
|
||||||
`;
|
`;
|
||||||
|
|
|
||||||
|
|
@ -11,23 +11,18 @@ import plugin from '../index';
|
||||||
import headings from '../../headings/index';
|
import headings from '../../headings/index';
|
||||||
|
|
||||||
const processFixture = async (name: string) => {
|
const processFixture = async (name: string) => {
|
||||||
|
const {remark} = await import('remark');
|
||||||
const {default: gfm} = await import('remark-gfm');
|
const {default: gfm} = await import('remark-gfm');
|
||||||
|
const {default: mdx} = await import('remark-mdx');
|
||||||
|
|
||||||
const {compile} = await import('@mdx-js/mdx');
|
const filePath = path.join(__dirname, '__fixtures__', `${name}.md`);
|
||||||
|
|
||||||
const filePath = path.join(
|
|
||||||
__dirname,
|
|
||||||
'__fixtures__',
|
|
||||||
name.endsWith('.mdx') ? name : `${name}.md`,
|
|
||||||
);
|
|
||||||
|
|
||||||
const file = await vfile.read(filePath);
|
const file = await vfile.read(filePath);
|
||||||
|
const result = await remark()
|
||||||
const result = await compile(file, {
|
.use(headings)
|
||||||
format: 'mdx',
|
.use(gfm)
|
||||||
remarkPlugins: [headings, gfm, plugin],
|
.use(mdx)
|
||||||
rehypePlugins: [],
|
.use(plugin)
|
||||||
});
|
.process(file);
|
||||||
|
|
||||||
return result.value;
|
return result.value;
|
||||||
};
|
};
|
||||||
|
|
@ -75,21 +70,4 @@ describe('toc remark plugin', () => {
|
||||||
const result = await processFixture('empty-headings');
|
const result = await processFixture('empty-headings');
|
||||||
expect(result).toMatchSnapshot();
|
expect(result).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('works with imported markdown', async () => {
|
|
||||||
const result = await processFixture('partials/index.mdx');
|
|
||||||
expect(result).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works with partials importing other partials', async () => {
|
|
||||||
const result = await processFixture('partials/_partial2.mdx');
|
|
||||||
expect(result).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('works with partial imported after its usage', async () => {
|
|
||||||
const result = await processFixture(
|
|
||||||
'partials/partial-used-before-import.mdx',
|
|
||||||
);
|
|
||||||
expect(result).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,183 +5,154 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {parse, type ParserOptions} from '@babel/parser';
|
||||||
addTocSliceImportIfNeeded,
|
import traverse from '@babel/traverse';
|
||||||
createTOCExportNodeAST,
|
import stringifyObject from 'stringify-object';
|
||||||
findDefaultImportName,
|
import {toValue} from '../utils';
|
||||||
getImportDeclarations,
|
import type {Identifier} from '@babel/types';
|
||||||
isMarkdownImport,
|
import type {Node, Parent} from 'unist';
|
||||||
isNamedExport,
|
import type {Heading, Literal} from 'mdast';
|
||||||
} from './utils';
|
|
||||||
import type {Heading, Root} from 'mdast';
|
|
||||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||||
import type {Transformer} from 'unified';
|
import type {Transformer} from 'unified';
|
||||||
import type {
|
import type {
|
||||||
MdxjsEsm,
|
MdxjsEsm,
|
||||||
MdxJsxFlowElement,
|
|
||||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
||||||
} from 'mdast-util-mdx';
|
} from 'mdast-util-mdx';
|
||||||
import type {TOCItems} from './types';
|
|
||||||
import type {ImportDeclaration} from 'estree';
|
// TODO as of April 2023, no way to import/re-export this ESM type easily :/
|
||||||
|
// TODO upgrade to TS 5.3
|
||||||
|
// See https://github.com/microsoft/TypeScript/issues/49721#issuecomment-1517839391
|
||||||
|
// import type {Plugin} from 'unified';
|
||||||
|
type Plugin = any; // TODO fix this asap
|
||||||
|
|
||||||
|
export type TOCItem = {
|
||||||
|
readonly value: string;
|
||||||
|
readonly id: string;
|
||||||
|
readonly level: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const parseOptions: ParserOptions = {
|
||||||
|
plugins: ['jsx'],
|
||||||
|
sourceType: 'module',
|
||||||
|
};
|
||||||
|
|
||||||
|
const isImport = (child: any): child is Literal =>
|
||||||
|
child.type === 'mdxjsEsm' && child.value.startsWith('import');
|
||||||
|
const hasImports = (index: number) => index > -1;
|
||||||
|
const isExport = (child: any): child is Literal =>
|
||||||
|
child.type === 'mdxjsEsm' && child.value.startsWith('export');
|
||||||
|
|
||||||
interface PluginOptions {
|
interface PluginOptions {
|
||||||
name?: string;
|
name?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComponentName (default export) => ImportDeclaration mapping
|
const isTarget = (child: Literal, name: string) => {
|
||||||
type MarkdownImports = Map<string, {declaration: ImportDeclaration}>;
|
let found = false;
|
||||||
|
const ast = parse(child.value, parseOptions);
|
||||||
// MdxjsEsm node representing an already existing "export const toc" declaration
|
traverse(ast, {
|
||||||
type ExistingTOCExport = MdxjsEsm | null;
|
VariableDeclarator: (path) => {
|
||||||
|
if ((path.node.id as Identifier).name === name) {
|
||||||
function createTocSliceImportName({
|
found = true;
|
||||||
tocExportName,
|
|
||||||
componentName,
|
|
||||||
}: {
|
|
||||||
tocExportName: string;
|
|
||||||
componentName: string;
|
|
||||||
}) {
|
|
||||||
// The name of the toc slice import alias doesn't matter much
|
|
||||||
// We just need to ensure it's valid and won't conflict with other names
|
|
||||||
return `__${tocExportName}${componentName}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function collectImportsExports({
|
|
||||||
root,
|
|
||||||
tocExportName,
|
|
||||||
}: {
|
|
||||||
root: Root;
|
|
||||||
tocExportName: string;
|
|
||||||
}): Promise<{
|
|
||||||
markdownImports: MarkdownImports;
|
|
||||||
existingTocExport: ExistingTOCExport;
|
|
||||||
}> {
|
|
||||||
const {visit} = await import('unist-util-visit');
|
|
||||||
|
|
||||||
const markdownImports = new Map<string, {declaration: ImportDeclaration}>();
|
|
||||||
let existingTocExport: MdxjsEsm | null = null;
|
|
||||||
|
|
||||||
visit(root, 'mdxjsEsm', (node) => {
|
|
||||||
if (!node.data?.estree) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (isNamedExport(node, tocExportName)) {
|
|
||||||
existingTocExport = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
getImportDeclarations(node.data.estree).forEach((declaration) => {
|
|
||||||
if (!isMarkdownImport(declaration)) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
const componentName = findDefaultImportName(declaration);
|
},
|
||||||
if (!componentName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
markdownImports.set(componentName, {
|
|
||||||
declaration,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
return found;
|
||||||
|
};
|
||||||
|
|
||||||
return {markdownImports, existingTocExport};
|
const getOrCreateExistingTargetIndex = async (
|
||||||
}
|
children: Node[],
|
||||||
|
name: string,
|
||||||
|
) => {
|
||||||
|
let importsIndex = -1;
|
||||||
|
let targetIndex = -1;
|
||||||
|
|
||||||
async function collectTOCItems({
|
children.forEach((child, index) => {
|
||||||
root,
|
if (isImport(child)) {
|
||||||
tocExportName,
|
importsIndex = index;
|
||||||
markdownImports,
|
} else if (isExport(child) && isTarget(child, name)) {
|
||||||
}: {
|
targetIndex = index;
|
||||||
root: Root;
|
|
||||||
tocExportName: string;
|
|
||||||
markdownImports: MarkdownImports;
|
|
||||||
}): Promise<{
|
|
||||||
// The toc items we collected in the tree
|
|
||||||
tocItems: TOCItems;
|
|
||||||
}> {
|
|
||||||
const {toString} = await import('mdast-util-to-string');
|
|
||||||
const {visit} = await import('unist-util-visit');
|
|
||||||
|
|
||||||
const tocItems: TOCItems = [];
|
|
||||||
|
|
||||||
visit(root, (child) => {
|
|
||||||
if (child.type === 'heading') {
|
|
||||||
visitHeading(child);
|
|
||||||
} else if (child.type === 'mdxJsxFlowElement') {
|
|
||||||
visitJSXElement(child);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return {tocItems};
|
if (targetIndex === -1) {
|
||||||
|
const target = await createExportNode(name, []);
|
||||||
|
|
||||||
// Visit Markdown headings
|
targetIndex = hasImports(importsIndex) ? importsIndex + 1 : 0;
|
||||||
function visitHeading(node: Heading) {
|
children.splice(targetIndex, 0, target);
|
||||||
const value = toString(node);
|
|
||||||
// depth:1 headings are titles and not included in the TOC
|
|
||||||
if (!value || node.depth < 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
tocItems.push({
|
|
||||||
type: 'heading',
|
|
||||||
heading: node,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Visit JSX elements, such as <Partial/>
|
return targetIndex;
|
||||||
function visitJSXElement(node: MdxJsxFlowElement) {
|
};
|
||||||
const componentName = node.name;
|
|
||||||
if (!componentName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const importDeclaration = markdownImports.get(componentName)?.declaration;
|
|
||||||
if (!importDeclaration) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const tocSliceImportName = createTocSliceImportName({
|
const plugin: Plugin = function plugin(
|
||||||
tocExportName,
|
options: PluginOptions = {},
|
||||||
componentName,
|
): Transformer {
|
||||||
});
|
const name = options.name || 'toc';
|
||||||
|
|
||||||
tocItems.push({
|
|
||||||
type: 'slice',
|
|
||||||
importName: tocSliceImportName,
|
|
||||||
});
|
|
||||||
|
|
||||||
addTocSliceImportIfNeeded({
|
|
||||||
importDeclaration,
|
|
||||||
tocExportName,
|
|
||||||
tocSliceImportName,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function plugin(options: PluginOptions = {}): Transformer<Root> {
|
|
||||||
const tocExportName = options.name || 'toc';
|
|
||||||
|
|
||||||
return async (root) => {
|
return async (root) => {
|
||||||
const {markdownImports, existingTocExport} = await collectImportsExports({
|
const {toString} = await import('mdast-util-to-string');
|
||||||
root,
|
const {visit} = await import('unist-util-visit');
|
||||||
tocExportName,
|
|
||||||
|
const headings: TOCItem[] = [];
|
||||||
|
|
||||||
|
visit(root, 'heading', (child: Heading) => {
|
||||||
|
const value = toString(child);
|
||||||
|
|
||||||
|
// depth:1 headings are titles and not included in the TOC
|
||||||
|
if (!value || child.depth < 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
headings.push({
|
||||||
|
value: toValue(child, toString),
|
||||||
|
id: child.data!.id!,
|
||||||
|
level: child.depth,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// If user explicitly writes "export const toc" in his mdx file
|
const {children} = root as Parent;
|
||||||
// We keep it as is do not override their explicit toc structure
|
const targetIndex = await getOrCreateExistingTargetIndex(children, name);
|
||||||
// See https://github.com/facebook/docusaurus/pull/7530#discussion_r1458087876
|
|
||||||
if (existingTocExport) {
|
if (headings?.length) {
|
||||||
return;
|
children[targetIndex] = await createExportNode(name, headings);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
const {tocItems} = await collectTOCItems({
|
export default plugin;
|
||||||
root,
|
|
||||||
tocExportName,
|
|
||||||
markdownImports,
|
|
||||||
});
|
|
||||||
|
|
||||||
root.children.push(
|
async function createExportNode(name: string, object: any): Promise<MdxjsEsm> {
|
||||||
await createTOCExportNodeAST({
|
const {valueToEstree} = await import('estree-util-value-to-estree');
|
||||||
tocExportName,
|
|
||||||
tocItems,
|
return {
|
||||||
}),
|
type: 'mdxjsEsm',
|
||||||
);
|
value: `export const ${name} = ${stringifyObject(object)}`,
|
||||||
|
data: {
|
||||||
|
estree: {
|
||||||
|
type: 'Program',
|
||||||
|
body: [
|
||||||
|
{
|
||||||
|
type: 'ExportNamedDeclaration',
|
||||||
|
declaration: {
|
||||||
|
type: 'VariableDeclaration',
|
||||||
|
declarations: [
|
||||||
|
{
|
||||||
|
type: 'VariableDeclarator',
|
||||||
|
id: {
|
||||||
|
type: 'Identifier',
|
||||||
|
name,
|
||||||
|
},
|
||||||
|
init: valueToEstree(object),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
kind: 'const',
|
||||||
|
},
|
||||||
|
specifiers: [],
|
||||||
|
source: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
sourceType: 'module',
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,29 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type {Heading} from 'mdast';
|
|
||||||
|
|
||||||
// Note: this type is exported from mdx-loader and used in theme
|
|
||||||
// Need to keep it retro compatible
|
|
||||||
export type TOCItem = {
|
|
||||||
readonly value: string;
|
|
||||||
readonly id: string;
|
|
||||||
readonly level: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TOCHeading = {
|
|
||||||
readonly type: 'heading';
|
|
||||||
readonly heading: Heading;
|
|
||||||
};
|
|
||||||
|
|
||||||
// A TOC slice represents a TOCItem[] imported from a partial
|
|
||||||
export type TOCSlice = {
|
|
||||||
readonly type: 'slice';
|
|
||||||
readonly importName: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type TOCItems = (TOCHeading | TOCSlice)[];
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import {toValue} from '../utils';
|
|
||||||
import type {Node} from 'unist';
|
|
||||||
import type {
|
|
||||||
MdxjsEsm,
|
|
||||||
// @ts-expect-error: TODO see https://github.com/microsoft/TypeScript/issues/49721
|
|
||||||
} from 'mdast-util-mdx';
|
|
||||||
import type {TOCHeading, TOCItem, TOCItems, TOCSlice} from './types';
|
|
||||||
import type {
|
|
||||||
Program,
|
|
||||||
SpreadElement,
|
|
||||||
ImportDeclaration,
|
|
||||||
ImportSpecifier,
|
|
||||||
} from 'estree';
|
|
||||||
|
|
||||||
export function getImportDeclarations(program: Program): ImportDeclaration[] {
|
|
||||||
return program.body.filter(
|
|
||||||
(item): item is ImportDeclaration => item.type === 'ImportDeclaration',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isMarkdownImport(node: Node): node is ImportDeclaration {
|
|
||||||
if (node.type !== 'ImportDeclaration') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const importPath = (node as ImportDeclaration).source.value;
|
|
||||||
return typeof importPath === 'string' && /\.mdx?$/.test(importPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function findDefaultImportName(
|
|
||||||
importDeclaration: ImportDeclaration,
|
|
||||||
): string | undefined {
|
|
||||||
return importDeclaration.specifiers.find(
|
|
||||||
(o: Node) => o.type === 'ImportDefaultSpecifier',
|
|
||||||
)?.local.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function findNamedImportSpecifier(
|
|
||||||
importDeclaration: ImportDeclaration,
|
|
||||||
localName: string,
|
|
||||||
): ImportSpecifier | undefined {
|
|
||||||
return importDeclaration?.specifiers.find(
|
|
||||||
(specifier): specifier is ImportSpecifier =>
|
|
||||||
specifier.type === 'ImportSpecifier' &&
|
|
||||||
specifier.local.name === localName,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Before: import Partial from "partial"
|
|
||||||
// After: import Partial, {toc as __tocPartial} from "partial"
|
|
||||||
export function addTocSliceImportIfNeeded({
|
|
||||||
importDeclaration,
|
|
||||||
tocExportName,
|
|
||||||
tocSliceImportName,
|
|
||||||
}: {
|
|
||||||
importDeclaration: ImportDeclaration;
|
|
||||||
tocExportName: string;
|
|
||||||
tocSliceImportName: string;
|
|
||||||
}): void {
|
|
||||||
// We only add the toc slice named import if it doesn't exist already
|
|
||||||
if (!findNamedImportSpecifier(importDeclaration, tocSliceImportName)) {
|
|
||||||
importDeclaration.specifiers.push({
|
|
||||||
type: 'ImportSpecifier',
|
|
||||||
imported: {type: 'Identifier', name: tocExportName},
|
|
||||||
local: {type: 'Identifier', name: tocSliceImportName},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isNamedExport(
|
|
||||||
node: Node,
|
|
||||||
exportName: string,
|
|
||||||
): node is MdxjsEsm {
|
|
||||||
if (node.type !== 'mdxjsEsm') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const program = (node as MdxjsEsm).data?.estree;
|
|
||||||
if (!program) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (program.body.length !== 1) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const exportDeclaration = program.body[0]!;
|
|
||||||
if (exportDeclaration.type !== 'ExportNamedDeclaration') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const variableDeclaration = exportDeclaration.declaration;
|
|
||||||
if (variableDeclaration?.type !== 'VariableDeclaration') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const {id} = variableDeclaration.declarations[0]!;
|
|
||||||
if (id.type !== 'Identifier') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return id.name === exportName;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createTOCExportNodeAST({
|
|
||||||
tocExportName,
|
|
||||||
tocItems,
|
|
||||||
}: {
|
|
||||||
tocExportName: string;
|
|
||||||
tocItems: TOCItems;
|
|
||||||
}): Promise<MdxjsEsm> {
|
|
||||||
function createTOCSliceAST(tocSlice: TOCSlice): SpreadElement {
|
|
||||||
return {
|
|
||||||
type: 'SpreadElement',
|
|
||||||
argument: {type: 'Identifier', name: tocSlice.importName},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createTOCHeadingAST({heading}: TOCHeading) {
|
|
||||||
const {toString} = await import('mdast-util-to-string');
|
|
||||||
const {valueToEstree} = await import('estree-util-value-to-estree');
|
|
||||||
const value: TOCItem = {
|
|
||||||
value: toValue(heading, toString),
|
|
||||||
id: heading.data!.id!,
|
|
||||||
level: heading.depth,
|
|
||||||
};
|
|
||||||
return valueToEstree(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function createTOCItemAST(tocItem: TOCItems[number]) {
|
|
||||||
switch (tocItem.type) {
|
|
||||||
case 'slice':
|
|
||||||
return createTOCSliceAST(tocItem);
|
|
||||||
case 'heading':
|
|
||||||
return createTOCHeadingAST(tocItem);
|
|
||||||
default: {
|
|
||||||
throw new Error(`unexpected toc item type`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
type: 'mdxjsEsm',
|
|
||||||
value: '', // See https://github.com/facebook/docusaurus/pull/9684#discussion_r1457595181
|
|
||||||
data: {
|
|
||||||
estree: {
|
|
||||||
type: 'Program',
|
|
||||||
body: [
|
|
||||||
{
|
|
||||||
type: 'ExportNamedDeclaration',
|
|
||||||
declaration: {
|
|
||||||
type: 'VariableDeclaration',
|
|
||||||
declarations: [
|
|
||||||
{
|
|
||||||
type: 'VariableDeclarator',
|
|
||||||
id: {
|
|
||||||
type: 'Identifier',
|
|
||||||
name: tocExportName,
|
|
||||||
},
|
|
||||||
init: {
|
|
||||||
type: 'ArrayExpression',
|
|
||||||
elements: await Promise.all(tocItems.map(createTOCItemAST)),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
kind: 'const',
|
|
||||||
},
|
|
||||||
specifiers: [],
|
|
||||||
source: null,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
sourceType: 'module',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/module-type-aliases",
|
"name": "@docusaurus/module-type-aliases",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Docusaurus module type aliases.",
|
"description": "Docusaurus module type aliases.",
|
||||||
"types": "./src/index.d.ts",
|
"types": "./src/index.d.ts",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/react-loadable": "5.5.2",
|
"@docusaurus/react-loadable": "5.5.2",
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.1.1",
|
||||||
"@types/history": "^4.7.11",
|
"@types/history": "^4.7.11",
|
||||||
"@types/react": "*",
|
"@types/react": "*",
|
||||||
"@types/react-router-config": "*",
|
"@types/react-router-config": "*",
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/plugin-client-redirects",
|
"name": "@docusaurus/plugin-client-redirects",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Client redirects plugin for Docusaurus.",
|
"description": "Client redirects plugin for Docusaurus.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "lib/index.d.ts",
|
"types": "lib/index.d.ts",
|
||||||
|
|
@ -18,18 +18,18 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.1.1",
|
||||||
"@docusaurus/logger": "3.2.0",
|
"@docusaurus/logger": "3.1.1",
|
||||||
"@docusaurus/utils": "3.2.0",
|
"@docusaurus/utils": "3.1.1",
|
||||||
"@docusaurus/utils-common": "3.2.0",
|
"@docusaurus/utils-common": "3.1.1",
|
||||||
"@docusaurus/utils-validation": "3.2.0",
|
"@docusaurus/utils-validation": "3.1.1",
|
||||||
"eta": "^2.2.0",
|
"eta": "^2.2.0",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"tslib": "^2.6.0"
|
"tslib": "^2.6.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@docusaurus/types": "3.2.0"
|
"@docusaurus/types": "3.1.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"react": "^18.0.0",
|
"react": "^18.0.0",
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {removeTrailingSlash} from '@docusaurus/utils-common';
|
import {removeTrailingSlash} from '@docusaurus/utils';
|
||||||
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
||||||
import collectRedirects from '../collectRedirects';
|
import collectRedirects from '../collectRedirects';
|
||||||
import {validateOptions} from '../options';
|
import {validateOptions} from '../options';
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,8 @@
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import {
|
import {addTrailingSlash, removeTrailingSlash} from '@docusaurus/utils';
|
||||||
applyTrailingSlash,
|
import {applyTrailingSlash} from '@docusaurus/utils-common';
|
||||||
addTrailingSlash,
|
|
||||||
removeTrailingSlash,
|
|
||||||
} from '@docusaurus/utils-common';
|
|
||||||
import {
|
import {
|
||||||
createFromExtensionsRedirects,
|
createFromExtensionsRedirects,
|
||||||
createToExtensionsRedirects,
|
createToExtensionsRedirects,
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import {
|
||||||
addTrailingSlash,
|
addTrailingSlash,
|
||||||
removeSuffix,
|
removeSuffix,
|
||||||
removeTrailingSlash,
|
removeTrailingSlash,
|
||||||
} from '@docusaurus/utils-common';
|
} from '@docusaurus/utils';
|
||||||
import type {RedirectItem} from './types';
|
import type {RedirectItem} from './types';
|
||||||
|
|
||||||
const ExtensionAdditionalMessage =
|
const ExtensionAdditionalMessage =
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {addLeadingSlash, removePrefix} from '@docusaurus/utils-common';
|
import {removePrefix, addLeadingSlash} from '@docusaurus/utils';
|
||||||
import collectRedirects from './collectRedirects';
|
import collectRedirects from './collectRedirects';
|
||||||
import writeRedirectFiles, {
|
import writeRedirectFiles, {
|
||||||
toRedirectFiles,
|
toRedirectFiles,
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/plugin-content-blog",
|
"name": "@docusaurus/plugin-content-blog",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Blog plugin for Docusaurus.",
|
"description": "Blog plugin for Docusaurus.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "src/plugin-content-blog.d.ts",
|
"types": "src/plugin-content-blog.d.ts",
|
||||||
"exports": {
|
|
||||||
"./lib/*": "./lib/*",
|
|
||||||
"./src/*": "./src/*",
|
|
||||||
"./client": {
|
|
||||||
"type": "./lib/client/index.d.ts",
|
|
||||||
"default": "./lib/client/index.js"
|
|
||||||
},
|
|
||||||
".": {
|
|
||||||
"types": "./src/plugin-content-blog.d.ts",
|
|
||||||
"default": "./lib/index.js"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc --build",
|
"build": "tsc",
|
||||||
"watch": "tsc --build --watch",
|
"watch": "tsc --watch",
|
||||||
"test:generate-build-snap": "yarn docusaurus build src/__tests__/__fixtures__/website --out-dir build-snap && yarn rimraf src/__tests__/__fixtures__/website/.docusaurus && yarn rimraf src/__tests__/__fixtures__/website/build-snap/assets && git add src/__tests__/__fixtures__/website/build-snap"
|
"test:generate-build-snap": "yarn docusaurus build src/__tests__/__fixtures__/website --out-dir build-snap && yarn rimraf src/__tests__/__fixtures__/website/.docusaurus && yarn rimraf src/__tests__/__fixtures__/website/build-snap/assets && git add src/__tests__/__fixtures__/website/build-snap"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|
@ -31,13 +19,13 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.1.1",
|
||||||
"@docusaurus/logger": "3.2.0",
|
"@docusaurus/logger": "3.1.1",
|
||||||
"@docusaurus/mdx-loader": "3.2.0",
|
"@docusaurus/mdx-loader": "3.1.1",
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.1.1",
|
||||||
"@docusaurus/utils": "3.2.0",
|
"@docusaurus/utils": "3.1.1",
|
||||||
"@docusaurus/utils-common": "3.2.0",
|
"@docusaurus/utils-common": "3.1.1",
|
||||||
"@docusaurus/utils-validation": "3.2.0",
|
"@docusaurus/utils-validation": "3.1.1",
|
||||||
"cheerio": "^1.0.0-rc.12",
|
"cheerio": "^1.0.0-rc.12",
|
||||||
"feed": "^4.2.2",
|
"feed": "^4.2.2",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
|
|
@ -55,8 +43,5 @@
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.0"
|
"node": ">=18.0"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@total-typescript/shoehorn": "^0.1.2"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
---
|
|
||||||
title: Author
|
|
||||||
slug: author
|
|
||||||
author: ozaki
|
|
||||||
last_update:
|
|
||||||
author: seb
|
|
||||||
---
|
|
||||||
|
|
||||||
author
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
title: Both
|
|
||||||
slug: both
|
|
||||||
date: 2020-01-01
|
|
||||||
last_update:
|
|
||||||
date: 2021-01-01
|
|
||||||
author: seb
|
|
||||||
author: ozaki
|
|
||||||
---
|
|
||||||
|
|
||||||
last update date
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
---
|
|
||||||
title: Last update date
|
|
||||||
slug: lastUpdateDate
|
|
||||||
date: 2020-01-01
|
|
||||||
last_update:
|
|
||||||
date: 2021-01-01
|
|
||||||
---
|
|
||||||
|
|
||||||
last update date
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
---
|
|
||||||
title: Nothing
|
|
||||||
slug: nothing
|
|
||||||
---
|
|
||||||
|
|
||||||
nothing
|
|
||||||
|
|
@ -23,32 +23,7 @@ title: This post links to another one!
|
||||||
[Linked post](/blog/2018/12/14/Happy-First-Birthday-Slash)"
|
[Linked post](/blog/2018/12/14/Happy-First-Birthday-Slash)"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`paginateBlogPosts generates a single page 1`] = `
|
exports[`paginateBlogPosts generates right pages 1`] = `
|
||||||
[
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"post1",
|
|
||||||
"post2",
|
|
||||||
"post3",
|
|
||||||
"post4",
|
|
||||||
"post5",
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog Description",
|
|
||||||
"blogTitle": "Blog Title",
|
|
||||||
"nextPage": undefined,
|
|
||||||
"page": 1,
|
|
||||||
"permalink": "/",
|
|
||||||
"postsPerPage": 10,
|
|
||||||
"previousPage": undefined,
|
|
||||||
"totalCount": 5,
|
|
||||||
"totalPages": 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`paginateBlogPosts generates pages 1`] = `
|
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"items": [
|
"items": [
|
||||||
|
|
@ -103,7 +78,7 @@ exports[`paginateBlogPosts generates pages 1`] = `
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`paginateBlogPosts generates pages at blog root 1`] = `
|
exports[`paginateBlogPosts generates right pages 2`] = `
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"items": [
|
"items": [
|
||||||
|
|
@ -158,56 +133,26 @@ exports[`paginateBlogPosts generates pages at blog root 1`] = `
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`paginateBlogPosts generates pages with custom pageBasePath 1`] = `
|
exports[`paginateBlogPosts generates right pages 3`] = `
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"items": [
|
"items": [
|
||||||
"post1",
|
"post1",
|
||||||
"post2",
|
"post2",
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog Description",
|
|
||||||
"blogTitle": "Blog Title",
|
|
||||||
"nextPage": "/blog/customPageBasePath/2",
|
|
||||||
"page": 1,
|
|
||||||
"permalink": "/blog",
|
|
||||||
"postsPerPage": 2,
|
|
||||||
"previousPage": undefined,
|
|
||||||
"totalCount": 5,
|
|
||||||
"totalPages": 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"post3",
|
"post3",
|
||||||
"post4",
|
"post4",
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog Description",
|
|
||||||
"blogTitle": "Blog Title",
|
|
||||||
"nextPage": "/blog/customPageBasePath/3",
|
|
||||||
"page": 2,
|
|
||||||
"permalink": "/blog/customPageBasePath/2",
|
|
||||||
"postsPerPage": 2,
|
|
||||||
"previousPage": "/blog",
|
|
||||||
"totalCount": 5,
|
|
||||||
"totalPages": 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"post5",
|
"post5",
|
||||||
],
|
],
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"blogDescription": "Blog Description",
|
"blogDescription": "Blog Description",
|
||||||
"blogTitle": "Blog Title",
|
"blogTitle": "Blog Title",
|
||||||
"nextPage": undefined,
|
"nextPage": undefined,
|
||||||
"page": 3,
|
"page": 1,
|
||||||
"permalink": "/blog/customPageBasePath/3",
|
"permalink": "/",
|
||||||
"postsPerPage": 2,
|
"postsPerPage": 10,
|
||||||
"previousPage": "/blog/customPageBasePath/2",
|
"previousPage": undefined,
|
||||||
"totalCount": 5,
|
"totalCount": 5,
|
||||||
"totalPages": 3,
|
"totalPages": 1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -220,134 +220,6 @@ exports[`atom has feed item for each post 1`] = `
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`atom has feed item for each post - with trailing slash 1`] = `
|
|
||||||
[
|
|
||||||
"<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<feed xmlns="http://www.w3.org/2005/Atom">
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/</id>
|
|
||||||
<title>Hello Blog</title>
|
|
||||||
<updated>2023-07-23T00:00:00.000Z</updated>
|
|
||||||
<generator>https://github.com/jpmonette/feed</generator>
|
|
||||||
<link rel="alternate" href="https://docusaurus.io/myBaseUrl/blog/"/>
|
|
||||||
<subtitle>Hello Blog</subtitle>
|
|
||||||
<icon>https://docusaurus.io/myBaseUrl/image/favicon.ico</icon>
|
|
||||||
<rights>Copyright</rights>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[test links]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/blog-with-links/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/blog-with-links/"/>
|
|
||||||
<updated>2023-07-23T00:00:00.000Z</updated>
|
|
||||||
<summary type="html"><![CDATA[absolute full url]]></summary>
|
|
||||||
<content type="html"><![CDATA[<p><a href="https://github.com/facebook/docusaurus" target="_blank" rel="noopener noreferrer">absolute full url</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title">absolute pathname</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title">relative pathname</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title">md link</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/myBaseUrl/blog/blog-with-links/#title">anchor</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title#title">relative pathname + anchor</a></p>
|
|
||||||
<p><img loading="lazy" src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png" width="760" height="160" class="img_yGFe"></p>
|
|
||||||
<p><img loading="lazy" src="https://docusaurus.io/assets/images/slash-introducing-411a16dd05086935b8e9ddae38ae9b45.svg" alt="" class="img_yGFe"></p>
|
|
||||||
<img srcset="https://docusaurus.io/img/test-image.png 300w, https://docusaurus.io/img/docusaurus-social-card.png 500w">
|
|
||||||
<img src="https://docusaurus.io/img/test-image.png">]]></content>
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[MDX Blog Sample with require calls]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/"/>
|
|
||||||
<updated>2021-03-06T00:00:00.000Z</updated>
|
|
||||||
<summary type="html"><![CDATA[Test MDX with require calls]]></summary>
|
|
||||||
<content type="html"><![CDATA[<p>Test MDX with require calls</p>
|
|
||||||
<!-- -->
|
|
||||||
<!-- -->
|
|
||||||
<img src="https://docusaurus.io/img/test-image.png">
|
|
||||||
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">
|
|
||||||
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">]]></content>
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[Full Blog Sample]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/"/>
|
|
||||||
<updated>2021-03-05T00:00:00.000Z</updated>
|
|
||||||
<summary type="html"><![CDATA[HTML Heading 1]]></summary>
|
|
||||||
<content type="html"><![CDATA[<h1>HTML Heading 1</h1>
|
|
||||||
<h2>HTML Heading 2</h2>
|
|
||||||
<p>HTML Paragraph</p>
|
|
||||||
<!-- -->
|
|
||||||
<!-- -->
|
|
||||||
<p>Import DOM</p>
|
|
||||||
<h1>Heading 1</h1>
|
|
||||||
<h2 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-2">Heading 2<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-2" class="hash-link" aria-label="Direct link to Heading 2" title="Direct link to Heading 2"></a></h2>
|
|
||||||
<h3 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-3">Heading 3<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-3" class="hash-link" aria-label="Direct link to Heading 3" title="Direct link to Heading 3"></a></h3>
|
|
||||||
<h4 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-4">Heading 4<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-4" class="hash-link" aria-label="Direct link to Heading 4" title="Direct link to Heading 4"></a></h4>
|
|
||||||
<h5 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-5">Heading 5<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-5" class="hash-link" aria-label="Direct link to Heading 5" title="Direct link to Heading 5"></a></h5>
|
|
||||||
<ul>
|
|
||||||
<li>list1</li>
|
|
||||||
<li>list2</li>
|
|
||||||
<li>list3</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li>list1</li>
|
|
||||||
<li>list2</li>
|
|
||||||
<li>list3</li>
|
|
||||||
</ul>
|
|
||||||
<p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p>
|
|
||||||
<p><a href="https://v2.docusaurus.io/" target="_blank" rel="noopener noreferrer">link</a> <img loading="lazy" src="https://v2.docusaurus.io/" alt="image" class="img_yGFe"></p>]]></content>
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[Complex Slug]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/"/>
|
|
||||||
<updated>2020-08-16T00:00:00.000Z</updated>
|
|
||||||
<summary type="html"><![CDATA[complex url slug]]></summary>
|
|
||||||
<content type="html"><![CDATA[<p>complex url slug</p>]]></content>
|
|
||||||
<category label="date" term="date"/>
|
|
||||||
<category label="complex" term="complex"/>
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[Simple Slug]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/simple/slug/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/simple/slug/"/>
|
|
||||||
<updated>2020-08-15T00:00:00.000Z</updated>
|
|
||||||
<summary type="html"><![CDATA[simple url slug]]></summary>
|
|
||||||
<content type="html"><![CDATA[<p>simple url slug</p>]]></content>
|
|
||||||
<author>
|
|
||||||
<name>Sébastien Lorber</name>
|
|
||||||
<uri>https://sebastienlorber.com</uri>
|
|
||||||
</author>
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[some heading]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/heading-as-title/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/heading-as-title/"/>
|
|
||||||
<updated>2019-01-02T00:00:00.000Z</updated>
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[date-matter]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/date-matter/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/date-matter/"/>
|
|
||||||
<updated>2019-01-01T00:00:00.000Z</updated>
|
|
||||||
<summary type="html"><![CDATA[date inside front matter]]></summary>
|
|
||||||
<content type="html"><![CDATA[<p>date inside front matter</p>]]></content>
|
|
||||||
<category label="date" term="date"/>
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<title type="html"><![CDATA[Happy 1st Birthday Slash! (translated)]]></title>
|
|
||||||
<id>https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/</id>
|
|
||||||
<link href="https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/"/>
|
|
||||||
<updated>2018-12-14T00:00:00.000Z</updated>
|
|
||||||
<summary type="html"><![CDATA[Happy birthday! (translated)]]></summary>
|
|
||||||
<content type="html"><![CDATA[<p>Happy birthday! (translated)</p>]]></content>
|
|
||||||
<author>
|
|
||||||
<name>Yangshun Tay (translated)</name>
|
|
||||||
</author>
|
|
||||||
<author>
|
|
||||||
<name>Sébastien Lorber (translated)</name>
|
|
||||||
<email>lorber.sebastien@gmail.com</email>
|
|
||||||
</author>
|
|
||||||
</entry>
|
|
||||||
</feed>",
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`json filters to the first two entries 1`] = `
|
exports[`json filters to the first two entries 1`] = `
|
||||||
[
|
[
|
||||||
"{
|
"{
|
||||||
|
|
@ -506,102 +378,6 @@ exports[`json has feed item for each post 1`] = `
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`json has feed item for each post - with trailing slash 1`] = `
|
|
||||||
[
|
|
||||||
"{
|
|
||||||
"version": "https://jsonfeed.org/version/1",
|
|
||||||
"title": "Hello Blog",
|
|
||||||
"home_page_url": "https://docusaurus.io/myBaseUrl/blog/",
|
|
||||||
"description": "Hello Blog",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/",
|
|
||||||
"content_html": "<p><a href=\\"https://github.com/facebook/docusaurus\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">absolute full url</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title\\">absolute pathname</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title\\">relative pathname</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title\\">md link</a></p>/n<p><a href=\\"https://docusaurus.io/myBaseUrl/blog/blog-with-links/#title\\">anchor</a></p>/n<p><a href=\\"https://docusaurus.io/blog/heading-as-title#title\\">relative pathname + anchor</a></p>/n<p><img loading=\\"lazy\\" src=\\"https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png\\" width=\\"760\\" height=\\"160\\" class=\\"img_yGFe\\"></p>/n<p><img loading=\\"lazy\\" src=\\"https://docusaurus.io/assets/images/slash-introducing-411a16dd05086935b8e9ddae38ae9b45.svg\\" alt=\\"\\" class=\\"img_yGFe\\"></p>/n<img srcset=\\"https://docusaurus.io/img/test-image.png 300w, https://docusaurus.io/img/docusaurus-social-card.png 500w\\">/n<img src=\\"https://docusaurus.io/img/test-image.png\\">",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/blog-with-links/",
|
|
||||||
"title": "test links",
|
|
||||||
"summary": "absolute full url",
|
|
||||||
"date_modified": "2023-07-23T00:00:00.000Z",
|
|
||||||
"tags": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/",
|
|
||||||
"content_html": "<p>Test MDX with require calls</p>/n<!-- -->/n<!-- -->/n<img src=\\"https://docusaurus.io/img/test-image.png\\">/n<img src=\\"https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png\\">/n<img src=\\"https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png\\">",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/",
|
|
||||||
"title": "MDX Blog Sample with require calls",
|
|
||||||
"summary": "Test MDX with require calls",
|
|
||||||
"date_modified": "2021-03-06T00:00:00.000Z",
|
|
||||||
"tags": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/",
|
|
||||||
"content_html": "<h1>HTML Heading 1</h1>/n<h2>HTML Heading 2</h2>/n<p>HTML Paragraph</p>/n<!-- -->/n<!-- -->/n<p>Import DOM</p>/n<h1>Heading 1</h1>/n<h2 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-2\\">Heading 2<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-2\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 2\\" title=\\"Direct link to Heading 2\\"></a></h2>/n<h3 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-3\\">Heading 3<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-3\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 3\\" title=\\"Direct link to Heading 3\\"></a></h3>/n<h4 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-4\\">Heading 4<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-4\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 4\\" title=\\"Direct link to Heading 4\\"></a></h4>/n<h5 class=\\"anchor anchorWithHideOnScrollNavbar_G5V2\\" id=\\"heading-5\\">Heading 5<a href=\\"https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-5\\" class=\\"hash-link\\" aria-label=\\"Direct link to Heading 5\\" title=\\"Direct link to Heading 5\\"></a></h5>/n<ul>/n<li>list1</li>/n<li>list2</li>/n<li>list3</li>/n</ul>/n<ul>/n<li>list1</li>/n<li>list2</li>/n<li>list3</li>/n</ul>/n<p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p>/n<p><a href=\\"https://v2.docusaurus.io/\\" target=\\"_blank\\" rel=\\"noopener noreferrer\\">link</a> <img loading=\\"lazy\\" src=\\"https://v2.docusaurus.io/\\" alt=\\"image\\" class=\\"img_yGFe\\"></p>",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/",
|
|
||||||
"title": "Full Blog Sample",
|
|
||||||
"summary": "HTML Heading 1",
|
|
||||||
"date_modified": "2021-03-05T00:00:00.000Z",
|
|
||||||
"tags": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/",
|
|
||||||
"content_html": "<p>complex url slug</p>",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/",
|
|
||||||
"title": "Complex Slug",
|
|
||||||
"summary": "complex url slug",
|
|
||||||
"date_modified": "2020-08-16T00:00:00.000Z",
|
|
||||||
"tags": [
|
|
||||||
"date",
|
|
||||||
"complex"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/simple/slug/",
|
|
||||||
"content_html": "<p>simple url slug</p>",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/simple/slug/",
|
|
||||||
"title": "Simple Slug",
|
|
||||||
"summary": "simple url slug",
|
|
||||||
"date_modified": "2020-08-15T00:00:00.000Z",
|
|
||||||
"author": {
|
|
||||||
"name": "Sébastien Lorber",
|
|
||||||
"url": "https://sebastienlorber.com"
|
|
||||||
},
|
|
||||||
"tags": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/",
|
|
||||||
"content_html": "",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/heading-as-title/",
|
|
||||||
"title": "some heading",
|
|
||||||
"date_modified": "2019-01-02T00:00:00.000Z",
|
|
||||||
"tags": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/date-matter/",
|
|
||||||
"content_html": "<p>date inside front matter</p>",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/date-matter/",
|
|
||||||
"title": "date-matter",
|
|
||||||
"summary": "date inside front matter",
|
|
||||||
"date_modified": "2019-01-01T00:00:00.000Z",
|
|
||||||
"tags": [
|
|
||||||
"date"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/",
|
|
||||||
"content_html": "<p>Happy birthday! (translated)</p>",
|
|
||||||
"url": "https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/",
|
|
||||||
"title": "Happy 1st Birthday Slash! (translated)",
|
|
||||||
"summary": "Happy birthday! (translated)",
|
|
||||||
"date_modified": "2018-12-14T00:00:00.000Z",
|
|
||||||
"author": {
|
|
||||||
"name": "Yangshun Tay (translated)"
|
|
||||||
},
|
|
||||||
"tags": []
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}",
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`rss filters to the first two entries 1`] = `
|
exports[`rss filters to the first two entries 1`] = `
|
||||||
[
|
[
|
||||||
"<?xml version="1.0" encoding="utf-8"?>
|
"<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
@ -817,123 +593,3 @@ exports[`rss has feed item for each post 1`] = `
|
||||||
</rss>",
|
</rss>",
|
||||||
]
|
]
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`rss has feed item for each post - with trailing slash 1`] = `
|
|
||||||
[
|
|
||||||
"<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
|
|
||||||
<channel>
|
|
||||||
<title>Hello Blog</title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/</link>
|
|
||||||
<description>Hello Blog</description>
|
|
||||||
<lastBuildDate>Sun, 23 Jul 2023 00:00:00 GMT</lastBuildDate>
|
|
||||||
<docs>https://validator.w3.org/feed/docs/rss2.html</docs>
|
|
||||||
<generator>https://github.com/jpmonette/feed</generator>
|
|
||||||
<language>en</language>
|
|
||||||
<copyright>Copyright</copyright>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[test links]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/blog-with-links/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/blog-with-links/</guid>
|
|
||||||
<pubDate>Sun, 23 Jul 2023 00:00:00 GMT</pubDate>
|
|
||||||
<description><![CDATA[absolute full url]]></description>
|
|
||||||
<content:encoded><![CDATA[<p><a href="https://github.com/facebook/docusaurus" target="_blank" rel="noopener noreferrer">absolute full url</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title">absolute pathname</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title">relative pathname</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title">md link</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/myBaseUrl/blog/blog-with-links/#title">anchor</a></p>
|
|
||||||
<p><a href="https://docusaurus.io/blog/heading-as-title#title">relative pathname + anchor</a></p>
|
|
||||||
<p><img loading="lazy" src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png" width="760" height="160" class="img_yGFe"></p>
|
|
||||||
<p><img loading="lazy" src="https://docusaurus.io/assets/images/slash-introducing-411a16dd05086935b8e9ddae38ae9b45.svg" alt="" class="img_yGFe"></p>
|
|
||||||
<img srcset="https://docusaurus.io/img/test-image.png 300w, https://docusaurus.io/img/docusaurus-social-card.png 500w">
|
|
||||||
<img src="https://docusaurus.io/img/test-image.png">]]></content:encoded>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[MDX Blog Sample with require calls]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/mdx-require-blog-post/</guid>
|
|
||||||
<pubDate>Sat, 06 Mar 2021 00:00:00 GMT</pubDate>
|
|
||||||
<description><![CDATA[Test MDX with require calls]]></description>
|
|
||||||
<content:encoded><![CDATA[<p>Test MDX with require calls</p>
|
|
||||||
<!-- -->
|
|
||||||
<!-- -->
|
|
||||||
<img src="https://docusaurus.io/img/test-image.png">
|
|
||||||
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">
|
|
||||||
<img src="https://docusaurus.io/assets/images/test-image-742d39e51f41482e8132e79c09ad4eea.png">]]></content:encoded>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[Full Blog Sample]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/</guid>
|
|
||||||
<pubDate>Fri, 05 Mar 2021 00:00:00 GMT</pubDate>
|
|
||||||
<description><![CDATA[HTML Heading 1]]></description>
|
|
||||||
<content:encoded><![CDATA[<h1>HTML Heading 1</h1>
|
|
||||||
<h2>HTML Heading 2</h2>
|
|
||||||
<p>HTML Paragraph</p>
|
|
||||||
<!-- -->
|
|
||||||
<!-- -->
|
|
||||||
<p>Import DOM</p>
|
|
||||||
<h1>Heading 1</h1>
|
|
||||||
<h2 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-2">Heading 2<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-2" class="hash-link" aria-label="Direct link to Heading 2" title="Direct link to Heading 2"></a></h2>
|
|
||||||
<h3 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-3">Heading 3<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-3" class="hash-link" aria-label="Direct link to Heading 3" title="Direct link to Heading 3"></a></h3>
|
|
||||||
<h4 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-4">Heading 4<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-4" class="hash-link" aria-label="Direct link to Heading 4" title="Direct link to Heading 4"></a></h4>
|
|
||||||
<h5 class="anchor anchorWithHideOnScrollNavbar_G5V2" id="heading-5">Heading 5<a href="https://docusaurus.io/myBaseUrl/blog/mdx-blog-post/#heading-5" class="hash-link" aria-label="Direct link to Heading 5" title="Direct link to Heading 5"></a></h5>
|
|
||||||
<ul>
|
|
||||||
<li>list1</li>
|
|
||||||
<li>list2</li>
|
|
||||||
<li>list3</li>
|
|
||||||
</ul>
|
|
||||||
<ul>
|
|
||||||
<li>list1</li>
|
|
||||||
<li>list2</li>
|
|
||||||
<li>list3</li>
|
|
||||||
</ul>
|
|
||||||
<p>Normal Text <em>Italics Text</em> <strong>Bold Text</strong></p>
|
|
||||||
<p><a href="https://v2.docusaurus.io/" target="_blank" rel="noopener noreferrer">link</a> <img loading="lazy" src="https://v2.docusaurus.io/" alt="image" class="img_yGFe"></p>]]></content:encoded>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[Complex Slug]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/hey/my super path/héllô/</guid>
|
|
||||||
<pubDate>Sun, 16 Aug 2020 00:00:00 GMT</pubDate>
|
|
||||||
<description><![CDATA[complex url slug]]></description>
|
|
||||||
<content:encoded><![CDATA[<p>complex url slug</p>]]></content:encoded>
|
|
||||||
<category>date</category>
|
|
||||||
<category>complex</category>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[Simple Slug]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/simple/slug/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/simple/slug/</guid>
|
|
||||||
<pubDate>Sat, 15 Aug 2020 00:00:00 GMT</pubDate>
|
|
||||||
<description><![CDATA[simple url slug]]></description>
|
|
||||||
<content:encoded><![CDATA[<p>simple url slug</p>]]></content:encoded>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[some heading]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/heading-as-title/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/heading-as-title/</guid>
|
|
||||||
<pubDate>Wed, 02 Jan 2019 00:00:00 GMT</pubDate>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[date-matter]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/date-matter/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/date-matter/</guid>
|
|
||||||
<pubDate>Tue, 01 Jan 2019 00:00:00 GMT</pubDate>
|
|
||||||
<description><![CDATA[date inside front matter]]></description>
|
|
||||||
<content:encoded><![CDATA[<p>date inside front matter</p>]]></content:encoded>
|
|
||||||
<category>date</category>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<title><![CDATA[Happy 1st Birthday Slash! (translated)]]></title>
|
|
||||||
<link>https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/</link>
|
|
||||||
<guid>https://docusaurus.io/myBaseUrl/blog/2018/12/14/Happy-First-Birthday-Slash/</guid>
|
|
||||||
<pubDate>Fri, 14 Dec 2018 00:00:00 GMT</pubDate>
|
|
||||||
<description><![CDATA[Happy birthday! (translated)]]></description>
|
|
||||||
<content:encoded><![CDATA[<p>Happy birthday! (translated)</p>]]></content:encoded>
|
|
||||||
<author>lorber.sebastien@gmail.com (Sébastien Lorber (translated))</author>
|
|
||||||
</item>
|
|
||||||
</channel>
|
|
||||||
</rss>",
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
|
||||||
|
|
@ -1,250 +1,5 @@
|
||||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
exports[`blog plugin process blog posts load content 1`] = `
|
|
||||||
{
|
|
||||||
"/blog/tags/tag-1": {
|
|
||||||
"items": [
|
|
||||||
"/simple/slug/another",
|
|
||||||
"/another/tags",
|
|
||||||
"/another/tags2",
|
|
||||||
],
|
|
||||||
"label": "tag1",
|
|
||||||
"pages": [
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"/simple/slug/another",
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog",
|
|
||||||
"blogTitle": "Blog",
|
|
||||||
"nextPage": "/blog/tags/tag-1/page/2",
|
|
||||||
"page": 1,
|
|
||||||
"permalink": "/blog/tags/tag-1",
|
|
||||||
"postsPerPage": 1,
|
|
||||||
"previousPage": undefined,
|
|
||||||
"totalCount": 3,
|
|
||||||
"totalPages": 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"/another/tags",
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog",
|
|
||||||
"blogTitle": "Blog",
|
|
||||||
"nextPage": "/blog/tags/tag-1/page/3",
|
|
||||||
"page": 2,
|
|
||||||
"permalink": "/blog/tags/tag-1/page/2",
|
|
||||||
"postsPerPage": 1,
|
|
||||||
"previousPage": "/blog/tags/tag-1",
|
|
||||||
"totalCount": 3,
|
|
||||||
"totalPages": 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"/another/tags2",
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog",
|
|
||||||
"blogTitle": "Blog",
|
|
||||||
"nextPage": undefined,
|
|
||||||
"page": 3,
|
|
||||||
"permalink": "/blog/tags/tag-1/page/3",
|
|
||||||
"postsPerPage": 1,
|
|
||||||
"previousPage": "/blog/tags/tag-1/page/2",
|
|
||||||
"totalCount": 3,
|
|
||||||
"totalPages": 3,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"permalink": "/blog/tags/tag-1",
|
|
||||||
"unlisted": false,
|
|
||||||
},
|
|
||||||
"/blog/tags/tag-2": {
|
|
||||||
"items": [
|
|
||||||
"/another/tags",
|
|
||||||
"/another/tags2",
|
|
||||||
],
|
|
||||||
"label": "tag2",
|
|
||||||
"pages": [
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"/another/tags",
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog",
|
|
||||||
"blogTitle": "Blog",
|
|
||||||
"nextPage": "/blog/tags/tag-2/page/2",
|
|
||||||
"page": 1,
|
|
||||||
"permalink": "/blog/tags/tag-2",
|
|
||||||
"postsPerPage": 1,
|
|
||||||
"previousPage": undefined,
|
|
||||||
"totalCount": 2,
|
|
||||||
"totalPages": 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
"/another/tags2",
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"blogDescription": "Blog",
|
|
||||||
"blogTitle": "Blog",
|
|
||||||
"nextPage": undefined,
|
|
||||||
"page": 2,
|
|
||||||
"permalink": "/blog/tags/tag-2/page/2",
|
|
||||||
"postsPerPage": 1,
|
|
||||||
"previousPage": "/blog/tags/tag-2",
|
|
||||||
"totalCount": 2,
|
|
||||||
"totalPages": 2,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"permalink": "/blog/tags/tag-2",
|
|
||||||
"unlisted": false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`blog plugin process blog posts load content 2`] = `
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"content": "simple url slug",
|
|
||||||
"id": "/simple/slug/another",
|
|
||||||
"metadata": {
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"imageURL": undefined,
|
|
||||||
"name": "Sébastien Lorber",
|
|
||||||
"title": "Docusaurus maintainer",
|
|
||||||
"url": "https://sebastienlorber.com",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"date": 2020-08-15T00:00:00.000Z,
|
|
||||||
"description": "simple url slug",
|
|
||||||
"editUrl": "https://baseEditUrl.com/edit/blog/another-simple-slug-with-tags.md",
|
|
||||||
"frontMatter": {
|
|
||||||
"author": "Sébastien Lorber",
|
|
||||||
"author_title": "Docusaurus maintainer",
|
|
||||||
"author_url": "https://sebastienlorber.com",
|
|
||||||
"date": 2020-08-15T00:00:00.000Z,
|
|
||||||
"slug": "/simple/slug/another",
|
|
||||||
"tags": [
|
|
||||||
"tag1",
|
|
||||||
],
|
|
||||||
"title": "Another Simple Slug",
|
|
||||||
},
|
|
||||||
"hasTruncateMarker": false,
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"lastUpdatedBy": undefined,
|
|
||||||
"nextItem": {
|
|
||||||
"permalink": "/blog/another/tags",
|
|
||||||
"title": "Another With Tag",
|
|
||||||
},
|
|
||||||
"permalink": "/blog/simple/slug/another",
|
|
||||||
"readingTime": 0.015,
|
|
||||||
"source": "@site/blog/another-simple-slug-with-tags.md",
|
|
||||||
"tags": [
|
|
||||||
{
|
|
||||||
"label": "tag1",
|
|
||||||
"permalink": "/blog/tags/tag-1",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"title": "Another Simple Slug",
|
|
||||||
"unlisted": false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": "with tag",
|
|
||||||
"id": "/another/tags",
|
|
||||||
"metadata": {
|
|
||||||
"authors": [],
|
|
||||||
"date": 2020-08-15T00:00:00.000Z,
|
|
||||||
"description": "with tag",
|
|
||||||
"editUrl": "https://baseEditUrl.com/edit/blog/another-with-tags.md",
|
|
||||||
"frontMatter": {
|
|
||||||
"date": 2020-08-15T00:00:00.000Z,
|
|
||||||
"slug": "/another/tags",
|
|
||||||
"tags": [
|
|
||||||
"tag1",
|
|
||||||
"tag2",
|
|
||||||
],
|
|
||||||
"title": "Another With Tag",
|
|
||||||
},
|
|
||||||
"hasTruncateMarker": false,
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"lastUpdatedBy": undefined,
|
|
||||||
"nextItem": {
|
|
||||||
"permalink": "/blog/another/tags2",
|
|
||||||
"title": "Another With Tag",
|
|
||||||
},
|
|
||||||
"permalink": "/blog/another/tags",
|
|
||||||
"prevItem": {
|
|
||||||
"permalink": "/blog/simple/slug/another",
|
|
||||||
"title": "Another Simple Slug",
|
|
||||||
},
|
|
||||||
"readingTime": 0.01,
|
|
||||||
"source": "@site/blog/another-with-tags.md",
|
|
||||||
"tags": [
|
|
||||||
{
|
|
||||||
"label": "tag1",
|
|
||||||
"permalink": "/blog/tags/tag-1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "tag2",
|
|
||||||
"permalink": "/blog/tags/tag-2",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"title": "Another With Tag",
|
|
||||||
"unlisted": false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": "with tag",
|
|
||||||
"id": "/another/tags2",
|
|
||||||
"metadata": {
|
|
||||||
"authors": [],
|
|
||||||
"date": 2020-08-15T00:00:00.000Z,
|
|
||||||
"description": "with tag",
|
|
||||||
"editUrl": "https://baseEditUrl.com/edit/blog/another-with-tags2.md",
|
|
||||||
"frontMatter": {
|
|
||||||
"date": 2020-08-15T00:00:00.000Z,
|
|
||||||
"slug": "/another/tags2",
|
|
||||||
"tags": [
|
|
||||||
"tag1",
|
|
||||||
"tag2",
|
|
||||||
],
|
|
||||||
"title": "Another With Tag",
|
|
||||||
},
|
|
||||||
"hasTruncateMarker": false,
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"lastUpdatedBy": undefined,
|
|
||||||
"permalink": "/blog/another/tags2",
|
|
||||||
"prevItem": {
|
|
||||||
"permalink": "/blog/another/tags",
|
|
||||||
"title": "Another With Tag",
|
|
||||||
},
|
|
||||||
"readingTime": 0.01,
|
|
||||||
"source": "@site/blog/another-with-tags2.md",
|
|
||||||
"tags": [
|
|
||||||
{
|
|
||||||
"label": "tag1",
|
|
||||||
"permalink": "/blog/tags/tag-1",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "tag2",
|
|
||||||
"permalink": "/blog/tags/tag-2",
|
|
||||||
},
|
|
||||||
],
|
|
||||||
"title": "Another With Tag",
|
|
||||||
"unlisted": false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
]
|
|
||||||
`;
|
|
||||||
|
|
||||||
exports[`blog plugin works on blog tags without pagination 1`] = `
|
exports[`blog plugin works on blog tags without pagination 1`] = `
|
||||||
{
|
{
|
||||||
"/blog/tags/tag-1": {
|
"/blog/tags/tag-1": {
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,7 @@ exports[`translateContent falls back when translation is incomplete 1`] = `
|
||||||
"authors": [],
|
"authors": [],
|
||||||
"date": 2021-07-19T00:00:00.000Z,
|
"date": 2021-07-19T00:00:00.000Z,
|
||||||
"description": "/blog/2021/06/19/hello",
|
"description": "/blog/2021/06/19/hello",
|
||||||
|
"formattedDate": "June 19, 2021",
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"hasTruncateMarker": true,
|
"hasTruncateMarker": true,
|
||||||
"permalink": "/blog/2021/06/19/hello",
|
"permalink": "/blog/2021/06/19/hello",
|
||||||
|
|
@ -93,6 +94,7 @@ exports[`translateContent returns translated loaded 1`] = `
|
||||||
"authors": [],
|
"authors": [],
|
||||||
"date": 2021-07-19T00:00:00.000Z,
|
"date": 2021-07-19T00:00:00.000Z,
|
||||||
"description": "/blog/2021/06/19/hello",
|
"description": "/blog/2021/06/19/hello",
|
||||||
|
"formattedDate": "June 19, 2021",
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"hasTruncateMarker": true,
|
"hasTruncateMarker": true,
|
||||||
"permalink": "/blog/2021/06/19/hello",
|
"permalink": "/blog/2021/06/19/hello",
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,12 @@
|
||||||
import {jest} from '@jest/globals';
|
import {jest} from '@jest/globals';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {fromPartial} from '@total-typescript/shoehorn';
|
|
||||||
import {
|
import {
|
||||||
truncate,
|
truncate,
|
||||||
parseBlogFileName,
|
parseBlogFileName,
|
||||||
linkify,
|
linkify,
|
||||||
getSourceToPermalink,
|
getSourceToPermalink,
|
||||||
paginateBlogPosts,
|
paginateBlogPosts,
|
||||||
applyProcessBlogPosts,
|
|
||||||
type LinkifyParams,
|
type LinkifyParams,
|
||||||
} from '../blogUtils';
|
} from '../blogUtils';
|
||||||
import type {BlogBrokenMarkdownLink, BlogContentPaths} from '../types';
|
import type {BlogBrokenMarkdownLink, BlogContentPaths} from '../types';
|
||||||
|
|
@ -40,15 +38,14 @@ describe('truncate', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('paginateBlogPosts', () => {
|
describe('paginateBlogPosts', () => {
|
||||||
const blogPosts = [
|
it('generates right pages', () => {
|
||||||
{id: 'post1', metadata: {}, content: 'Foo 1'},
|
const blogPosts = [
|
||||||
{id: 'post2', metadata: {}, content: 'Foo 2'},
|
{id: 'post1', metadata: {}, content: 'Foo 1'},
|
||||||
{id: 'post3', metadata: {}, content: 'Foo 3'},
|
{id: 'post2', metadata: {}, content: 'Foo 2'},
|
||||||
{id: 'post4', metadata: {}, content: 'Foo 4'},
|
{id: 'post3', metadata: {}, content: 'Foo 3'},
|
||||||
{id: 'post5', metadata: {}, content: 'Foo 5'},
|
{id: 'post4', metadata: {}, content: 'Foo 4'},
|
||||||
] as BlogPost[];
|
{id: 'post5', metadata: {}, content: 'Foo 5'},
|
||||||
|
] as BlogPost[];
|
||||||
it('generates pages', () => {
|
|
||||||
expect(
|
expect(
|
||||||
paginateBlogPosts({
|
paginateBlogPosts({
|
||||||
blogPosts,
|
blogPosts,
|
||||||
|
|
@ -56,12 +53,8 @@ describe('paginateBlogPosts', () => {
|
||||||
blogTitle: 'Blog Title',
|
blogTitle: 'Blog Title',
|
||||||
blogDescription: 'Blog Description',
|
blogDescription: 'Blog Description',
|
||||||
postsPerPageOption: 2,
|
postsPerPageOption: 2,
|
||||||
pageBasePath: 'page',
|
|
||||||
}),
|
}),
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
|
||||||
|
|
||||||
it('generates pages at blog root', () => {
|
|
||||||
expect(
|
expect(
|
||||||
paginateBlogPosts({
|
paginateBlogPosts({
|
||||||
blogPosts,
|
blogPosts,
|
||||||
|
|
@ -69,12 +62,8 @@ describe('paginateBlogPosts', () => {
|
||||||
blogTitle: 'Blog Title',
|
blogTitle: 'Blog Title',
|
||||||
blogDescription: 'Blog Description',
|
blogDescription: 'Blog Description',
|
||||||
postsPerPageOption: 2,
|
postsPerPageOption: 2,
|
||||||
pageBasePath: 'page',
|
|
||||||
}),
|
}),
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
|
||||||
|
|
||||||
it('generates a single page', () => {
|
|
||||||
expect(
|
expect(
|
||||||
paginateBlogPosts({
|
paginateBlogPosts({
|
||||||
blogPosts,
|
blogPosts,
|
||||||
|
|
@ -82,20 +71,6 @@ describe('paginateBlogPosts', () => {
|
||||||
blogTitle: 'Blog Title',
|
blogTitle: 'Blog Title',
|
||||||
blogDescription: 'Blog Description',
|
blogDescription: 'Blog Description',
|
||||||
postsPerPageOption: 10,
|
postsPerPageOption: 10,
|
||||||
pageBasePath: 'page',
|
|
||||||
}),
|
|
||||||
).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('generates pages with custom pageBasePath', () => {
|
|
||||||
expect(
|
|
||||||
paginateBlogPosts({
|
|
||||||
blogPosts,
|
|
||||||
basePageUrl: '/blog',
|
|
||||||
blogTitle: 'Blog Title',
|
|
||||||
blogDescription: 'Blog Description',
|
|
||||||
postsPerPageOption: 2,
|
|
||||||
pageBasePath: 'customPageBasePath',
|
|
||||||
}),
|
}),
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
@ -238,7 +213,7 @@ describe('linkify', () => {
|
||||||
hasTruncateMarker: false,
|
hasTruncateMarker: false,
|
||||||
frontMatter: {},
|
frontMatter: {},
|
||||||
authors: [],
|
authors: [],
|
||||||
unlisted: false,
|
formattedDate: '',
|
||||||
},
|
},
|
||||||
content: '',
|
content: '',
|
||||||
},
|
},
|
||||||
|
|
@ -297,81 +272,3 @@ describe('linkify', () => {
|
||||||
} as BlogBrokenMarkdownLink);
|
} as BlogBrokenMarkdownLink);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('processBlogPosts', () => {
|
|
||||||
const blogPost2022: BlogPost = fromPartial({
|
|
||||||
metadata: {date: new Date('2022-01-01')},
|
|
||||||
});
|
|
||||||
const blogPost2023: BlogPost = fromPartial({
|
|
||||||
metadata: {date: new Date('2023-01-01')},
|
|
||||||
});
|
|
||||||
const blogPost2024: BlogPost = fromPartial({
|
|
||||||
metadata: {date: new Date('2024-01-01')},
|
|
||||||
});
|
|
||||||
|
|
||||||
it('filter blogs only from 2024', async () => {
|
|
||||||
const processedBlogPosts = await applyProcessBlogPosts({
|
|
||||||
blogPosts: [blogPost2022, blogPost2023, blogPost2024],
|
|
||||||
processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) =>
|
|
||||||
blogPosts.filter(
|
|
||||||
(blogPost) => blogPost.metadata.date.getFullYear() === 2024,
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(processedBlogPosts).toEqual([blogPost2024]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sort blogs by date in ascending order', async () => {
|
|
||||||
const processedBlogPosts = await applyProcessBlogPosts({
|
|
||||||
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
|
|
||||||
processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) =>
|
|
||||||
blogPosts.sort(
|
|
||||||
(a, b) => a.metadata.date.getTime() - b.metadata.date.getTime(),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(processedBlogPosts).toEqual([
|
|
||||||
blogPost2022,
|
|
||||||
blogPost2023,
|
|
||||||
blogPost2024,
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('sort blogs by date in descending order', async () => {
|
|
||||||
const processedBlogPosts = await applyProcessBlogPosts({
|
|
||||||
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
|
|
||||||
processBlogPosts: async ({blogPosts}: {blogPosts: BlogPost[]}) =>
|
|
||||||
blogPosts.sort(
|
|
||||||
(a, b) => b.metadata.date.getTime() - a.metadata.date.getTime(),
|
|
||||||
),
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(processedBlogPosts).toEqual([
|
|
||||||
blogPost2024,
|
|
||||||
blogPost2023,
|
|
||||||
blogPost2022,
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('processBlogPosts return 2022 only', async () => {
|
|
||||||
const processedBlogPosts = await applyProcessBlogPosts({
|
|
||||||
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
|
|
||||||
processBlogPosts: async () => [blogPost2022],
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(processedBlogPosts).toEqual([blogPost2022]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('processBlogPosts return undefined', async () => {
|
|
||||||
const processedBlogPosts = await applyProcessBlogPosts({
|
|
||||||
blogPosts: [blogPost2023, blogPost2022, blogPost2024],
|
|
||||||
processBlogPosts: async () => {},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(processedBlogPosts).toEqual([
|
|
||||||
blogPost2023,
|
|
||||||
blogPost2022,
|
|
||||||
blogPost2024,
|
|
||||||
]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import {DEFAULT_PARSE_FRONT_MATTER} from '@docusaurus/utils';
|
import {DEFAULT_PARSE_FRONT_MATTER} from '@docusaurus/utils';
|
||||||
import {fromPartial} from '@total-typescript/shoehorn';
|
|
||||||
import {DEFAULT_OPTIONS} from '../options';
|
import {DEFAULT_OPTIONS} from '../options';
|
||||||
import {generateBlogPosts} from '../blogUtils';
|
import {generateBlogPosts} from '../blogUtils';
|
||||||
import {createBlogFeedFiles} from '../feed';
|
import {createBlogFeedFiles} from '../feed';
|
||||||
|
|
@ -81,12 +80,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
|
||||||
const outDir = path.join(siteDir, 'build-snap');
|
const outDir = path.join(siteDir, 'build-snap');
|
||||||
|
|
||||||
await testGenerateFeeds(
|
await testGenerateFeeds(
|
||||||
fromPartial({
|
{
|
||||||
siteDir,
|
siteDir,
|
||||||
siteConfig,
|
siteConfig,
|
||||||
i18n: DefaultI18N,
|
i18n: DefaultI18N,
|
||||||
outDir,
|
outDir,
|
||||||
}),
|
} as LoadContext,
|
||||||
{
|
{
|
||||||
path: 'invalid-blog-path',
|
path: 'invalid-blog-path',
|
||||||
routeBasePath: 'blog',
|
routeBasePath: 'blog',
|
||||||
|
|
@ -121,12 +120,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
|
||||||
// Build is quite difficult to mock, so we built the blog beforehand and
|
// Build is quite difficult to mock, so we built the blog beforehand and
|
||||||
// copied the output to the fixture...
|
// copied the output to the fixture...
|
||||||
await testGenerateFeeds(
|
await testGenerateFeeds(
|
||||||
fromPartial({
|
{
|
||||||
siteDir,
|
siteDir,
|
||||||
siteConfig,
|
siteConfig,
|
||||||
i18n: DefaultI18N,
|
i18n: DefaultI18N,
|
||||||
outDir,
|
outDir,
|
||||||
}),
|
} as LoadContext,
|
||||||
{
|
{
|
||||||
path: 'blog',
|
path: 'blog',
|
||||||
routeBasePath: 'blog',
|
routeBasePath: 'blog',
|
||||||
|
|
@ -164,12 +163,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
|
||||||
// Build is quite difficult to mock, so we built the blog beforehand and
|
// Build is quite difficult to mock, so we built the blog beforehand and
|
||||||
// copied the output to the fixture...
|
// copied the output to the fixture...
|
||||||
await testGenerateFeeds(
|
await testGenerateFeeds(
|
||||||
fromPartial({
|
{
|
||||||
siteDir,
|
siteDir,
|
||||||
siteConfig,
|
siteConfig,
|
||||||
i18n: DefaultI18N,
|
i18n: DefaultI18N,
|
||||||
outDir,
|
outDir,
|
||||||
}),
|
} as LoadContext,
|
||||||
{
|
{
|
||||||
path: 'blog',
|
path: 'blog',
|
||||||
routeBasePath: 'blog',
|
routeBasePath: 'blog',
|
||||||
|
|
@ -217,12 +216,12 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
|
||||||
// Build is quite difficult to mock, so we built the blog beforehand and
|
// Build is quite difficult to mock, so we built the blog beforehand and
|
||||||
// copied the output to the fixture...
|
// copied the output to the fixture...
|
||||||
await testGenerateFeeds(
|
await testGenerateFeeds(
|
||||||
fromPartial({
|
{
|
||||||
siteDir,
|
siteDir,
|
||||||
siteConfig,
|
siteConfig,
|
||||||
i18n: DefaultI18N,
|
i18n: DefaultI18N,
|
||||||
outDir,
|
outDir,
|
||||||
}),
|
} as LoadContext,
|
||||||
{
|
{
|
||||||
path: 'blog',
|
path: 'blog',
|
||||||
routeBasePath: 'blog',
|
routeBasePath: 'blog',
|
||||||
|
|
@ -246,48 +245,4 @@ describe.each(['atom', 'rss', 'json'])('%s', (feedType) => {
|
||||||
).toMatchSnapshot();
|
).toMatchSnapshot();
|
||||||
fsMock.mockClear();
|
fsMock.mockClear();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('has feed item for each post - with trailing slash', async () => {
|
|
||||||
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
|
||||||
const outDir = path.join(siteDir, 'build-snap');
|
|
||||||
const siteConfig = {
|
|
||||||
title: 'Hello',
|
|
||||||
baseUrl: '/myBaseUrl/',
|
|
||||||
url: 'https://docusaurus.io',
|
|
||||||
favicon: 'image/favicon.ico',
|
|
||||||
trailingSlash: true,
|
|
||||||
markdown,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Build is quite difficult to mock, so we built the blog beforehand and
|
|
||||||
// copied the output to the fixture...
|
|
||||||
await testGenerateFeeds(
|
|
||||||
fromPartial({
|
|
||||||
siteDir,
|
|
||||||
siteConfig,
|
|
||||||
i18n: DefaultI18N,
|
|
||||||
outDir,
|
|
||||||
}),
|
|
||||||
{
|
|
||||||
path: 'blog',
|
|
||||||
routeBasePath: 'blog',
|
|
||||||
tagsBasePath: 'tags',
|
|
||||||
authorsMapPath: 'authors.yml',
|
|
||||||
include: DEFAULT_OPTIONS.include,
|
|
||||||
exclude: DEFAULT_OPTIONS.exclude,
|
|
||||||
feedOptions: {
|
|
||||||
type: [feedType],
|
|
||||||
copyright: 'Copyright',
|
|
||||||
},
|
|
||||||
readingTime: ({content, defaultReadingTime}) =>
|
|
||||||
defaultReadingTime({content}),
|
|
||||||
truncateMarker: /<!--\s*truncate\s*-->/,
|
|
||||||
} as PluginOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
fsMock.mock.calls.map((call) => call[1] as string),
|
|
||||||
).toMatchSnapshot();
|
|
||||||
fsMock.mockClear();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -8,11 +8,7 @@
|
||||||
import {jest} from '@jest/globals';
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
||||||
import {
|
import {posixPath, getFileCommitDate} from '@docusaurus/utils';
|
||||||
posixPath,
|
|
||||||
getFileCommitDate,
|
|
||||||
LAST_UPDATE_FALLBACK,
|
|
||||||
} from '@docusaurus/utils';
|
|
||||||
import pluginContentBlog from '../index';
|
import pluginContentBlog from '../index';
|
||||||
import {validateOptions} from '../options';
|
import {validateOptions} from '../options';
|
||||||
import type {
|
import type {
|
||||||
|
|
@ -45,7 +41,6 @@ const markdown: MarkdownConfig = {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
},
|
},
|
||||||
remarkRehypeOptions: undefined,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function findByTitle(
|
function findByTitle(
|
||||||
|
|
@ -180,6 +175,7 @@ describe('blog plugin', () => {
|
||||||
description: `date inside front matter`,
|
description: `date inside front matter`,
|
||||||
authors: [],
|
authors: [],
|
||||||
date: new Date('2019-01-01'),
|
date: new Date('2019-01-01'),
|
||||||
|
formattedDate: 'January 1, 2019',
|
||||||
frontMatter: {
|
frontMatter: {
|
||||||
date: new Date('2019-01-01'),
|
date: new Date('2019-01-01'),
|
||||||
tags: ['date'],
|
tags: ['date'],
|
||||||
|
|
@ -224,6 +220,7 @@ describe('blog plugin', () => {
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
date: new Date('2018-12-14'),
|
date: new Date('2018-12-14'),
|
||||||
|
formattedDate: 'December 14, 2018',
|
||||||
frontMatter: {
|
frontMatter: {
|
||||||
authors: [
|
authors: [
|
||||||
{
|
{
|
||||||
|
|
@ -259,6 +256,7 @@ describe('blog plugin', () => {
|
||||||
title: 'Simple Slug',
|
title: 'Simple Slug',
|
||||||
},
|
},
|
||||||
date: new Date('2020-08-16'),
|
date: new Date('2020-08-16'),
|
||||||
|
formattedDate: 'August 16, 2020',
|
||||||
frontMatter: {
|
frontMatter: {
|
||||||
date: '2020/08/16',
|
date: '2020/08/16',
|
||||||
slug: '/hey/my super path/héllô',
|
slug: '/hey/my super path/héllô',
|
||||||
|
|
@ -304,6 +302,7 @@ describe('blog plugin', () => {
|
||||||
title: 'draft',
|
title: 'draft',
|
||||||
},
|
},
|
||||||
date: new Date('2020-08-15'),
|
date: new Date('2020-08-15'),
|
||||||
|
formattedDate: 'August 15, 2020',
|
||||||
frontMatter: {
|
frontMatter: {
|
||||||
author: 'Sébastien Lorber',
|
author: 'Sébastien Lorber',
|
||||||
author_title: 'Docusaurus maintainer',
|
author_title: 'Docusaurus maintainer',
|
||||||
|
|
@ -329,6 +328,7 @@ describe('blog plugin', () => {
|
||||||
description: '',
|
description: '',
|
||||||
authors: [],
|
authors: [],
|
||||||
date: new Date('2019-01-02'),
|
date: new Date('2019-01-02'),
|
||||||
|
formattedDate: 'January 2, 2019',
|
||||||
frontMatter: {
|
frontMatter: {
|
||||||
date: new Date('2019-01-02'),
|
date: new Date('2019-01-02'),
|
||||||
},
|
},
|
||||||
|
|
@ -343,6 +343,39 @@ describe('blog plugin', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('builds simple website blog with localized dates', async () => {
|
||||||
|
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
||||||
|
const blogPostsFrench = await getBlogPosts(siteDir, {}, getI18n('fr'));
|
||||||
|
expect(blogPostsFrench).toHaveLength(10);
|
||||||
|
expect(blogPostsFrench[0]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"23 juillet 2023"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[1]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"6 mars 2021"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[2]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"5 mars 2021"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[3]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"16 août 2020"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[4]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"15 août 2020"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[5]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"27 février 2020"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[6]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"27 février 2020"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[7]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"2 janvier 2019"`,
|
||||||
|
);
|
||||||
|
expect(blogPostsFrench[8]!.metadata.formattedDate).toMatchInlineSnapshot(
|
||||||
|
`"1 janvier 2019"`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('handles edit URL with editLocalizedBlogs: true', async () => {
|
it('handles edit URL with editLocalizedBlogs: true', async () => {
|
||||||
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
const siteDir = path.join(__dirname, '__fixtures__', 'website');
|
||||||
const blogPosts = await getBlogPosts(siteDir, {editLocalizedFiles: true});
|
const blogPosts = await getBlogPosts(siteDir, {editLocalizedFiles: true});
|
||||||
|
|
@ -441,8 +474,13 @@ describe('blog plugin', () => {
|
||||||
const noDateSource = path.posix.join('@site', PluginPath, 'no date.md');
|
const noDateSource = path.posix.join('@site', PluginPath, 'no date.md');
|
||||||
const noDateSourceFile = path.posix.join(siteDir, PluginPath, 'no date.md');
|
const noDateSourceFile = path.posix.join(siteDir, PluginPath, 'no date.md');
|
||||||
// We know the file exists and we know we have git
|
// We know the file exists and we know we have git
|
||||||
const result = await getFileCommitDate(noDateSourceFile, {age: 'oldest'});
|
const result = getFileCommitDate(noDateSourceFile, {age: 'oldest'});
|
||||||
const noDateSourceTime = result.date;
|
const noDateSourceTime = result.date;
|
||||||
|
const formattedDate = Intl.DateTimeFormat('en', {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
}).format(noDateSourceTime);
|
||||||
|
|
||||||
expect({
|
expect({
|
||||||
...getByTitle(blogPosts, 'no date').metadata,
|
...getByTitle(blogPosts, 'no date').metadata,
|
||||||
|
|
@ -456,6 +494,7 @@ describe('blog plugin', () => {
|
||||||
description: `no date`,
|
description: `no date`,
|
||||||
authors: [],
|
authors: [],
|
||||||
date: noDateSourceTime,
|
date: noDateSourceTime,
|
||||||
|
formattedDate,
|
||||||
frontMatter: {},
|
frontMatter: {},
|
||||||
tags: [],
|
tags: [],
|
||||||
prevItem: undefined,
|
prevItem: undefined,
|
||||||
|
|
@ -502,165 +541,4 @@ describe('blog plugin', () => {
|
||||||
|
|
||||||
expect(blogTags).toMatchSnapshot();
|
expect(blogTags).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('process blog posts load content', async () => {
|
|
||||||
const siteDir = path.join(
|
|
||||||
__dirname,
|
|
||||||
'__fixtures__',
|
|
||||||
'website-blog-with-tags',
|
|
||||||
);
|
|
||||||
const plugin = await getPlugin(
|
|
||||||
siteDir,
|
|
||||||
{
|
|
||||||
postsPerPage: 1,
|
|
||||||
processBlogPosts: async ({blogPosts}) =>
|
|
||||||
blogPosts.filter((blog) => blog.metadata.tags[0]?.label === 'tag1'),
|
|
||||||
},
|
|
||||||
DefaultI18N,
|
|
||||||
);
|
|
||||||
const {blogPosts, blogTags, blogListPaginated} =
|
|
||||||
(await plugin.loadContent!())!;
|
|
||||||
|
|
||||||
expect(blogListPaginated).toHaveLength(3);
|
|
||||||
|
|
||||||
expect(Object.keys(blogTags)).toHaveLength(2);
|
|
||||||
expect(blogTags).toMatchSnapshot();
|
|
||||||
|
|
||||||
expect(blogPosts).toHaveLength(3);
|
|
||||||
expect(blogPosts).toMatchSnapshot();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('last update', () => {
|
|
||||||
const siteDir = path.join(
|
|
||||||
__dirname,
|
|
||||||
'__fixtures__',
|
|
||||||
'website-blog-with-last-update',
|
|
||||||
);
|
|
||||||
|
|
||||||
const lastUpdateFor = (date: string) => new Date(date).getTime();
|
|
||||||
|
|
||||||
it('author and time', async () => {
|
|
||||||
const plugin = await getPlugin(
|
|
||||||
siteDir,
|
|
||||||
{
|
|
||||||
showLastUpdateAuthor: true,
|
|
||||||
showLastUpdateTime: true,
|
|
||||||
},
|
|
||||||
DefaultI18N,
|
|
||||||
);
|
|
||||||
const {blogPosts} = (await plugin.loadContent!())!;
|
|
||||||
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedBy).toBe('seb');
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedAt,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedBy).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedBy,
|
|
||||||
);
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedAt,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedBy).toBe('seb');
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
lastUpdateFor('2021-01-01'),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedBy).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedBy,
|
|
||||||
);
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
lastUpdateFor('2021-01-01'),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('time only', async () => {
|
|
||||||
const plugin = await getPlugin(
|
|
||||||
siteDir,
|
|
||||||
{
|
|
||||||
showLastUpdateAuthor: false,
|
|
||||||
showLastUpdateTime: true,
|
|
||||||
},
|
|
||||||
DefaultI18N,
|
|
||||||
);
|
|
||||||
const {blogPosts} = (await plugin.loadContent!())!;
|
|
||||||
|
|
||||||
expect(blogPosts[0]?.metadata.title).toBe('Author');
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedAt,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(blogPosts[1]?.metadata.title).toBe('Nothing');
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedAt,
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(blogPosts[2]?.metadata.title).toBe('Both');
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
lastUpdateFor('2021-01-01'),
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(blogPosts[3]?.metadata.title).toBe('Last update date');
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedAt).toBe(
|
|
||||||
lastUpdateFor('2021-01-01'),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('author only', async () => {
|
|
||||||
const plugin = await getPlugin(
|
|
||||||
siteDir,
|
|
||||||
{
|
|
||||||
showLastUpdateAuthor: true,
|
|
||||||
showLastUpdateTime: false,
|
|
||||||
},
|
|
||||||
DefaultI18N,
|
|
||||||
);
|
|
||||||
const {blogPosts} = (await plugin.loadContent!())!;
|
|
||||||
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedBy).toBe('seb');
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedBy).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedBy,
|
|
||||||
);
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedBy).toBe('seb');
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedBy).toBe(
|
|
||||||
LAST_UPDATE_FALLBACK.lastUpdatedBy,
|
|
||||||
);
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('none', async () => {
|
|
||||||
const plugin = await getPlugin(
|
|
||||||
siteDir,
|
|
||||||
{
|
|
||||||
showLastUpdateAuthor: false,
|
|
||||||
showLastUpdateTime: false,
|
|
||||||
},
|
|
||||||
DefaultI18N,
|
|
||||||
);
|
|
||||||
const {blogPosts} = (await plugin.loadContent!())!;
|
|
||||||
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[0]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[1]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[2]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedBy).toBeUndefined();
|
|
||||||
expect(blogPosts[3]?.metadata.lastUpdatedAt).toBeUndefined();
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,7 @@ const sampleBlogPosts: BlogPost[] = [
|
||||||
source: '/blog/2021/06/19/hello',
|
source: '/blog/2021/06/19/hello',
|
||||||
description: '/blog/2021/06/19/hello',
|
description: '/blog/2021/06/19/hello',
|
||||||
date: new Date(2021, 6, 19),
|
date: new Date(2021, 6, 19),
|
||||||
|
formattedDate: 'June 19, 2021',
|
||||||
tags: [],
|
tags: [],
|
||||||
title: 'Hello',
|
title: 'Hello',
|
||||||
hasTruncateMarker: true,
|
hasTruncateMarker: true,
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import {
|
||||||
getContentPathList,
|
getContentPathList,
|
||||||
isUnlisted,
|
isUnlisted,
|
||||||
isDraft,
|
isDraft,
|
||||||
readLastUpdateData,
|
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import {validateBlogPostFrontMatter} from './frontMatter';
|
import {validateBlogPostFrontMatter} from './frontMatter';
|
||||||
import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors';
|
import {type AuthorsMap, getAuthorsMap, getBlogPostAuthors} from './authors';
|
||||||
|
|
@ -58,14 +57,12 @@ export function paginateBlogPosts({
|
||||||
blogTitle,
|
blogTitle,
|
||||||
blogDescription,
|
blogDescription,
|
||||||
postsPerPageOption,
|
postsPerPageOption,
|
||||||
pageBasePath,
|
|
||||||
}: {
|
}: {
|
||||||
blogPosts: BlogPost[];
|
blogPosts: BlogPost[];
|
||||||
basePageUrl: string;
|
basePageUrl: string;
|
||||||
blogTitle: string;
|
blogTitle: string;
|
||||||
blogDescription: string;
|
blogDescription: string;
|
||||||
postsPerPageOption: number | 'ALL';
|
postsPerPageOption: number | 'ALL';
|
||||||
pageBasePath: string;
|
|
||||||
}): BlogPaginated[] {
|
}): BlogPaginated[] {
|
||||||
const totalCount = blogPosts.length;
|
const totalCount = blogPosts.length;
|
||||||
const postsPerPage =
|
const postsPerPage =
|
||||||
|
|
@ -76,7 +73,7 @@ export function paginateBlogPosts({
|
||||||
|
|
||||||
function permalink(page: number) {
|
function permalink(page: number) {
|
||||||
return page > 0
|
return page > 0
|
||||||
? normalizeUrl([basePageUrl, pageBasePath, `${page + 1}`])
|
? normalizeUrl([basePageUrl, `page/${page + 1}`])
|
||||||
: basePageUrl;
|
: basePageUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -114,7 +111,6 @@ export function getBlogTags({
|
||||||
blogTitle: string;
|
blogTitle: string;
|
||||||
blogDescription: string;
|
blogDescription: string;
|
||||||
postsPerPageOption: number | 'ALL';
|
postsPerPageOption: number | 'ALL';
|
||||||
pageBasePath: string;
|
|
||||||
}): BlogTags {
|
}): BlogTags {
|
||||||
const groups = groupTaggedItems(
|
const groups = groupTaggedItems(
|
||||||
blogPosts,
|
blogPosts,
|
||||||
|
|
@ -165,6 +161,25 @@ export function parseBlogFileName(
|
||||||
return {date: undefined, text, slug};
|
return {date: undefined, text, slug};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function formatBlogPostDate(
|
||||||
|
locale: string,
|
||||||
|
date: Date,
|
||||||
|
calendar: string,
|
||||||
|
): string {
|
||||||
|
try {
|
||||||
|
return new Intl.DateTimeFormat(locale, {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
timeZone: 'UTC',
|
||||||
|
calendar,
|
||||||
|
}).format(date);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error`Can't format blog post date "${String(date)}"`;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function parseBlogPostMarkdownFile({
|
async function parseBlogPostMarkdownFile({
|
||||||
filePath,
|
filePath,
|
||||||
parseFrontMatter,
|
parseFrontMatter,
|
||||||
|
|
@ -232,12 +247,6 @@ async function processBlogSourceFile(
|
||||||
|
|
||||||
const aliasedSource = aliasedSitePath(blogSourceAbsolute, siteDir);
|
const aliasedSource = aliasedSitePath(blogSourceAbsolute, siteDir);
|
||||||
|
|
||||||
const lastUpdate = await readLastUpdateData(
|
|
||||||
blogSourceAbsolute,
|
|
||||||
options,
|
|
||||||
frontMatter.last_update,
|
|
||||||
);
|
|
||||||
|
|
||||||
const draft = isDraft({frontMatter});
|
const draft = isDraft({frontMatter});
|
||||||
const unlisted = isUnlisted({frontMatter});
|
const unlisted = isUnlisted({frontMatter});
|
||||||
|
|
||||||
|
|
@ -265,11 +274,10 @@ async function processBlogSourceFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const result = await getFileCommitDate(blogSourceAbsolute, {
|
const result = getFileCommitDate(blogSourceAbsolute, {
|
||||||
age: 'oldest',
|
age: 'oldest',
|
||||||
includeAuthor: false,
|
includeAuthor: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
return result.date;
|
return result.date;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.warn(err);
|
logger.warn(err);
|
||||||
|
|
@ -278,6 +286,11 @@ async function processBlogSourceFile(
|
||||||
}
|
}
|
||||||
|
|
||||||
const date = await getDate();
|
const date = await getDate();
|
||||||
|
const formattedDate = formatBlogPostDate(
|
||||||
|
i18n.currentLocale,
|
||||||
|
date,
|
||||||
|
i18n.localeConfigs[i18n.currentLocale]!.calendar,
|
||||||
|
);
|
||||||
|
|
||||||
const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text;
|
const title = frontMatter.title ?? contentTitle ?? parsedBlogFileName.text;
|
||||||
const description = frontMatter.description ?? excerpt ?? '';
|
const description = frontMatter.description ?? excerpt ?? '';
|
||||||
|
|
@ -332,6 +345,7 @@ async function processBlogSourceFile(
|
||||||
title,
|
title,
|
||||||
description,
|
description,
|
||||||
date,
|
date,
|
||||||
|
formattedDate,
|
||||||
tags: normalizeFrontMatterTags(tagsBasePath, frontMatter.tags),
|
tags: normalizeFrontMatterTags(tagsBasePath, frontMatter.tags),
|
||||||
readingTime: showReadingTime
|
readingTime: showReadingTime
|
||||||
? options.readingTime({
|
? options.readingTime({
|
||||||
|
|
@ -344,8 +358,6 @@ async function processBlogSourceFile(
|
||||||
authors,
|
authors,
|
||||||
frontMatter,
|
frontMatter,
|
||||||
unlisted,
|
unlisted,
|
||||||
lastUpdatedAt: lastUpdate.lastUpdatedAt,
|
|
||||||
lastUpdatedBy: lastUpdate.lastUpdatedBy,
|
|
||||||
},
|
},
|
||||||
content,
|
content,
|
||||||
};
|
};
|
||||||
|
|
@ -431,19 +443,3 @@ export function linkify({
|
||||||
|
|
||||||
return newContent;
|
return newContent;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function applyProcessBlogPosts({
|
|
||||||
blogPosts,
|
|
||||||
processBlogPosts,
|
|
||||||
}: {
|
|
||||||
blogPosts: BlogPost[];
|
|
||||||
processBlogPosts: PluginOptions['processBlogPosts'];
|
|
||||||
}): Promise<BlogPost[]> {
|
|
||||||
const processedBlogPosts = await processBlogPosts({blogPosts});
|
|
||||||
|
|
||||||
if (Array.isArray(processedBlogPosts)) {
|
|
||||||
return processedBlogPosts;
|
|
||||||
}
|
|
||||||
|
|
||||||
return blogPosts;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
||||||
*
|
|
||||||
* This source code is licensed under the MIT license found in the
|
|
||||||
* LICENSE file in the root directory of this source tree.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import useRouteContext from '@docusaurus/useRouteContext';
|
|
||||||
import type {BlogMetadata} from '@docusaurus/plugin-content-blog';
|
|
||||||
|
|
||||||
export function useBlogMetadata(): BlogMetadata {
|
|
||||||
const routeContext = useRouteContext();
|
|
||||||
const blogMetadata = routeContext?.data?.blogMetadata;
|
|
||||||
if (!blogMetadata) {
|
|
||||||
throw new Error(
|
|
||||||
"useBlogMetadata() can't be called on the current route because the blog metadata could not be found in route context",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return blogMetadata as BlogMetadata;
|
|
||||||
}
|
|
||||||
|
|
@ -11,10 +11,7 @@ import logger from '@docusaurus/logger';
|
||||||
import {Feed, type Author as FeedAuthor} from 'feed';
|
import {Feed, type Author as FeedAuthor} from 'feed';
|
||||||
import * as srcset from 'srcset';
|
import * as srcset from 'srcset';
|
||||||
import {normalizeUrl, readOutputHTMLFile} from '@docusaurus/utils';
|
import {normalizeUrl, readOutputHTMLFile} from '@docusaurus/utils';
|
||||||
import {
|
import {blogPostContainerID} from '@docusaurus/utils-common';
|
||||||
blogPostContainerID,
|
|
||||||
applyTrailingSlash,
|
|
||||||
} from '@docusaurus/utils-common';
|
|
||||||
import {load as cheerioLoad} from 'cheerio';
|
import {load as cheerioLoad} from 'cheerio';
|
||||||
import type {DocusaurusConfig} from '@docusaurus/types';
|
import type {DocusaurusConfig} from '@docusaurus/types';
|
||||||
import type {
|
import type {
|
||||||
|
|
@ -43,14 +40,8 @@ async function generateBlogFeed({
|
||||||
}
|
}
|
||||||
|
|
||||||
const {feedOptions, routeBasePath} = options;
|
const {feedOptions, routeBasePath} = options;
|
||||||
const {url: siteUrl, baseUrl, title, favicon, trailingSlash} = siteConfig;
|
const {url: siteUrl, baseUrl, title, favicon} = siteConfig;
|
||||||
const blogBaseUrl = applyTrailingSlash(
|
const blogBaseUrl = normalizeUrl([siteUrl, baseUrl, routeBasePath]);
|
||||||
normalizeUrl([siteUrl, baseUrl, routeBasePath]),
|
|
||||||
{
|
|
||||||
trailingSlash,
|
|
||||||
baseUrl,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const blogPostsForFeed =
|
const blogPostsForFeed =
|
||||||
feedOptions.limit === false || feedOptions.limit === null
|
feedOptions.limit === false || feedOptions.limit === null
|
||||||
|
|
@ -94,7 +85,7 @@ async function defaultCreateFeedItems({
|
||||||
siteConfig: DocusaurusConfig;
|
siteConfig: DocusaurusConfig;
|
||||||
outDir: string;
|
outDir: string;
|
||||||
}): Promise<BlogFeedItem[]> {
|
}): Promise<BlogFeedItem[]> {
|
||||||
const {url: siteUrl, baseUrl, trailingSlash} = siteConfig;
|
const {url: siteUrl} = siteConfig;
|
||||||
|
|
||||||
function toFeedAuthor(author: Author): FeedAuthor {
|
function toFeedAuthor(author: Author): FeedAuthor {
|
||||||
return {name: author.name, link: author.url, email: author.email};
|
return {name: author.name, link: author.url, email: author.email};
|
||||||
|
|
@ -114,19 +105,13 @@ async function defaultCreateFeedItems({
|
||||||
} = post;
|
} = post;
|
||||||
|
|
||||||
const content = await readOutputHTMLFile(
|
const content = await readOutputHTMLFile(
|
||||||
permalink.replace(baseUrl, ''),
|
permalink.replace(siteConfig.baseUrl, ''),
|
||||||
outDir,
|
outDir,
|
||||||
trailingSlash,
|
siteConfig.trailingSlash,
|
||||||
);
|
);
|
||||||
const $ = cheerioLoad(content);
|
const $ = cheerioLoad(content);
|
||||||
|
|
||||||
const blogPostAbsoluteUrl = applyTrailingSlash(
|
const blogPostAbsoluteUrl = normalizeUrl([siteUrl, permalink]);
|
||||||
normalizeUrl([siteUrl, permalink]),
|
|
||||||
{
|
|
||||||
trailingSlash,
|
|
||||||
baseUrl,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const toAbsoluteUrl = (src: string) =>
|
const toAbsoluteUrl = (src: string) =>
|
||||||
String(new URL(src, blogPostAbsoluteUrl));
|
String(new URL(src, blogPostAbsoluteUrl));
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,14 @@
|
||||||
* This source code is licensed under the MIT license found in the
|
* This source code is licensed under the MIT license found in the
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ContentVisibilitySchema,
|
|
||||||
FrontMatterLastUpdateSchema,
|
|
||||||
FrontMatterTOCHeadingLevels,
|
|
||||||
FrontMatterTagsSchema,
|
|
||||||
JoiFrontMatter as Joi, // Custom instance for front matter
|
JoiFrontMatter as Joi, // Custom instance for front matter
|
||||||
URISchema,
|
URISchema,
|
||||||
validateFrontMatter,
|
validateFrontMatter,
|
||||||
|
FrontMatterTagsSchema,
|
||||||
|
FrontMatterTOCHeadingLevels,
|
||||||
|
ContentVisibilitySchema,
|
||||||
} from '@docusaurus/utils-validation';
|
} from '@docusaurus/utils-validation';
|
||||||
import type {BlogPostFrontMatter} from '@docusaurus/plugin-content-blog';
|
import type {BlogPostFrontMatter} from '@docusaurus/plugin-content-blog';
|
||||||
|
|
||||||
|
|
@ -69,7 +69,6 @@ const BlogFrontMatterSchema = Joi.object<BlogPostFrontMatter>({
|
||||||
hide_table_of_contents: Joi.boolean(),
|
hide_table_of_contents: Joi.boolean(),
|
||||||
|
|
||||||
...FrontMatterTOCHeadingLevels,
|
...FrontMatterTOCHeadingLevels,
|
||||||
last_update: FrontMatterLastUpdateSchema,
|
|
||||||
})
|
})
|
||||||
.messages({
|
.messages({
|
||||||
'deprecate.error':
|
'deprecate.error':
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import {
|
||||||
normalizeUrl,
|
normalizeUrl,
|
||||||
docuHash,
|
docuHash,
|
||||||
aliasedSitePath,
|
aliasedSitePath,
|
||||||
aliasedSitePathToRelativePath,
|
|
||||||
getPluginI18nPath,
|
getPluginI18nPath,
|
||||||
posixPath,
|
posixPath,
|
||||||
addTrailingPathSeparator,
|
addTrailingPathSeparator,
|
||||||
|
|
@ -21,12 +20,11 @@ import {
|
||||||
DEFAULT_PLUGIN_ID,
|
DEFAULT_PLUGIN_ID,
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import {
|
import {
|
||||||
|
generateBlogPosts,
|
||||||
getSourceToPermalink,
|
getSourceToPermalink,
|
||||||
getBlogTags,
|
getBlogTags,
|
||||||
paginateBlogPosts,
|
paginateBlogPosts,
|
||||||
shouldBeListed,
|
shouldBeListed,
|
||||||
applyProcessBlogPosts,
|
|
||||||
generateBlogPosts,
|
|
||||||
} from './blogUtils';
|
} from './blogUtils';
|
||||||
import footnoteIDFixer from './remark/footnoteIDFixer';
|
import footnoteIDFixer from './remark/footnoteIDFixer';
|
||||||
import {translateContent, getTranslationFiles} from './translations';
|
import {translateContent, getTranslationFiles} from './translations';
|
||||||
|
|
@ -34,12 +32,7 @@ import {createBlogFeedFiles} from './feed';
|
||||||
|
|
||||||
import {toTagProp, toTagsProp} from './props';
|
import {toTagProp, toTagsProp} from './props';
|
||||||
import type {BlogContentPaths, BlogMarkdownLoaderOptions} from './types';
|
import type {BlogContentPaths, BlogMarkdownLoaderOptions} from './types';
|
||||||
import type {
|
import type {LoadContext, Plugin, HtmlTags} from '@docusaurus/types';
|
||||||
LoadContext,
|
|
||||||
Plugin,
|
|
||||||
HtmlTags,
|
|
||||||
RouteMetadata,
|
|
||||||
} from '@docusaurus/types';
|
|
||||||
import type {
|
import type {
|
||||||
PluginOptions,
|
PluginOptions,
|
||||||
BlogPostFrontMatter,
|
BlogPostFrontMatter,
|
||||||
|
|
@ -49,7 +42,6 @@ import type {
|
||||||
BlogTags,
|
BlogTags,
|
||||||
BlogContent,
|
BlogContent,
|
||||||
BlogPaginated,
|
BlogPaginated,
|
||||||
BlogMetadata,
|
|
||||||
} from '@docusaurus/plugin-content-blog';
|
} from '@docusaurus/plugin-content-blog';
|
||||||
|
|
||||||
export default async function pluginContentBlog(
|
export default async function pluginContentBlog(
|
||||||
|
|
@ -115,16 +107,11 @@ export default async function pluginContentBlog(
|
||||||
blogDescription,
|
blogDescription,
|
||||||
blogTitle,
|
blogTitle,
|
||||||
blogSidebarTitle,
|
blogSidebarTitle,
|
||||||
pageBasePath,
|
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
|
const baseBlogUrl = normalizeUrl([baseUrl, routeBasePath]);
|
||||||
const blogTagsListPath = normalizeUrl([baseBlogUrl, tagsBasePath]);
|
const blogTagsListPath = normalizeUrl([baseBlogUrl, tagsBasePath]);
|
||||||
let blogPosts = await generateBlogPosts(contentPaths, context, options);
|
const blogPosts = await generateBlogPosts(contentPaths, context, options);
|
||||||
blogPosts = await applyProcessBlogPosts({
|
|
||||||
blogPosts,
|
|
||||||
processBlogPosts: options.processBlogPosts,
|
|
||||||
});
|
|
||||||
const listedBlogPosts = blogPosts.filter(shouldBeListed);
|
const listedBlogPosts = blogPosts.filter(shouldBeListed);
|
||||||
|
|
||||||
if (!blogPosts.length) {
|
if (!blogPosts.length) {
|
||||||
|
|
@ -134,10 +121,11 @@ export default async function pluginContentBlog(
|
||||||
blogListPaginated: [],
|
blogListPaginated: [],
|
||||||
blogTags: {},
|
blogTags: {},
|
||||||
blogTagsListPath,
|
blogTagsListPath,
|
||||||
|
blogTagsPaginated: [],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Collocate next and prev metadata.
|
// Colocate next and prev metadata.
|
||||||
listedBlogPosts.forEach((blogPost, index) => {
|
listedBlogPosts.forEach((blogPost, index) => {
|
||||||
const prevItem = index > 0 ? listedBlogPosts[index - 1] : null;
|
const prevItem = index > 0 ? listedBlogPosts[index - 1] : null;
|
||||||
if (prevItem) {
|
if (prevItem) {
|
||||||
|
|
@ -165,7 +153,6 @@ export default async function pluginContentBlog(
|
||||||
blogDescription,
|
blogDescription,
|
||||||
postsPerPageOption,
|
postsPerPageOption,
|
||||||
basePageUrl: baseBlogUrl,
|
basePageUrl: baseBlogUrl,
|
||||||
pageBasePath,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const blogTags: BlogTags = getBlogTags({
|
const blogTags: BlogTags = getBlogTags({
|
||||||
|
|
@ -173,7 +160,6 @@ export default async function pluginContentBlog(
|
||||||
postsPerPageOption,
|
postsPerPageOption,
|
||||||
blogDescription,
|
blogDescription,
|
||||||
blogTitle,
|
blogTitle,
|
||||||
pageBasePath,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -194,7 +180,6 @@ export default async function pluginContentBlog(
|
||||||
blogArchiveComponent,
|
blogArchiveComponent,
|
||||||
routeBasePath,
|
routeBasePath,
|
||||||
archiveBasePath,
|
archiveBasePath,
|
||||||
blogTitle,
|
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
const {addRoute, createData} = actions;
|
const {addRoute, createData} = actions;
|
||||||
|
|
@ -270,24 +255,6 @@ export default async function pluginContentBlog(
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const blogMetadata: BlogMetadata = {
|
|
||||||
blogBasePath: normalizeUrl([baseUrl, routeBasePath]),
|
|
||||||
blogTitle,
|
|
||||||
};
|
|
||||||
const blogMetadataPath = await createData(
|
|
||||||
`blogMetadata-${pluginId}.json`,
|
|
||||||
JSON.stringify(blogMetadata, null, 2),
|
|
||||||
);
|
|
||||||
|
|
||||||
function createBlogPostRouteMetadata(
|
|
||||||
blogPostMeta: BlogPostMetadata,
|
|
||||||
): RouteMetadata {
|
|
||||||
return {
|
|
||||||
sourceFilePath: aliasedSitePathToRelativePath(blogPostMeta.source),
|
|
||||||
lastUpdatedAt: blogPostMeta.lastUpdatedAt,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create routes for blog entries.
|
// Create routes for blog entries.
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
blogPosts.map(async (blogPost) => {
|
blogPosts.map(async (blogPost) => {
|
||||||
|
|
@ -307,10 +274,6 @@ export default async function pluginContentBlog(
|
||||||
sidebar: aliasedSource(sidebarProp),
|
sidebar: aliasedSource(sidebarProp),
|
||||||
content: metadata.source,
|
content: metadata.source,
|
||||||
},
|
},
|
||||||
metadata: createBlogPostRouteMetadata(metadata),
|
|
||||||
context: {
|
|
||||||
blogMetadata: aliasedSource(blogMetadataPath),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
blogItemsToMetadata[id] = metadata;
|
blogItemsToMetadata[id] = metadata;
|
||||||
|
|
|
||||||
|
|
@ -45,15 +45,11 @@ export const DEFAULT_OPTIONS: PluginOptions = {
|
||||||
routeBasePath: 'blog',
|
routeBasePath: 'blog',
|
||||||
tagsBasePath: 'tags',
|
tagsBasePath: 'tags',
|
||||||
archiveBasePath: 'archive',
|
archiveBasePath: 'archive',
|
||||||
pageBasePath: 'page',
|
|
||||||
path: 'blog',
|
path: 'blog',
|
||||||
editLocalizedFiles: false,
|
editLocalizedFiles: false,
|
||||||
authorsMapPath: 'authors.yml',
|
authorsMapPath: 'authors.yml',
|
||||||
readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}),
|
readingTime: ({content, defaultReadingTime}) => defaultReadingTime({content}),
|
||||||
sortPosts: 'descending',
|
sortPosts: 'descending',
|
||||||
showLastUpdateTime: false,
|
|
||||||
showLastUpdateAuthor: false,
|
|
||||||
processBlogPosts: async () => undefined,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const PluginOptionSchema = Joi.object<PluginOptions>({
|
const PluginOptionSchema = Joi.object<PluginOptions>({
|
||||||
|
|
@ -63,7 +59,6 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
|
||||||
.allow(null),
|
.allow(null),
|
||||||
routeBasePath: RouteBasePathSchema.default(DEFAULT_OPTIONS.routeBasePath),
|
routeBasePath: RouteBasePathSchema.default(DEFAULT_OPTIONS.routeBasePath),
|
||||||
tagsBasePath: Joi.string().default(DEFAULT_OPTIONS.tagsBasePath),
|
tagsBasePath: Joi.string().default(DEFAULT_OPTIONS.tagsBasePath),
|
||||||
pageBasePath: Joi.string().default(DEFAULT_OPTIONS.pageBasePath),
|
|
||||||
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
include: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.include),
|
||||||
exclude: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.exclude),
|
exclude: Joi.array().items(Joi.string()).default(DEFAULT_OPTIONS.exclude),
|
||||||
postsPerPage: Joi.alternatives()
|
postsPerPage: Joi.alternatives()
|
||||||
|
|
@ -137,13 +132,6 @@ const PluginOptionSchema = Joi.object<PluginOptions>({
|
||||||
sortPosts: Joi.string()
|
sortPosts: Joi.string()
|
||||||
.valid('descending', 'ascending')
|
.valid('descending', 'ascending')
|
||||||
.default(DEFAULT_OPTIONS.sortPosts),
|
.default(DEFAULT_OPTIONS.sortPosts),
|
||||||
showLastUpdateTime: Joi.bool().default(DEFAULT_OPTIONS.showLastUpdateTime),
|
|
||||||
showLastUpdateAuthor: Joi.bool().default(
|
|
||||||
DEFAULT_OPTIONS.showLastUpdateAuthor,
|
|
||||||
),
|
|
||||||
processBlogPosts: Joi.function()
|
|
||||||
.optional()
|
|
||||||
.default(() => DEFAULT_OPTIONS.processBlogPosts),
|
|
||||||
}).default(DEFAULT_OPTIONS);
|
}).default(DEFAULT_OPTIONS);
|
||||||
|
|
||||||
export function validateOptions({
|
export function validateOptions({
|
||||||
|
|
|
||||||
|
|
@ -5,17 +5,10 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// <reference types="@docusaurus/module-type-aliases" />
|
|
||||||
|
|
||||||
declare module '@docusaurus/plugin-content-blog' {
|
declare module '@docusaurus/plugin-content-blog' {
|
||||||
import type {LoadedMDXContent} from '@docusaurus/mdx-loader';
|
import type {LoadedMDXContent} from '@docusaurus/mdx-loader';
|
||||||
import type {MDXOptions} from '@docusaurus/mdx-loader';
|
import type {MDXOptions} from '@docusaurus/mdx-loader';
|
||||||
import type {
|
import type {FrontMatterTag, Tag} from '@docusaurus/utils';
|
||||||
FrontMatterTag,
|
|
||||||
Tag,
|
|
||||||
LastUpdateData,
|
|
||||||
FrontMatterLastUpdate,
|
|
||||||
} from '@docusaurus/utils';
|
|
||||||
import type {DocusaurusConfig, Plugin, LoadContext} from '@docusaurus/types';
|
import type {DocusaurusConfig, Plugin, LoadContext} from '@docusaurus/types';
|
||||||
import type {Item as FeedItem} from 'feed';
|
import type {Item as FeedItem} from 'feed';
|
||||||
import type {Overwrite} from 'utility-types';
|
import type {Overwrite} from 'utility-types';
|
||||||
|
|
@ -161,8 +154,6 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
toc_min_heading_level?: number;
|
toc_min_heading_level?: number;
|
||||||
/** Maximum TOC heading level. Must be between 2 and 6. */
|
/** Maximum TOC heading level. Must be between 2 and 6. */
|
||||||
toc_max_heading_level?: number;
|
toc_max_heading_level?: number;
|
||||||
/** Allows overriding the last updated author and/or date. */
|
|
||||||
last_update?: FrontMatterLastUpdate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BlogPostFrontMatterAuthor = Author & {
|
export type BlogPostFrontMatterAuthor = Author & {
|
||||||
|
|
@ -187,7 +178,7 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
| BlogPostFrontMatterAuthor
|
| BlogPostFrontMatterAuthor
|
||||||
| (string | BlogPostFrontMatterAuthor)[];
|
| (string | BlogPostFrontMatterAuthor)[];
|
||||||
|
|
||||||
export type BlogPostMetadata = LastUpdateData & {
|
export type BlogPostMetadata = {
|
||||||
/** Path to the Markdown source, with `@site` alias. */
|
/** Path to the Markdown source, with `@site` alias. */
|
||||||
readonly source: string;
|
readonly source: string;
|
||||||
/**
|
/**
|
||||||
|
|
@ -199,6 +190,11 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
* into a string.
|
* into a string.
|
||||||
*/
|
*/
|
||||||
readonly date: Date;
|
readonly date: Date;
|
||||||
|
/**
|
||||||
|
* Publish date formatted according to the locale, so that the client can
|
||||||
|
* render the date regardless of the existence of `Intl.DateTimeFormat`.
|
||||||
|
*/
|
||||||
|
readonly formattedDate: string;
|
||||||
/** Full link including base URL. */
|
/** Full link including base URL. */
|
||||||
readonly permalink: string;
|
readonly permalink: string;
|
||||||
/**
|
/**
|
||||||
|
|
@ -337,11 +333,6 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
defaultReadingTime: ReadingTimeFunction;
|
defaultReadingTime: ReadingTimeFunction;
|
||||||
},
|
},
|
||||||
) => number | undefined;
|
) => number | undefined;
|
||||||
|
|
||||||
export type ProcessBlogPostsFn = (params: {
|
|
||||||
blogPosts: BlogPost[];
|
|
||||||
}) => Promise<void | BlogPost[]>;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Plugin options after normalization.
|
* Plugin options after normalization.
|
||||||
*/
|
*/
|
||||||
|
|
@ -360,15 +351,10 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
routeBasePath: string;
|
routeBasePath: string;
|
||||||
/**
|
/**
|
||||||
* URL route for the tags section of your blog. Will be appended to
|
* URL route for the tags section of your blog. Will be appended to
|
||||||
* `routeBasePath`.
|
* `routeBasePath`. **DO NOT** include a trailing slash.
|
||||||
*/
|
*/
|
||||||
tagsBasePath: string;
|
tagsBasePath: string;
|
||||||
/**
|
/**
|
||||||
* URL route for the pages section of your blog. Will be appended to
|
|
||||||
* `routeBasePath`.
|
|
||||||
*/
|
|
||||||
pageBasePath: string;
|
|
||||||
/**
|
|
||||||
* URL route for the archive section of your blog. Will be appended to
|
* URL route for the archive section of your blog. Will be appended to
|
||||||
* `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to
|
* `routeBasePath`. **DO NOT** include a trailing slash. Use `null` to
|
||||||
* disable generation of archive.
|
* disable generation of archive.
|
||||||
|
|
@ -433,14 +419,6 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
readingTime: ReadingTimeFunctionOption;
|
readingTime: ReadingTimeFunctionOption;
|
||||||
/** Governs the direction of blog post sorting. */
|
/** Governs the direction of blog post sorting. */
|
||||||
sortPosts: 'ascending' | 'descending';
|
sortPosts: 'ascending' | 'descending';
|
||||||
/** Whether to display the last date the doc was updated. */
|
|
||||||
showLastUpdateTime: boolean;
|
|
||||||
/** Whether to display the author who last updated the doc. */
|
|
||||||
showLastUpdateAuthor: boolean;
|
|
||||||
/** An optional function which can be used to transform blog posts
|
|
||||||
* (filter, modify, delete, etc...).
|
|
||||||
*/
|
|
||||||
processBlogPosts: ProcessBlogPostsFn;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -483,13 +461,6 @@ yarn workspace v1.22.19image` is a collocated image path, this entry will be the
|
||||||
blogTagsListPath: string;
|
blogTagsListPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BlogMetadata = {
|
|
||||||
/** the path to the base of the blog */
|
|
||||||
blogBasePath: string;
|
|
||||||
/** title of the overall blog */
|
|
||||||
blogTitle: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type BlogTags = {
|
export type BlogTags = {
|
||||||
[permalink: string]: BlogTag;
|
[permalink: string]: BlogTag;
|
||||||
};
|
};
|
||||||
|
|
@ -561,7 +532,6 @@ declare module '@theme/BlogPostPage' {
|
||||||
BlogPostFrontMatter,
|
BlogPostFrontMatter,
|
||||||
BlogSidebar,
|
BlogSidebar,
|
||||||
PropBlogPostContent,
|
PropBlogPostContent,
|
||||||
BlogMetadata,
|
|
||||||
} from '@docusaurus/plugin-content-blog';
|
} from '@docusaurus/plugin-content-blog';
|
||||||
|
|
||||||
export type FrontMatter = BlogPostFrontMatter;
|
export type FrontMatter = BlogPostFrontMatter;
|
||||||
|
|
@ -573,8 +543,6 @@ declare module '@theme/BlogPostPage' {
|
||||||
readonly sidebar: BlogSidebar;
|
readonly sidebar: BlogSidebar;
|
||||||
/** Content of this post as an MDX component, with useful metadata. */
|
/** Content of this post as an MDX component, with useful metadata. */
|
||||||
readonly content: Content;
|
readonly content: Content;
|
||||||
/** Metadata about the blog. */
|
|
||||||
readonly blogMetadata: BlogMetadata;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function BlogPostPage(props: Props): JSX.Element;
|
export default function BlogPostPage(props: Props): JSX.Element;
|
||||||
|
|
@ -584,10 +552,6 @@ declare module '@theme/BlogPostPage/Metadata' {
|
||||||
export default function BlogPostPageMetadata(): JSX.Element;
|
export default function BlogPostPageMetadata(): JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/BlogPostPage/StructuredData' {
|
|
||||||
export default function BlogPostStructuredData(): JSX.Element;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '@theme/BlogListPage' {
|
declare module '@theme/BlogListPage' {
|
||||||
import type {Content} from '@theme/BlogPostPage';
|
import type {Content} from '@theme/BlogPostPage';
|
||||||
import type {
|
import type {
|
||||||
|
|
@ -610,28 +574,6 @@ declare module '@theme/BlogListPage' {
|
||||||
export default function BlogListPage(props: Props): JSX.Element;
|
export default function BlogListPage(props: Props): JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@theme/BlogListPage/StructuredData' {
|
|
||||||
import type {Content} from '@theme/BlogPostPage';
|
|
||||||
import type {
|
|
||||||
BlogSidebar,
|
|
||||||
BlogPaginatedMetadata,
|
|
||||||
} from '@docusaurus/plugin-content-blog';
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
/** Blog sidebar. */
|
|
||||||
readonly sidebar: BlogSidebar;
|
|
||||||
/** Metadata of the current listing page. */
|
|
||||||
readonly metadata: BlogPaginatedMetadata;
|
|
||||||
/**
|
|
||||||
* Array of blog posts included on this page. Every post's metadata is also
|
|
||||||
* available.
|
|
||||||
*/
|
|
||||||
readonly items: readonly {readonly content: Content}[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export default function BlogListPageStructuredData(props: Props): JSX.Element;
|
|
||||||
}
|
|
||||||
|
|
||||||
declare module '@theme/BlogTagsListPage' {
|
declare module '@theme/BlogTagsListPage' {
|
||||||
import type {BlogSidebar} from '@docusaurus/plugin-content-blog';
|
import type {BlogSidebar} from '@docusaurus/plugin-content-blog';
|
||||||
import type {TagsListItem} from '@docusaurus/utils';
|
import type {TagsListItem} from '@docusaurus/utils';
|
||||||
|
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
{
|
|
||||||
"extends": "../../tsconfig.json",
|
|
||||||
"compilerOptions": {
|
|
||||||
"noEmit": false,
|
|
||||||
"composite": true,
|
|
||||||
"incremental": true,
|
|
||||||
"tsBuildInfoFile": "./lib/.tsbuildinfo-client",
|
|
||||||
"moduleResolution": "bundler",
|
|
||||||
"module": "esnext",
|
|
||||||
"target": "esnext",
|
|
||||||
"rootDir": "src",
|
|
||||||
"outDir": "lib"
|
|
||||||
},
|
|
||||||
"include": ["src/client", "src/*.d.ts"],
|
|
||||||
"exclude": ["**/__tests__/**"]
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
{
|
{
|
||||||
"extends": "../../tsconfig.json",
|
"extends": "../../tsconfig.json",
|
||||||
"references": [{"path": "./tsconfig.client.json"}],
|
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"noEmit": false,
|
"noEmit": false,
|
||||||
"incremental": true,
|
"incremental": true,
|
||||||
|
|
@ -9,5 +8,5 @@
|
||||||
"outDir": "lib"
|
"outDir": "lib"
|
||||||
},
|
},
|
||||||
"include": ["src"],
|
"include": ["src"],
|
||||||
"exclude": ["src/client", "**/__tests__/**"]
|
"exclude": ["**/__tests__/**"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/plugin-content-docs",
|
"name": "@docusaurus/plugin-content-docs",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Docs plugin for Docusaurus.",
|
"description": "Docs plugin for Docusaurus.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
|
|
@ -35,14 +35,13 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.1.1",
|
||||||
"@docusaurus/logger": "3.2.0",
|
"@docusaurus/logger": "3.1.1",
|
||||||
"@docusaurus/mdx-loader": "3.2.0",
|
"@docusaurus/mdx-loader": "3.1.1",
|
||||||
"@docusaurus/module-type-aliases": "3.2.0",
|
"@docusaurus/module-type-aliases": "3.1.1",
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.1.1",
|
||||||
"@docusaurus/utils": "3.2.0",
|
"@docusaurus/utils": "3.1.1",
|
||||||
"@docusaurus/utils-common": "3.2.0",
|
"@docusaurus/utils-validation": "3.1.1",
|
||||||
"@docusaurus/utils-validation": "3.2.0",
|
|
||||||
"@types/react-router-config": "^5.0.7",
|
"@types/react-router-config": "^5.0.7",
|
||||||
"combine-promises": "^1.1.0",
|
"combine-promises": "^1.1.0",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ exports[`simple website content 1`] = `
|
||||||
"description": "Images",
|
"description": "Images",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "baz",
|
"id": "baz",
|
||||||
"pagination_label": "baz pagination_label",
|
"pagination_label": "baz pagination_label",
|
||||||
|
|
@ -104,6 +105,7 @@ exports[`simple website content 2`] = `
|
||||||
"description": "Hi, Endilie here :)",
|
"description": "Hi, Endilie here :)",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "hello",
|
"id": "hello",
|
||||||
"sidebar_label": "Hello sidebar_label",
|
"sidebar_label": "Hello sidebar_label",
|
||||||
|
|
@ -149,6 +151,7 @@ exports[`simple website content 3`] = `
|
||||||
"description": "This is custom description",
|
"description": "This is custom description",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"description": "This is custom description",
|
"description": "This is custom description",
|
||||||
"id": "bar",
|
"id": "bar",
|
||||||
|
|
@ -1482,10 +1485,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/hello.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/hello.md",
|
"content": "@site/docs/hello.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1495,10 +1494,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/absoluteSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/absoluteSlug.md",
|
"content": "@site/docs/slugs/absoluteSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1516,10 +1511,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/customLastUpdate.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/customLastUpdate.md",
|
"content": "@site/docs/customLastUpdate.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1528,10 +1519,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/doc with space.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/doc with space.md",
|
"content": "@site/docs/doc with space.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1540,10 +1527,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/doc-draft.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/doc-draft.md",
|
"content": "@site/docs/doc-draft.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1552,10 +1535,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/doc-unlisted.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/doc-unlisted.md",
|
"content": "@site/docs/doc-unlisted.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1565,10 +1544,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/foo/bar.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/foo/bar.md",
|
"content": "@site/docs/foo/bar.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1578,10 +1553,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/foo/baz.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/foo/baz.md",
|
"content": "@site/docs/foo/baz.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1591,10 +1562,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/headingAsTitle.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/headingAsTitle.md",
|
"content": "@site/docs/headingAsTitle.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1604,10 +1571,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/rootResolvedSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/rootResolvedSlug.md",
|
"content": "@site/docs/rootResolvedSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1617,10 +1580,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/ipsum.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/ipsum.md",
|
"content": "@site/docs/ipsum.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1629,10 +1588,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/lastUpdateAuthorOnly.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/lastUpdateAuthorOnly.md",
|
"content": "@site/docs/lastUpdateAuthorOnly.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1641,10 +1596,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/lastUpdateDateOnly.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/lastUpdateDateOnly.md",
|
"content": "@site/docs/lastUpdateDateOnly.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1653,10 +1604,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/lorem.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/lorem.md",
|
"content": "@site/docs/lorem.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1665,10 +1612,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/rootAbsoluteSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/rootAbsoluteSlug.md",
|
"content": "@site/docs/rootAbsoluteSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1678,10 +1621,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/rootRelativeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/rootRelativeSlug.md",
|
"content": "@site/docs/rootRelativeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1691,10 +1630,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/rootTryToEscapeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/rootTryToEscapeSlug.md",
|
"content": "@site/docs/rootTryToEscapeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1704,10 +1639,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/resolvedSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/resolvedSlug.md",
|
"content": "@site/docs/slugs/resolvedSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1716,10 +1647,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/relativeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/relativeSlug.md",
|
"content": "@site/docs/slugs/relativeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1728,10 +1655,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/tryToEscapeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/tryToEscapeSlug.md",
|
"content": "@site/docs/slugs/tryToEscapeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1740,10 +1663,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/unlisted-category/index.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/unlisted-category/index.md",
|
"content": "@site/docs/unlisted-category/index.md",
|
||||||
},
|
},
|
||||||
|
|
@ -1753,10 +1672,6 @@ exports[`simple website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/unlisted-category/unlisted-category-doc.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/unlisted-category/unlisted-category-doc.md",
|
"content": "@site/docs/unlisted-category/unlisted-category-doc.md",
|
||||||
},
|
},
|
||||||
|
|
@ -2056,6 +1971,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Getting started text",
|
"description": "Getting started text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "getting-started",
|
"id": "getting-started",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2083,6 +1999,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Installation text",
|
"description": "Installation text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "installation",
|
"id": "installation",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2113,6 +2030,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Guide 1 text",
|
"description": "Guide 1 text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "guide1",
|
"id": "guide1",
|
||||||
"sidebar_position": 1,
|
"sidebar_position": 1,
|
||||||
|
|
@ -2146,6 +2064,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Guide 2 text",
|
"description": "Guide 2 text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "guide2",
|
"id": "guide2",
|
||||||
},
|
},
|
||||||
|
|
@ -2178,6 +2097,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Guide 2.5 text",
|
"description": "Guide 2.5 text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "guide2.5",
|
"id": "guide2.5",
|
||||||
"sidebar_position": 2.5,
|
"sidebar_position": 2.5,
|
||||||
|
|
@ -2211,6 +2131,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Guide 3 text",
|
"description": "Guide 3 text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "guide3",
|
"id": "guide3",
|
||||||
"sidebar_position": 3,
|
"sidebar_position": 3,
|
||||||
|
|
@ -2244,6 +2165,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Guide 4 text",
|
"description": "Guide 4 text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "guide4",
|
"id": "guide4",
|
||||||
},
|
},
|
||||||
|
|
@ -2276,6 +2198,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Guide 5 text",
|
"description": "Guide 5 text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"id": "guide5",
|
"id": "guide5",
|
||||||
},
|
},
|
||||||
|
|
@ -2308,6 +2231,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "API Overview text",
|
"description": "API Overview text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/api-overview",
|
"id": "API/api-overview",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2338,6 +2262,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Client API text",
|
"description": "Client API text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/Core APIs/Client API",
|
"id": "API/Core APIs/Client API",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2368,6 +2293,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Server API text",
|
"description": "Server API text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/Core APIs/Server API",
|
"id": "API/Core APIs/Server API",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2398,6 +2324,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Plugin API text",
|
"description": "Plugin API text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/Extension APIs/Plugin API",
|
"id": "API/Extension APIs/Plugin API",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2428,6 +2355,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "Theme API text",
|
"description": "Theme API text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/Extension APIs/Theme API",
|
"id": "API/Extension APIs/Theme API",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2458,6 +2386,7 @@ exports[`site with full autogenerated sidebar docs in fully generated sidebar ha
|
||||||
"description": "API End text",
|
"description": "API End text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/api-end",
|
"id": "API/api-end",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2637,6 +2566,7 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
|
||||||
"description": "API End text",
|
"description": "API End text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/api-end",
|
"id": "API/api-end",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2664,6 +2594,7 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
|
||||||
"description": "API Overview text",
|
"description": "API Overview text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/api-overview",
|
"id": "API/api-overview",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2694,6 +2625,7 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
|
||||||
"description": "Plugin API text",
|
"description": "Plugin API text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/Extension APIs/Plugin API",
|
"id": "API/Extension APIs/Plugin API",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2724,6 +2656,7 @@ exports[`site with partial autogenerated sidebars docs in partially generated si
|
||||||
"description": "Theme API text",
|
"description": "Theme API text",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "API/Extension APIs/Theme API",
|
"id": "API/Extension APIs/Theme API",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -2783,6 +2716,7 @@ exports[`versioned website (community) content 1`] = `
|
||||||
"description": "Team current version (translated)",
|
"description": "Team current version (translated)",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"title": "Team title translated",
|
"title": "Team title translated",
|
||||||
},
|
},
|
||||||
|
|
@ -2809,6 +2743,7 @@ exports[`versioned website (community) content 2`] = `
|
||||||
"description": "Team 1.0.0",
|
"description": "Team 1.0.0",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "team",
|
"id": "team",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -3028,10 +2963,6 @@ exports[`versioned website (community) content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "i18n/en/docusaurus-plugin-content-docs-community/current/team.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md",
|
"content": "@site/i18n/en/docusaurus-plugin-content-docs-community/current/team.md",
|
||||||
},
|
},
|
||||||
|
|
@ -3059,10 +2990,6 @@ exports[`versioned website (community) content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "community_versioned_docs/version-1.0.0/team.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/community_versioned_docs/version-1.0.0/team.md",
|
"content": "@site/community_versioned_docs/version-1.0.0/team.md",
|
||||||
},
|
},
|
||||||
|
|
@ -3096,6 +3023,7 @@ exports[`versioned website content 1`] = `
|
||||||
"description": "This is next version of bar.",
|
"description": "This is next version of bar.",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"slug": "barSlug",
|
"slug": "barSlug",
|
||||||
"tags": [
|
"tags": [
|
||||||
|
|
@ -3146,6 +3074,7 @@ exports[`versioned website content 2`] = `
|
||||||
"description": "Bar 1.0.1 !",
|
"description": "Bar 1.0.1 !",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "foo/bar",
|
"id": "foo/bar",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -3173,6 +3102,7 @@ exports[`versioned website content 3`] = `
|
||||||
"description": "Hello next !",
|
"description": "Hello next !",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"slug": "/",
|
"slug": "/",
|
||||||
},
|
},
|
||||||
|
|
@ -3202,6 +3132,7 @@ exports[`versioned website content 4`] = `
|
||||||
"description": "Hello 1.0.1 !",
|
"description": "Hello 1.0.1 !",
|
||||||
"draft": false,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {
|
"frontMatter": {
|
||||||
"slug": "/",
|
"slug": "/",
|
||||||
},
|
},
|
||||||
|
|
@ -3231,6 +3162,7 @@ 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,
|
"draft": false,
|
||||||
"editUrl": undefined,
|
"editUrl": undefined,
|
||||||
|
"formattedLastUpdatedAt": undefined,
|
||||||
"frontMatter": {},
|
"frontMatter": {},
|
||||||
"id": "foo/baz",
|
"id": "foo/baz",
|
||||||
"lastUpdatedAt": undefined,
|
"lastUpdatedAt": undefined,
|
||||||
|
|
@ -4270,10 +4202,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md",
|
"content": "@site/i18n/en/docusaurus-plugin-content-docs/version-1.0.0/hello.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4283,10 +4211,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-1.0.0/foo/bar.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-1.0.0/foo/bar.md",
|
"content": "@site/versioned_docs/version-1.0.0/foo/bar.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4296,10 +4220,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-1.0.0/foo/baz.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-1.0.0/foo/baz.md",
|
"content": "@site/versioned_docs/version-1.0.0/foo/baz.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4359,10 +4279,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/hello.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/hello.md",
|
"content": "@site/docs/hello.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4372,10 +4288,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/absoluteSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/absoluteSlug.md",
|
"content": "@site/docs/slugs/absoluteSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4384,10 +4296,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/foo/bar.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/foo/bar.md",
|
"content": "@site/docs/foo/bar.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4397,10 +4305,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/resolvedSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/resolvedSlug.md",
|
"content": "@site/docs/slugs/resolvedSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4409,10 +4313,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/relativeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/relativeSlug.md",
|
"content": "@site/docs/slugs/relativeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4421,10 +4321,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "docs/slugs/tryToEscapeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/docs/slugs/tryToEscapeSlug.md",
|
"content": "@site/docs/slugs/tryToEscapeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4451,10 +4347,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/slugs/absoluteSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/slugs/absoluteSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4463,10 +4355,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/rootResolvedSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/rootResolvedSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/rootResolvedSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4475,10 +4363,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/rootAbsoluteSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/rootAbsoluteSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4488,10 +4372,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/rootRelativeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/rootRelativeSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/rootRelativeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4500,10 +4380,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/rootTryToEscapeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/rootTryToEscapeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4512,10 +4388,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/slugs/resolvedSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/slugs/resolvedSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4524,10 +4396,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/slugs/relativeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/slugs/relativeSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/slugs/relativeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4536,10 +4404,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md",
|
"content": "@site/versioned_docs/version-withSlugs/slugs/tryToEscapeSlug.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4566,10 +4430,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-1.0.1/hello.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-1.0.1/hello.md",
|
"content": "@site/versioned_docs/version-1.0.1/hello.md",
|
||||||
},
|
},
|
||||||
|
|
@ -4579,10 +4439,6 @@ exports[`versioned website content: route config 1`] = `
|
||||||
{
|
{
|
||||||
"component": "@theme/DocItem",
|
"component": "@theme/DocItem",
|
||||||
"exact": true,
|
"exact": true,
|
||||||
"metadata": {
|
|
||||||
"lastUpdatedAt": undefined,
|
|
||||||
"sourceFilePath": "versioned_docs/version-1.0.1/foo/bar.md",
|
|
||||||
},
|
|
||||||
"modules": {
|
"modules": {
|
||||||
"content": "@site/versioned_docs/version-1.0.1/foo/bar.md",
|
"content": "@site/versioned_docs/version-1.0.1/foo/bar.md",
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,8 @@
|
||||||
|
|
||||||
import {jest} from '@jest/globals';
|
import {jest} from '@jest/globals';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {loadContext} from '@docusaurus/core/src/server/site';
|
import {loadContext} from '@docusaurus/core/src/server/index';
|
||||||
import {
|
import {createSlugger, posixPath, DEFAULT_PLUGIN_ID} from '@docusaurus/utils';
|
||||||
createSlugger,
|
|
||||||
posixPath,
|
|
||||||
DEFAULT_PLUGIN_ID,
|
|
||||||
LAST_UPDATE_FALLBACK,
|
|
||||||
} from '@docusaurus/utils';
|
|
||||||
import {createSidebarsUtils} from '../sidebars/utils';
|
import {createSidebarsUtils} from '../sidebars/utils';
|
||||||
import {
|
import {
|
||||||
processDocMetadata,
|
processDocMetadata,
|
||||||
|
|
@ -479,8 +474,9 @@ describe('simple site', () => {
|
||||||
custom_edit_url: 'https://github.com/customUrl/docs/lorem.md',
|
custom_edit_url: 'https://github.com/customUrl/docs/lorem.md',
|
||||||
unrelated_front_matter: "won't be part of metadata",
|
unrelated_front_matter: "won't be part of metadata",
|
||||||
},
|
},
|
||||||
lastUpdatedAt: LAST_UPDATE_FALLBACK.lastUpdatedAt,
|
lastUpdatedAt: 1539502055,
|
||||||
lastUpdatedBy: LAST_UPDATE_FALLBACK.lastUpdatedBy,
|
formattedLastUpdatedAt: 'Oct 14, 2018',
|
||||||
|
lastUpdatedBy: 'Author',
|
||||||
tags: [],
|
tags: [],
|
||||||
unlisted: false,
|
unlisted: false,
|
||||||
});
|
});
|
||||||
|
|
@ -576,7 +572,8 @@ describe('simple site', () => {
|
||||||
},
|
},
|
||||||
title: 'Custom Last Update',
|
title: 'Custom Last Update',
|
||||||
},
|
},
|
||||||
lastUpdatedAt: new Date('1/1/2000').getTime(),
|
lastUpdatedAt: new Date('1/1/2000').getTime() / 1000,
|
||||||
|
formattedLastUpdatedAt: 'Jan 1, 2000',
|
||||||
lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)',
|
lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)',
|
||||||
sidebarPosition: undefined,
|
sidebarPosition: undefined,
|
||||||
tags: [],
|
tags: [],
|
||||||
|
|
@ -614,7 +611,8 @@ describe('simple site', () => {
|
||||||
},
|
},
|
||||||
title: 'Last Update Author Only',
|
title: 'Last Update Author Only',
|
||||||
},
|
},
|
||||||
lastUpdatedAt: LAST_UPDATE_FALLBACK.lastUpdatedAt,
|
lastUpdatedAt: 1539502055,
|
||||||
|
formattedLastUpdatedAt: 'Oct 14, 2018',
|
||||||
lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)',
|
lastUpdatedBy: 'Custom Author (processed by parseFrontMatter)',
|
||||||
sidebarPosition: undefined,
|
sidebarPosition: undefined,
|
||||||
tags: [],
|
tags: [],
|
||||||
|
|
@ -652,7 +650,8 @@ describe('simple site', () => {
|
||||||
},
|
},
|
||||||
title: 'Last Update Date Only',
|
title: 'Last Update Date Only',
|
||||||
},
|
},
|
||||||
lastUpdatedAt: new Date('1/1/2000').getTime(),
|
lastUpdatedAt: new Date('1/1/2000').getTime() / 1000,
|
||||||
|
formattedLastUpdatedAt: 'Jan 1, 2000',
|
||||||
lastUpdatedBy: 'Author',
|
lastUpdatedBy: 'Author',
|
||||||
sidebarPosition: undefined,
|
sidebarPosition: undefined,
|
||||||
tags: [],
|
tags: [],
|
||||||
|
|
@ -692,6 +691,7 @@ describe('simple site', () => {
|
||||||
title: 'Custom Last Update',
|
title: 'Custom Last Update',
|
||||||
},
|
},
|
||||||
lastUpdatedAt: undefined,
|
lastUpdatedAt: undefined,
|
||||||
|
formattedLastUpdatedAt: undefined,
|
||||||
lastUpdatedBy: undefined,
|
lastUpdatedBy: undefined,
|
||||||
sidebarPosition: undefined,
|
sidebarPosition: undefined,
|
||||||
tags: [],
|
tags: [],
|
||||||
|
|
|
||||||
|
|
@ -444,19 +444,19 @@ describe('validateDocFrontMatter last_update', () => {
|
||||||
invalidFrontMatters: [
|
invalidFrontMatters: [
|
||||||
[
|
[
|
||||||
{last_update: null},
|
{last_update: null},
|
||||||
'"last_update" does not look like a valid last update object. Please use an author key with a string or a date with a string or Date',
|
'does not look like a valid front matter FileChange object. Please use a FileChange object (with an author and/or date).',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{last_update: {}},
|
{last_update: {}},
|
||||||
'"last_update" does not look like a valid last update object. Please use an author key with a string or a date with a string or Date',
|
'does not look like a valid front matter FileChange object. Please use a FileChange object (with an author and/or date).',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{last_update: ''},
|
{last_update: ''},
|
||||||
'"last_update" does not look like a valid last update object. Please use an author key with a string or a date with a string or Date',
|
'does not look like a valid front matter FileChange object. Please use a FileChange object (with an author and/or date).',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{last_update: {invalid: 'key'}},
|
{last_update: {invalid: 'key'}},
|
||||||
'"last_update" does not look like a valid last update object. Please use an author key with a string or a date with a string or Date',
|
'does not look like a valid front matter FileChange object. Please use a FileChange object (with an author and/or date).',
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
{last_update: {author: 'test author', date: 'I am not a date :('}},
|
{last_update: {author: 'test author', date: 'I am not a date :('}},
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@ import _ from 'lodash';
|
||||||
import {isMatch} from 'picomatch';
|
import {isMatch} from 'picomatch';
|
||||||
import commander from 'commander';
|
import commander from 'commander';
|
||||||
import webpack from 'webpack';
|
import webpack from 'webpack';
|
||||||
import {loadContext} from '@docusaurus/core/src/server/site';
|
import {loadContext} from '@docusaurus/core/src/server/index';
|
||||||
import {applyConfigureWebpack} from '@docusaurus/core/src/webpack/utils';
|
import {applyConfigureWebpack} from '@docusaurus/core/src/webpack/utils';
|
||||||
import {sortRoutes} from '@docusaurus/core/src/server/plugins/routeConfig';
|
import {sortConfig} from '@docusaurus/core/src/server/plugins/routeConfig';
|
||||||
import {posixPath} from '@docusaurus/utils';
|
import {posixPath} from '@docusaurus/utils';
|
||||||
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ Entries created:
|
||||||
expectSnapshot: () => {
|
expectSnapshot: () => {
|
||||||
// Sort the route config like in src/server/plugins/index.ts for
|
// Sort the route config like in src/server/plugins/index.ts for
|
||||||
// consistent snapshot ordering
|
// consistent snapshot ordering
|
||||||
sortRoutes(routeConfigs);
|
sortConfig(routeConfigs);
|
||||||
expect(routeConfigs).not.toEqual([]);
|
expect(routeConfigs).not.toEqual([]);
|
||||||
expect(routeConfigs).toMatchSnapshot('route config');
|
expect(routeConfigs).toMatchSnapshot('route config');
|
||||||
expect(dataContainer).toMatchSnapshot('data');
|
expect(dataContainer).toMatchSnapshot('data');
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,117 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import {jest} from '@jest/globals';
|
||||||
|
import fs from 'fs-extra';
|
||||||
|
import path from 'path';
|
||||||
|
import shell from 'shelljs';
|
||||||
|
import {createTempRepo} from '@testing-utils/git';
|
||||||
|
|
||||||
|
import {getFileLastUpdate} from '../lastUpdate';
|
||||||
|
|
||||||
|
describe('getFileLastUpdate', () => {
|
||||||
|
const existingFilePath = path.join(
|
||||||
|
__dirname,
|
||||||
|
'__fixtures__/simple-site/docs/hello.md',
|
||||||
|
);
|
||||||
|
it('existing test file in repository with Git timestamp', async () => {
|
||||||
|
const lastUpdateData = await getFileLastUpdate(existingFilePath);
|
||||||
|
expect(lastUpdateData).not.toBeNull();
|
||||||
|
|
||||||
|
const {author, timestamp} = lastUpdateData!;
|
||||||
|
expect(author).not.toBeNull();
|
||||||
|
expect(typeof author).toBe('string');
|
||||||
|
|
||||||
|
expect(timestamp).not.toBeNull();
|
||||||
|
expect(typeof timestamp).toBe('number');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('existing test file with spaces in path', async () => {
|
||||||
|
const filePathWithSpace = path.join(
|
||||||
|
__dirname,
|
||||||
|
'__fixtures__/simple-site/docs/doc with space.md',
|
||||||
|
);
|
||||||
|
const lastUpdateData = await getFileLastUpdate(filePathWithSpace);
|
||||||
|
expect(lastUpdateData).not.toBeNull();
|
||||||
|
|
||||||
|
const {author, timestamp} = lastUpdateData!;
|
||||||
|
expect(author).not.toBeNull();
|
||||||
|
expect(typeof author).toBe('string');
|
||||||
|
|
||||||
|
expect(timestamp).not.toBeNull();
|
||||||
|
expect(typeof timestamp).toBe('number');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('non-existing file', async () => {
|
||||||
|
const consoleMock = jest
|
||||||
|
.spyOn(console, 'warn')
|
||||||
|
.mockImplementation(() => {});
|
||||||
|
const nonExistingFileName = '.nonExisting';
|
||||||
|
const nonExistingFilePath = path.join(
|
||||||
|
__dirname,
|
||||||
|
'__fixtures__',
|
||||||
|
nonExistingFileName,
|
||||||
|
);
|
||||||
|
await expect(getFileLastUpdate(nonExistingFilePath)).resolves.toBeNull();
|
||||||
|
expect(consoleMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(consoleMock).toHaveBeenLastCalledWith(
|
||||||
|
expect.stringMatching(/because the file does not exist./),
|
||||||
|
);
|
||||||
|
consoleMock.mockRestore();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('temporary created file that is not tracked by git', async () => {
|
||||||
|
const consoleMock = jest
|
||||||
|
.spyOn(console, 'warn')
|
||||||
|
.mockImplementation(() => {});
|
||||||
|
const {repoDir} = createTempRepo();
|
||||||
|
const tempFilePath = path.join(repoDir, 'file.md');
|
||||||
|
await fs.writeFile(tempFilePath, 'Lorem ipsum :)');
|
||||||
|
await expect(getFileLastUpdate(tempFilePath)).resolves.toBeNull();
|
||||||
|
expect(consoleMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(consoleMock).toHaveBeenLastCalledWith(
|
||||||
|
expect.stringMatching(/not tracked by git./),
|
||||||
|
);
|
||||||
|
await fs.unlink(tempFilePath);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('multiple files not tracked by git', async () => {
|
||||||
|
const consoleMock = jest
|
||||||
|
.spyOn(console, 'warn')
|
||||||
|
.mockImplementation(() => {});
|
||||||
|
const {repoDir} = createTempRepo();
|
||||||
|
const tempFilePath1 = path.join(repoDir, 'file1.md');
|
||||||
|
const tempFilePath2 = path.join(repoDir, 'file2.md');
|
||||||
|
await fs.writeFile(tempFilePath1, 'Lorem ipsum :)');
|
||||||
|
await fs.writeFile(tempFilePath2, 'Lorem ipsum :)');
|
||||||
|
await expect(getFileLastUpdate(tempFilePath1)).resolves.toBeNull();
|
||||||
|
await expect(getFileLastUpdate(tempFilePath2)).resolves.toBeNull();
|
||||||
|
expect(consoleMock).toHaveBeenCalledTimes(1);
|
||||||
|
expect(consoleMock).toHaveBeenLastCalledWith(
|
||||||
|
expect.stringMatching(/not tracked by git./),
|
||||||
|
);
|
||||||
|
await fs.unlink(tempFilePath1);
|
||||||
|
await fs.unlink(tempFilePath2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('git does not exist', async () => {
|
||||||
|
const mock = jest.spyOn(shell, 'which').mockImplementationOnce(() => null);
|
||||||
|
const consoleMock = jest
|
||||||
|
.spyOn(console, 'warn')
|
||||||
|
.mockImplementation(() => {});
|
||||||
|
const lastUpdateData = await getFileLastUpdate(existingFilePath);
|
||||||
|
expect(lastUpdateData).toBeNull();
|
||||||
|
expect(consoleMock).toHaveBeenLastCalledWith(
|
||||||
|
expect.stringMatching(
|
||||||
|
/.*\[WARNING\].* Sorry, the docs plugin last update options require Git\..*/,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
consoleMock.mockRestore();
|
||||||
|
mock.mockRestore();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -86,20 +86,10 @@ export const useAllDocsData = (): {[pluginId: string]: GlobalPluginData} =>
|
||||||
}
|
}
|
||||||
| undefined) ?? StableEmptyObject;
|
| undefined) ?? StableEmptyObject;
|
||||||
|
|
||||||
export const useDocsData = (pluginId: string | undefined): GlobalPluginData => {
|
export const useDocsData = (pluginId: string | undefined): GlobalPluginData =>
|
||||||
try {
|
usePluginData('docusaurus-plugin-content-docs', pluginId, {
|
||||||
return usePluginData('docusaurus-plugin-content-docs', pluginId, {
|
failfast: true,
|
||||||
failfast: true,
|
}) as GlobalPluginData;
|
||||||
}) as GlobalPluginData;
|
|
||||||
} catch (error) {
|
|
||||||
throw new Error(
|
|
||||||
`You are using a feature of the Docusaurus docs plugin, but this plugin does not seem to be enabled${
|
|
||||||
pluginId === 'Default' ? '' : ` (pluginId=${pluginId}`
|
|
||||||
}`,
|
|
||||||
{cause: error as Error},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO this feature should be provided by docusaurus core
|
// TODO this feature should be provided by docusaurus core
|
||||||
export function useActivePlugin(
|
export function useActivePlugin(
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
import logger from '@docusaurus/logger';
|
||||||
import {
|
import {
|
||||||
aliasedSitePath,
|
aliasedSitePath,
|
||||||
getEditUrl,
|
getEditUrl,
|
||||||
|
|
@ -20,11 +21,12 @@ import {
|
||||||
normalizeFrontMatterTags,
|
normalizeFrontMatterTags,
|
||||||
isUnlisted,
|
isUnlisted,
|
||||||
isDraft,
|
isDraft,
|
||||||
readLastUpdateData,
|
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import {validateDocFrontMatter} from './frontMatter';
|
|
||||||
|
import {getFileLastUpdate} from './lastUpdate';
|
||||||
import getSlug from './slug';
|
import getSlug from './slug';
|
||||||
import {stripPathNumberPrefixes} from './numberPrefix';
|
import {stripPathNumberPrefixes} from './numberPrefix';
|
||||||
|
import {validateDocFrontMatter} from './frontMatter';
|
||||||
import {toDocNavigationLink, toNavigationLink} from './sidebars/utils';
|
import {toDocNavigationLink, toNavigationLink} from './sidebars/utils';
|
||||||
import type {
|
import type {
|
||||||
MetadataOptions,
|
MetadataOptions,
|
||||||
|
|
@ -33,13 +35,61 @@ import type {
|
||||||
DocMetadataBase,
|
DocMetadataBase,
|
||||||
DocMetadata,
|
DocMetadata,
|
||||||
PropNavigationLink,
|
PropNavigationLink,
|
||||||
|
LastUpdateData,
|
||||||
VersionMetadata,
|
VersionMetadata,
|
||||||
LoadedVersion,
|
LoadedVersion,
|
||||||
|
FileChange,
|
||||||
} from '@docusaurus/plugin-content-docs';
|
} from '@docusaurus/plugin-content-docs';
|
||||||
import type {LoadContext} from '@docusaurus/types';
|
import type {LoadContext} from '@docusaurus/types';
|
||||||
import type {SidebarsUtils} from './sidebars/utils';
|
import type {SidebarsUtils} from './sidebars/utils';
|
||||||
import type {DocFile} from './types';
|
import type {DocFile} from './types';
|
||||||
|
|
||||||
|
type LastUpdateOptions = Pick<
|
||||||
|
PluginOptions,
|
||||||
|
'showLastUpdateAuthor' | 'showLastUpdateTime'
|
||||||
|
>;
|
||||||
|
|
||||||
|
async function readLastUpdateData(
|
||||||
|
filePath: string,
|
||||||
|
options: LastUpdateOptions,
|
||||||
|
lastUpdateFrontMatter: FileChange | undefined,
|
||||||
|
): Promise<LastUpdateData> {
|
||||||
|
const {showLastUpdateAuthor, showLastUpdateTime} = options;
|
||||||
|
if (showLastUpdateAuthor || showLastUpdateTime) {
|
||||||
|
const frontMatterTimestamp = lastUpdateFrontMatter?.date
|
||||||
|
? new Date(lastUpdateFrontMatter.date).getTime() / 1000
|
||||||
|
: undefined;
|
||||||
|
|
||||||
|
if (lastUpdateFrontMatter?.author && lastUpdateFrontMatter.date) {
|
||||||
|
return {
|
||||||
|
lastUpdatedAt: frontMatterTimestamp,
|
||||||
|
lastUpdatedBy: lastUpdateFrontMatter.author,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use fake data in dev for faster development.
|
||||||
|
const fileLastUpdateData =
|
||||||
|
process.env.NODE_ENV === 'production'
|
||||||
|
? await getFileLastUpdate(filePath)
|
||||||
|
: {
|
||||||
|
author: 'Author',
|
||||||
|
timestamp: 1539502055,
|
||||||
|
};
|
||||||
|
const {author, timestamp} = fileLastUpdateData ?? {};
|
||||||
|
|
||||||
|
return {
|
||||||
|
lastUpdatedBy: showLastUpdateAuthor
|
||||||
|
? lastUpdateFrontMatter?.author ?? author
|
||||||
|
: undefined,
|
||||||
|
lastUpdatedAt: showLastUpdateTime
|
||||||
|
? frontMatterTimestamp ?? timestamp
|
||||||
|
: undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
export async function readDocFile(
|
export async function readDocFile(
|
||||||
versionMetadata: Pick<
|
versionMetadata: Pick<
|
||||||
VersionMetadata,
|
VersionMetadata,
|
||||||
|
|
@ -92,6 +142,7 @@ async function doProcessDocMetadata({
|
||||||
const {source, content, contentPath, filePath} = docFile;
|
const {source, content, contentPath, filePath} = docFile;
|
||||||
const {
|
const {
|
||||||
siteDir,
|
siteDir,
|
||||||
|
i18n,
|
||||||
siteConfig: {
|
siteConfig: {
|
||||||
markdown: {parseFrontMatter},
|
markdown: {parseFrontMatter},
|
||||||
},
|
},
|
||||||
|
|
@ -206,6 +257,21 @@ async function doProcessDocMetadata({
|
||||||
const draft = isDraft({env, frontMatter});
|
const draft = isDraft({env, frontMatter});
|
||||||
const unlisted = isUnlisted({env, frontMatter});
|
const unlisted = isUnlisted({env, frontMatter});
|
||||||
|
|
||||||
|
const formatDate = (locale: string, date: Date, calendar: string): string => {
|
||||||
|
try {
|
||||||
|
return new Intl.DateTimeFormat(locale, {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
year: 'numeric',
|
||||||
|
timeZone: 'UTC',
|
||||||
|
calendar,
|
||||||
|
}).format(date);
|
||||||
|
} catch (err) {
|
||||||
|
logger.error`Can't format docs lastUpdatedAt date "${String(date)}"`;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 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
|
||||||
|
|
@ -225,6 +291,13 @@ async function doProcessDocMetadata({
|
||||||
version: versionMetadata.versionName,
|
version: versionMetadata.versionName,
|
||||||
lastUpdatedBy: lastUpdate.lastUpdatedBy,
|
lastUpdatedBy: lastUpdate.lastUpdatedBy,
|
||||||
lastUpdatedAt: lastUpdate.lastUpdatedAt,
|
lastUpdatedAt: lastUpdate.lastUpdatedAt,
|
||||||
|
formattedLastUpdatedAt: lastUpdate.lastUpdatedAt
|
||||||
|
? formatDate(
|
||||||
|
i18n.currentLocale,
|
||||||
|
new Date(lastUpdate.lastUpdatedAt * 1000),
|
||||||
|
i18n.localeConfigs[i18n.currentLocale]!.calendar,
|
||||||
|
)
|
||||||
|
: undefined,
|
||||||
sidebarPosition,
|
sidebarPosition,
|
||||||
frontMatter,
|
frontMatter,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
* This source code is licensed under the MIT license found in the
|
* This source code is licensed under the MIT license found in the
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {
|
||||||
JoiFrontMatter as Joi, // Custom instance for front matter
|
JoiFrontMatter as Joi, // Custom instance for front matter
|
||||||
URISchema,
|
URISchema,
|
||||||
|
|
@ -11,15 +12,17 @@ import {
|
||||||
FrontMatterTOCHeadingLevels,
|
FrontMatterTOCHeadingLevels,
|
||||||
validateFrontMatter,
|
validateFrontMatter,
|
||||||
ContentVisibilitySchema,
|
ContentVisibilitySchema,
|
||||||
FrontMatterLastUpdateSchema,
|
|
||||||
} from '@docusaurus/utils-validation';
|
} from '@docusaurus/utils-validation';
|
||||||
import type {DocFrontMatter} from '@docusaurus/plugin-content-docs';
|
import type {DocFrontMatter} from '@docusaurus/plugin-content-docs';
|
||||||
|
|
||||||
|
const FrontMatterLastUpdateErrorMessage =
|
||||||
|
'{{#label}} does not look like a valid front matter FileChange object. Please use a FileChange object (with an author and/or date).';
|
||||||
|
|
||||||
// NOTE: we don't add any default value on purpose here
|
// NOTE: we don't add any default value on purpose here
|
||||||
// We don't want default values to magically appear in doc metadata and props
|
// We don't want default values to magically appear in doc metadata and props
|
||||||
// While the user did not provide those values explicitly
|
// While the user did not provide those values explicitly
|
||||||
// We use default values in code instead
|
// We use default values in code instead
|
||||||
export const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
|
const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
|
||||||
id: Joi.string(),
|
id: Joi.string(),
|
||||||
// See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
|
// See https://github.com/facebook/docusaurus/issues/4591#issuecomment-822372398
|
||||||
title: Joi.string().allow(''),
|
title: Joi.string().allow(''),
|
||||||
|
|
@ -42,7 +45,15 @@ export const DocFrontMatterSchema = Joi.object<DocFrontMatter>({
|
||||||
pagination_next: Joi.string().allow(null),
|
pagination_next: Joi.string().allow(null),
|
||||||
pagination_prev: Joi.string().allow(null),
|
pagination_prev: Joi.string().allow(null),
|
||||||
...FrontMatterTOCHeadingLevels,
|
...FrontMatterTOCHeadingLevels,
|
||||||
last_update: FrontMatterLastUpdateSchema,
|
last_update: Joi.object({
|
||||||
|
author: Joi.string(),
|
||||||
|
date: Joi.date().raw(),
|
||||||
|
})
|
||||||
|
.or('author', 'date')
|
||||||
|
.messages({
|
||||||
|
'object.missing': FrontMatterLastUpdateErrorMessage,
|
||||||
|
'object.base': FrontMatterLastUpdateErrorMessage,
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
.unknown()
|
.unknown()
|
||||||
.concat(ContentVisibilitySchema);
|
.concat(ContentVisibilitySchema);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||||
|
*
|
||||||
|
* This source code is licensed under the MIT license found in the
|
||||||
|
* LICENSE file in the root directory of this source tree.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import logger from '@docusaurus/logger';
|
||||||
|
import {
|
||||||
|
getFileCommitDate,
|
||||||
|
FileNotTrackedError,
|
||||||
|
GitNotFoundError,
|
||||||
|
} from '@docusaurus/utils';
|
||||||
|
|
||||||
|
let showedGitRequirementError = false;
|
||||||
|
let showedFileNotTrackedError = false;
|
||||||
|
|
||||||
|
export async function getFileLastUpdate(
|
||||||
|
filePath: string,
|
||||||
|
): Promise<{timestamp: number; author: string} | null> {
|
||||||
|
if (!filePath) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap in try/catch in case the shell commands fail
|
||||||
|
// (e.g. project doesn't use Git, etc).
|
||||||
|
try {
|
||||||
|
const result = getFileCommitDate(filePath, {
|
||||||
|
age: 'newest',
|
||||||
|
includeAuthor: true,
|
||||||
|
});
|
||||||
|
return {timestamp: result.timestamp, author: result.author};
|
||||||
|
} catch (err) {
|
||||||
|
if (err instanceof GitNotFoundError) {
|
||||||
|
if (!showedGitRequirementError) {
|
||||||
|
logger.warn('Sorry, the docs plugin last update options require Git.');
|
||||||
|
showedGitRequirementError = true;
|
||||||
|
}
|
||||||
|
} else if (err instanceof FileNotTrackedError) {
|
||||||
|
if (!showedFileNotTrackedError) {
|
||||||
|
logger.warn(
|
||||||
|
'Cannot infer the update date for some files, as they are not tracked by git.',
|
||||||
|
);
|
||||||
|
showedFileNotTrackedError = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logger.warn(err);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -16,8 +16,6 @@ declare module '@docusaurus/plugin-content-docs' {
|
||||||
TagsListItem,
|
TagsListItem,
|
||||||
TagModule,
|
TagModule,
|
||||||
Tag,
|
Tag,
|
||||||
FrontMatterLastUpdate,
|
|
||||||
LastUpdateData,
|
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import type {Plugin, LoadContext} from '@docusaurus/types';
|
import type {Plugin, LoadContext} from '@docusaurus/types';
|
||||||
import type {Overwrite, Required} from 'utility-types';
|
import type {Overwrite, Required} from 'utility-types';
|
||||||
|
|
@ -26,6 +24,14 @@ declare module '@docusaurus/plugin-content-docs' {
|
||||||
image?: string;
|
image?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type FileChange = {
|
||||||
|
author?: string;
|
||||||
|
/** Date can be any
|
||||||
|
* [parsable date string](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse).
|
||||||
|
*/
|
||||||
|
date?: Date | string;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Custom callback for parsing number prefixes from file/folder names.
|
* Custom callback for parsing number prefixes from file/folder names.
|
||||||
*/
|
*/
|
||||||
|
|
@ -87,9 +93,9 @@ declare module '@docusaurus/plugin-content-docs' {
|
||||||
*/
|
*/
|
||||||
editLocalizedFiles: boolean;
|
editLocalizedFiles: boolean;
|
||||||
/** Whether to display the last date the doc was updated. */
|
/** Whether to display the last date the doc was updated. */
|
||||||
showLastUpdateTime: boolean;
|
showLastUpdateTime?: boolean;
|
||||||
/** Whether to display the author who last updated the doc. */
|
/** Whether to display the author who last updated the doc. */
|
||||||
showLastUpdateAuthor: boolean;
|
showLastUpdateAuthor?: boolean;
|
||||||
/**
|
/**
|
||||||
* Custom parsing logic to extract number prefixes from file names. Use
|
* Custom parsing logic to extract number prefixes from file names. Use
|
||||||
* `false` to disable this behavior and leave the docs untouched, and `true`
|
* `false` to disable this behavior and leave the docs untouched, and `true`
|
||||||
|
|
@ -395,7 +401,16 @@ declare module '@docusaurus/plugin-content-docs' {
|
||||||
/** Should this doc be accessible but hidden in production builds? */
|
/** Should this doc be accessible but hidden in production builds? */
|
||||||
unlisted?: boolean;
|
unlisted?: boolean;
|
||||||
/** Allows overriding the last updated author and/or date. */
|
/** Allows overriding the last updated author and/or date. */
|
||||||
last_update?: FrontMatterLastUpdate;
|
last_update?: FileChange;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LastUpdateData = {
|
||||||
|
/** A timestamp in **seconds**, directly acquired from `git log`. */
|
||||||
|
lastUpdatedAt?: number;
|
||||||
|
/** `lastUpdatedAt` formatted as a date according to the current locale. */
|
||||||
|
formattedLastUpdatedAt?: string;
|
||||||
|
/** The author's name directly acquired from `git log`. */
|
||||||
|
lastUpdatedBy?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DocMetadataBase = LastUpdateData & {
|
export type DocMetadataBase = LastUpdateData & {
|
||||||
|
|
|
||||||
|
|
@ -7,38 +7,21 @@
|
||||||
|
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import {
|
import {docuHash, createSlugger, normalizeUrl} from '@docusaurus/utils';
|
||||||
docuHash,
|
|
||||||
createSlugger,
|
|
||||||
normalizeUrl,
|
|
||||||
aliasedSitePathToRelativePath,
|
|
||||||
} from '@docusaurus/utils';
|
|
||||||
import {
|
import {
|
||||||
toTagDocListProp,
|
toTagDocListProp,
|
||||||
toTagsListTagsProp,
|
toTagsListTagsProp,
|
||||||
toVersionMetadataProp,
|
toVersionMetadataProp,
|
||||||
} from './props';
|
} from './props';
|
||||||
import {getVersionTags} from './tags';
|
import {getVersionTags} from './tags';
|
||||||
import type {
|
import type {PluginContentLoadedActions, RouteConfig} from '@docusaurus/types';
|
||||||
PluginContentLoadedActions,
|
|
||||||
RouteConfig,
|
|
||||||
RouteMetadata,
|
|
||||||
} from '@docusaurus/types';
|
|
||||||
import type {FullVersion, VersionTag} from './types';
|
import type {FullVersion, VersionTag} from './types';
|
||||||
import type {
|
import type {
|
||||||
CategoryGeneratedIndexMetadata,
|
CategoryGeneratedIndexMetadata,
|
||||||
DocMetadata,
|
|
||||||
PluginOptions,
|
PluginOptions,
|
||||||
PropTagsListPage,
|
PropTagsListPage,
|
||||||
} from '@docusaurus/plugin-content-docs';
|
} from '@docusaurus/plugin-content-docs';
|
||||||
|
|
||||||
function createDocRouteMetadata(docMeta: DocMetadata): RouteMetadata {
|
|
||||||
return {
|
|
||||||
sourceFilePath: aliasedSitePathToRelativePath(docMeta.source),
|
|
||||||
lastUpdatedAt: docMeta.lastUpdatedAt,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
async function buildVersionCategoryGeneratedIndexRoutes({
|
async function buildVersionCategoryGeneratedIndexRoutes({
|
||||||
version,
|
version,
|
||||||
actions,
|
actions,
|
||||||
|
|
@ -85,27 +68,26 @@ async function buildVersionDocRoutes({
|
||||||
options,
|
options,
|
||||||
}: BuildVersionRoutesParam): Promise<RouteConfig[]> {
|
}: BuildVersionRoutesParam): Promise<RouteConfig[]> {
|
||||||
return Promise.all(
|
return Promise.all(
|
||||||
version.docs.map(async (doc) => {
|
version.docs.map(async (metadataItem) => {
|
||||||
await actions.createData(
|
await actions.createData(
|
||||||
// Note that this created data path must be in sync with
|
// Note that this created data path must be in sync with
|
||||||
// metadataPath provided to mdx-loader.
|
// metadataPath provided to mdx-loader.
|
||||||
`${docuHash(doc.source)}.json`,
|
`${docuHash(metadataItem.source)}.json`,
|
||||||
JSON.stringify(doc, null, 2),
|
JSON.stringify(metadataItem, null, 2),
|
||||||
);
|
);
|
||||||
|
|
||||||
const docRoute: RouteConfig = {
|
const docRoute: RouteConfig = {
|
||||||
path: doc.permalink,
|
path: metadataItem.permalink,
|
||||||
component: options.docItemComponent,
|
component: options.docItemComponent,
|
||||||
exact: true,
|
exact: true,
|
||||||
modules: {
|
modules: {
|
||||||
content: doc.source,
|
content: metadataItem.source,
|
||||||
},
|
},
|
||||||
metadata: createDocRouteMetadata(doc),
|
|
||||||
// Because the parent (DocRoot) comp need to access it easily
|
// Because the parent (DocRoot) comp need to access it easily
|
||||||
// This permits to render the sidebar once without unmount/remount when
|
// This permits to render the sidebar once without unmount/remount when
|
||||||
// navigating (and preserve sidebar state)
|
// navigating (and preserve sidebar state)
|
||||||
...(doc.sidebar && {
|
...(metadataItem.sidebar && {
|
||||||
sidebar: doc.sidebar,
|
sidebar: metadataItem.sidebar,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
import {addTrailingSlash} from '@docusaurus/utils-common';
|
import {addTrailingSlash} from '@docusaurus/utils';
|
||||||
import {createDocsByIdIndex, toCategoryIndexMatcherParam} from '../docs';
|
import {createDocsByIdIndex, toCategoryIndexMatcherParam} from '../docs';
|
||||||
import type {
|
import type {
|
||||||
SidebarItemDoc,
|
SidebarItemDoc,
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,12 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {isValidPathname, resolvePathname} from '@docusaurus/utils';
|
import {
|
||||||
import {addLeadingSlash, addTrailingSlash} from '@docusaurus/utils-common';
|
addLeadingSlash,
|
||||||
|
addTrailingSlash,
|
||||||
|
isValidPathname,
|
||||||
|
resolvePathname,
|
||||||
|
} from '@docusaurus/utils';
|
||||||
import {
|
import {
|
||||||
DefaultNumberPrefixParser,
|
DefaultNumberPrefixParser,
|
||||||
stripPathNumberPrefixes,
|
stripPathNumberPrefixes,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/plugin-content-pages",
|
"name": "@docusaurus/plugin-content-pages",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Pages plugin for Docusaurus.",
|
"description": "Pages plugin for Docusaurus.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "src/plugin-content-pages.d.ts",
|
"types": "src/plugin-content-pages.d.ts",
|
||||||
|
|
@ -18,11 +18,11 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.1.1",
|
||||||
"@docusaurus/mdx-loader": "3.2.0",
|
"@docusaurus/mdx-loader": "3.1.1",
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.1.1",
|
||||||
"@docusaurus/utils": "3.2.0",
|
"@docusaurus/utils": "3.1.1",
|
||||||
"@docusaurus/utils-validation": "3.2.0",
|
"@docusaurus/utils-validation": "3.1.1",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
"tslib": "^2.6.0",
|
"tslib": "^2.6.0",
|
||||||
"webpack": "^5.88.1"
|
"webpack": "^5.88.1"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import {loadContext} from '@docusaurus/core/src/server/site';
|
import {loadContext} from '@docusaurus/core/lib/server';
|
||||||
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
import {normalizePluginOptions} from '@docusaurus/utils-validation';
|
||||||
|
|
||||||
import pluginContentPages from '../index';
|
import pluginContentPages from '../index';
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import {
|
||||||
encodePath,
|
encodePath,
|
||||||
fileToPath,
|
fileToPath,
|
||||||
aliasedSitePath,
|
aliasedSitePath,
|
||||||
aliasedSitePathToRelativePath,
|
|
||||||
docuHash,
|
docuHash,
|
||||||
getPluginI18nPath,
|
getPluginI18nPath,
|
||||||
getFolderContainingFile,
|
getFolderContainingFile,
|
||||||
|
|
@ -25,7 +24,8 @@ import {
|
||||||
isDraft,
|
isDraft,
|
||||||
} from '@docusaurus/utils';
|
} from '@docusaurus/utils';
|
||||||
import {validatePageFrontMatter} from './frontMatter';
|
import {validatePageFrontMatter} from './frontMatter';
|
||||||
import type {LoadContext, Plugin, RouteMetadata} from '@docusaurus/types';
|
|
||||||
|
import type {LoadContext, Plugin} from '@docusaurus/types';
|
||||||
import type {PagesContentPaths} from './types';
|
import type {PagesContentPaths} from './types';
|
||||||
import type {
|
import type {
|
||||||
PluginOptions,
|
PluginOptions,
|
||||||
|
|
@ -159,20 +159,9 @@ export default function pluginContentPages(
|
||||||
|
|
||||||
const {addRoute, createData} = actions;
|
const {addRoute, createData} = actions;
|
||||||
|
|
||||||
function createPageRouteMetadata(metadata: Metadata): RouteMetadata {
|
|
||||||
return {
|
|
||||||
sourceFilePath: aliasedSitePathToRelativePath(metadata.source),
|
|
||||||
// TODO add support for last updated date in the page plugin
|
|
||||||
// at least for Markdown files
|
|
||||||
// lastUpdatedAt: metadata.lastUpdatedAt,
|
|
||||||
lastUpdatedAt: undefined,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
content.map(async (metadata) => {
|
content.map(async (metadata) => {
|
||||||
const {permalink, source} = metadata;
|
const {permalink, source} = metadata;
|
||||||
const routeMetadata = createPageRouteMetadata(metadata);
|
|
||||||
if (metadata.type === 'mdx') {
|
if (metadata.type === 'mdx') {
|
||||||
await createData(
|
await createData(
|
||||||
// Note that this created data path must be in sync with
|
// Note that this created data path must be in sync with
|
||||||
|
|
@ -184,7 +173,6 @@ export default function pluginContentPages(
|
||||||
path: permalink,
|
path: permalink,
|
||||||
component: options.mdxPageComponent,
|
component: options.mdxPageComponent,
|
||||||
exact: true,
|
exact: true,
|
||||||
metadata: routeMetadata,
|
|
||||||
modules: {
|
modules: {
|
||||||
content: source,
|
content: source,
|
||||||
},
|
},
|
||||||
|
|
@ -194,7 +182,6 @@ export default function pluginContentPages(
|
||||||
path: permalink,
|
path: permalink,
|
||||||
component: source,
|
component: source,
|
||||||
exact: true,
|
exact: true,
|
||||||
metadata: routeMetadata,
|
|
||||||
modules: {
|
modules: {
|
||||||
config: `@generated/docusaurus.config`,
|
config: `@generated/docusaurus.config`,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@docusaurus/plugin-debug",
|
"name": "@docusaurus/plugin-debug",
|
||||||
"version": "3.2.0",
|
"version": "3.1.1",
|
||||||
"description": "Debug plugin for Docusaurus.",
|
"description": "Debug plugin for Docusaurus.",
|
||||||
"main": "lib/index.js",
|
"main": "lib/index.js",
|
||||||
"types": "src/plugin-debug.d.ts",
|
"types": "src/plugin-debug.d.ts",
|
||||||
|
|
@ -20,9 +20,9 @@
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "3.2.0",
|
"@docusaurus/core": "3.1.1",
|
||||||
"@docusaurus/types": "3.2.0",
|
"@docusaurus/types": "3.1.1",
|
||||||
"@docusaurus/utils": "3.2.0",
|
"@docusaurus/utils": "3.1.1",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
"react-json-view-lite": "^1.2.0",
|
"react-json-view-lite": "^1.2.0",
|
||||||
"tslib": "^2.6.0"
|
"tslib": "^2.6.0"
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue