Просмотр исходного кода

Merge branch 'dev/5.0.x' into feat/84145-84230-add-clamp

yohei0125 4 лет назад
Родитель
Сommit
895536049e
79 измененных файлов с 556 добавлено и 472 удалено
  1. 3 3
      .github/workflows/ci-slackbot-proxy.yml
  2. 5 26
      .github/workflows/ci.yml
  3. 2 2
      .github/workflows/list-unhealthy-branches.yml
  4. 1 1
      .github/workflows/release-slackbot-proxy.yml
  5. 2 2
      .github/workflows/release.yml
  6. 28 1
      CHANGELOG.md
  7. 1 3
      README.md
  8. 1 3
      README_JP.md
  9. 1 1
      lerna.json
  10. 4 4
      package.json
  11. 1 1
      packages/app/bin/download-cdn-resources.ts
  12. 2 2
      packages/app/bin/github-actions/update-readme.sh
  13. 0 2
      packages/app/config/webpack.common.js
  14. 0 1
      packages/app/config/webpack.dev.dll.js
  15. 3 3
      packages/app/docker/Dockerfile
  16. 4 2
      packages/app/docker/README.md
  17. 10 11
      packages/app/package.json
  18. 2 0
      packages/app/resource/locales/en_US/admin/admin.json
  19. 2 0
      packages/app/resource/locales/ja_JP/admin/admin.json
  20. 2 0
      packages/app/resource/locales/zh_CN/admin/admin.json
  21. 1 1
      packages/app/src/client/services/ContextExtractor.tsx
  22. 0 1
      packages/app/src/client/services/PageContainer.js
  23. 1 1
      packages/app/src/client/util/interceptor/detach-code-blocks.js
  24. 1 1
      packages/app/src/client/util/interceptor/drawio-interceptor.js
  25. 1 1
      packages/app/src/components/PageEditor.jsx
  26. 1 1
      packages/app/src/components/PageEditor/MarkdownTableInterceptor.js
  27. 1 1
      packages/app/src/components/PageEditor/PreventMarkdownListInterceptor.js
  28. 1 1
      packages/app/src/components/SearchForm.jsx
  29. 6 1
      packages/app/src/components/SearchPage/SortControl.tsx
  30. 29 1
      packages/app/src/components/Sidebar/PageTree.tsx
  31. 2 5
      packages/app/src/components/Sidebar/PageTree/ItemsTree.tsx
  32. 1 0
      packages/app/src/interfaces/page-listing-results.ts
  33. 1 1
      packages/app/src/server/models/GlobalNotificationSetting/index.js
  34. 39 21
      packages/app/src/server/models/obsolete-page.js
  35. 22 15
      packages/app/src/server/models/page.ts
  36. 1 1
      packages/app/src/server/routes/apiv3/app-settings.js
  37. 3 2
      packages/app/src/server/routes/apiv3/pages.js
  38. 9 7
      packages/app/src/server/routes/page.js
  39. 1 1
      packages/app/src/server/service/config-loader.ts
  40. 1 1
      packages/app/src/server/service/page.js
  41. 1 1
      packages/app/src/server/service/slack-command-handler/create-page-service.js
  42. 1 1
      packages/app/src/server/service/slack-command-handler/search.js
  43. 1 1
      packages/app/src/server/util/middlewares.js
  44. 1 1
      packages/app/src/server/util/swigFunctions.js
  45. 5 0
      packages/app/src/server/views/layout/layout.html
  46. 0 1
      packages/app/src/server/views/widget/page_content.html
  47. 1 1
      packages/app/src/services/cdn-resources-service.js
  48. 2 2
      packages/app/src/stores/page-listing.tsx
  49. 0 129
      packages/app/src/test/integration/service/page.test.js
  50. 194 0
      packages/app/src/test/integration/service/v5-migration.test.js
  51. 1 1
      packages/codemirror-textlint/package.json
  52. 0 27
      packages/core/README.md
  53. 1 1
      packages/core/package.json
  54. 11 14
      packages/core/src/index.js
  55. 2 4
      packages/core/src/plugin/service/tag-cache-manager.js
  56. 1 3
      packages/core/src/service/localstorage-manager.js
  57. 1 3
      packages/core/src/utils/basic-interceptor.js
  58. 1 1
      packages/plugin-attachment-refs/package.json
  59. 1 1
      packages/plugin-attachment-refs/src/client/js/util/Interceptor/RefsPostRenderInterceptor.js
  60. 1 1
      packages/plugin-attachment-refs/src/client/js/util/Interceptor/RefsPreRenderInterceptor.js
  61. 1 1
      packages/plugin-attachment-refs/src/client/js/util/RefsContext.js
  62. 1 1
      packages/plugin-attachment-refs/src/client/js/util/TagCacheManagerFactory.js
  63. 1 1
      packages/plugin-attachment-refs/src/server/routes/refs.js
  64. 1 1
      packages/plugin-lsx/package.json
  65. 1 1
      packages/plugin-lsx/src/client/js/components/Lsx.jsx
  66. 1 1
      packages/plugin-lsx/src/client/js/components/LsxPageList/LsxPage.jsx
  67. 1 1
      packages/plugin-lsx/src/client/js/util/Interceptor/LsxLogoutInterceptor.js
  68. 1 1
      packages/plugin-lsx/src/client/js/util/Interceptor/LsxPostRenderInterceptor.js
  69. 1 1
      packages/plugin-lsx/src/client/js/util/Interceptor/LsxPreRenderInterceptor.js
  70. 1 1
      packages/plugin-lsx/src/client/js/util/LsxContext.js
  71. 1 18
      packages/plugin-lsx/src/client/js/util/TagCacheManagerFactory.js
  72. 1 1
      packages/plugin-lsx/src/server/routes/lsx.js
  73. 1 1
      packages/plugin-pukiwiki-like-linker/package.json
  74. 1 1
      packages/slack/package.json
  75. 3 3
      packages/slackbot-proxy/docker/Dockerfile
  76. 2 2
      packages/slackbot-proxy/package.json
  77. 0 27
      packages/ui/README.md
  78. 1 1
      packages/ui/package.json
  79. 114 83
      yarn.lock

+ 3 - 3
.github/workflows/ci-slackbot-proxy.yml

@@ -15,7 +15,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [14.x]
+        node-version: [16.x]
 
     steps:
     - uses: actions/checkout@v2
@@ -58,7 +58,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [14.x]
+        node-version: [16.x]
 
     services:
       mysql:
@@ -118,7 +118,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [14.x]
+        node-version: [16.x]
 
     services:
       mysql:

+ 5 - 26
.github/workflows/ci.yml

@@ -15,7 +15,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [14.x]
+        node-version: [16.x]
 
     steps:
     - uses: actions/checkout@v2
@@ -58,17 +58,13 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [14.x]
+        node-version: [16.x]
 
     services:
       mongodb:
         image: mongo:4.4
         ports:
         - 27017/tcp
-      mongodb36:
-        image: mongo:3.6
-        ports:
-        - 27017/tcp
 
     steps:
     - uses: actions/checkout@v2
@@ -94,12 +90,6 @@ jobs:
         yarn test
       env:
         MONGO_URI: mongodb://localhost:${{ job.services.mongodb.ports['27017'] }}/growi_test
-    - name: yarn test with MongoDB 3.6
-      working-directory: ./packages/app
-      run: |
-        yarn test
-      env:
-        MONGO_URI: mongodb://localhost:${{ job.services.mongodb36.ports['27017'] }}/growi_test
 
     - name: Upload coverage report as artifact
       uses: actions/upload-artifact@v2
@@ -123,7 +113,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [14.x]
+        node-version: [16.x]
 
     services:
       mongodb:
@@ -173,17 +163,13 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [12.x, 14.x]
+        node-version: [14.x, 16.x]
 
     services:
       mongodb:
         image: mongo:4.4
         ports:
         - 27017/tcp
-      mongodb36:
-        image: mongo:3.6
-        ports:
-        - 27017/tcp
 
     steps:
     - uses: actions/checkout@v2
@@ -209,7 +195,7 @@ jobs:
       run: |
         yarn lerna run build
       env:
-        ANALYZE_BUNDLE_SIZE: ${{ matrix.node-version == '14.x' }}
+        ANALYZE_BUNDLE_SIZE: ${{ matrix.node-version == '16.x' }}
     - name: lerna bootstrap --production
       run: |
         npx lerna bootstrap -- --production
@@ -229,13 +215,6 @@ jobs:
         yarn server:ci
       env:
         MONGO_URI: mongodb://localhost:${{ job.services.mongodb.ports['27017'] }}/growi-${{ steps.getdbname.outputs.suffix }}
-    - name: yarn server:ci with MongoDB 3.6
-      working-directory: ./packages/app
-      run: |
-        cp config/ci/.env.local.for-ci .env.production.local
-        yarn server:ci
-      env:
-        MONGO_URI: mongodb://localhost:${{ job.services.mongodb36.ports['27017'] }}/growi-${{ steps.getdbname.outputs.suffix }}
 
     - name: Upload report as artifact
       uses: actions/upload-artifact@v2

+ 2 - 2
.github/workflows/list-unhealthy-branches.yml

@@ -14,9 +14,9 @@ jobs:
       with:
         fetch-depth: 0
 
-    - uses: actions/setup-node@v2-beta
+    - uses: actions/setup-node@v2
       with:
-        node-version: '14'
+        node-version: '16'
 
     - name: List branches
       id: list-branches

+ 1 - 1
.github/workflows/release-slackbot-proxy.yml

@@ -108,7 +108,7 @@ jobs:
 
     - uses: actions/setup-node@v2
       with:
-        node-version: '14'
+        node-version: '16'
         cache: 'yarn'
         cache-dependency-path: '**/yarn.lock'
 

+ 2 - 2
.github/workflows/release.yml

@@ -24,7 +24,7 @@ jobs:
 
     - uses: actions/setup-node@v2
       with:
-        node-version: '14'
+        node-version: '16'
         cache: 'yarn'
         cache-dependency-path: '**/yarn.lock'
 
@@ -85,7 +85,7 @@ jobs:
 
     - uses: actions/setup-node@v2
       with:
-        node-version: '14'
+        node-version: '16'
         cache: 'yarn'
         cache-dependency-path: '**/yarn.lock'
 

+ 28 - 1
CHANGELOG.md

@@ -1,9 +1,36 @@
 # Changelog
 
-## [Unreleased](https://github.com/weseek/growi/compare/v4.5.2...HEAD)
+## [Unreleased](https://github.com/weseek/growi/compare/v4.5.3...HEAD)
 
 *Please do not manually update this file. We've automated the process.*
 
+## [v4.5.3](https://github.com/weseek/growi/compare/v4.5.2...v4.5.3) - 2021-12-17
+
+### 💎 Features
+
+- feat: user activation by email (#4862) @kaoritokashiki
+
+### 🚀 Improvement
+
+- imprv: Use SWR for isSlackEnabled (#4827) @stevenfukase
+- imprv: Disable rubber band scroll for Mac & iOS users (#4834) @hakumizuki
+- imprv: Omit atlaskit and implement sidebar only with original codes (#4598) @yuki-takei
+
+### 🐛 Bug Fixes
+
+- fix: GROWI Bot search command after transplanting search service from dev/5.0.x (#4916) @hakumizuki
+- fix: Set min-height to sidebar scroll target (#4884) @yuki-takei
+
+### 🧰 Maintenance
+
+- support: fix dependabot alert for kind-of (#4891) @LuqmanHakim-Grune
+- support: fix dependabot alert for ini (#4892) @LuqmanHakim-Grune
+- support: fix and debug mixin-deep dependabot alert (#4867) @LuqmanHakim-Grune
+- support: dependabot alert xmlhttprequest-ssl (#4878) @mudana-grune
+- support: Transplant search service from dev/5.0.x (#4869) @hakumizuki
+- support: dependabot alert set-value (#4864) @LuqmanHakim-Grune
+- ci(deps): bump aws-sdk from 2.179.0 to 2.1044.0 (#4821) @dependabot
+
 ## [v4.5.2](https://github.com/weseek/growi/compare/v4.5.1...v4.5.2) - 2021-12-06
 
 ### 🐛 Bug Fixes

+ 1 - 3
README.md

@@ -82,9 +82,7 @@ See [GROWI Docs: Environment Variables](https://docs.growi.org/en/admin-guide/ad
 
 ## Dependencies
 
-- Node.js v12.x or v14.x
-- npm 6.x
-- yarn
+- Node.js v14.x or v16.x
 - MongoDB 4.x
 
 ### Optional Dependencies

+ 1 - 3
README_JP.md

@@ -81,9 +81,7 @@ Crowi からの移行は **[こちら](https://docs.growi.org/en/admin-guide/mig
 
 ## 依存関係
 
-- Node.js v12.x or v14.x
-- npm 6.x
-- yarn
+- Node.js v14.x or v16.x
 - MongoDB 4.x
 
 ### オプションの依存関係

+ 1 - 1
lerna.json

@@ -1,7 +1,7 @@
 {
   "npmClient": "yarn",
   "useWorkspaces": true,
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "packages": [
     "packages/*"
   ]

+ 4 - 4
package.json

@@ -1,6 +1,6 @@
 {
   "name": "growi",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "description": "Team collaboration software using markdown",
   "tags": [
     "wiki",
@@ -75,8 +75,8 @@
     "typescript": "^4.2.3"
   },
   "engines": {
-    "node": "^12 || ^14",
-    "npm": ">=6.11.3 <7",
-    "yarn": ">=1.19.1 <2"
+    "node": "^14 || ^16",
+    "npm": ">=6.14 <7 || >=8.1 < 9",
+    "yarn": ">=1.22 <2"
   }
 }

+ 1 - 1
packages/app/bin/download-cdn-resources.ts

@@ -3,7 +3,7 @@
  *
  * @author Yuki Takei <yuki@weseek.co.jp>
  */
-import { envUtils } from 'growi-commons';
+import { envUtils } from '@growi/core';
 
 import CdnResourcesDownloader from './cdn/cdn-resources-downloader';
 import loggerFactory from '../src/utils/logger';

+ 2 - 2
packages/app/bin/github-actions/update-readme.sh

@@ -2,5 +2,5 @@
 
 cd docker
 
-sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`4\.5\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASED_VERSION}\2\3${RELEASED_VERSION}\4/" README.md
-sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`4\.5-nocdn\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASED_VERSION}-nocdn\2\3${RELEASED_VERSION}\4/" README.md
+sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`5\.0\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASED_VERSION}\2\3${RELEASED_VERSION}\4/" README.md
+sed -i -e "s/^\([*] \[\`\)[^\`]\+\(\`, \`5\.0-nocdn\`, .\+\]\)\(.\+\/blob\/v\).\+\(\/docker\/Dockerfile.\+\)$/\1${RELEASED_VERSION}-nocdn\2\3${RELEASED_VERSION}\4/" README.md

+ 0 - 2
packages/app/config/webpack.common.js

@@ -83,8 +83,6 @@ module.exports = (options) => {
           exclude: {
             test: /node_modules/,
             exclude: [ // include as a result
-              { test: /node_modules\/growi-plugin-/ },
-              /node_modules\/growi-commons/,
               /node_modules\/codemirror/,
             ],
           },

+ 0 - 1
packages/app/config/webpack.dev.dll.js

@@ -17,7 +17,6 @@ module.exports = {
       'diff2html',
       'debug',
       'entities',
-      'growi-commons',
       'i18next', 'i18next-browser-languagedetector',
       'jquery-slimscroll',
       'lodash', 'pako',

+ 3 - 3
packages/app/docker/Dockerfile

@@ -7,7 +7,7 @@ ARG flavor=default
 ##
 ## deps-resolver
 ##
-FROM node:14-slim AS deps-resolver
+FROM node:16-slim AS deps-resolver
 LABEL maintainer Yuki Takei <yuki@weseek.co.jp>
 
 ENV appDir /opt/growi
@@ -51,7 +51,7 @@ RUN tar cf node_modules.tar \
 ##
 ## prebuilder-default
 ##
-FROM node:14-slim AS prebuilder-default
+FROM node:16-slim AS prebuilder-default
 
 ENV appDir /opt/growi
 
@@ -124,7 +124,7 @@ RUN tar cf packages.tar \
 ##
 ## release
 ##
-FROM node:14-slim
+FROM node:16-slim
 LABEL maintainer Yuki Takei <yuki@weseek.co.jp>
 
 ENV NODE_ENV production

+ 4 - 2
packages/app/docker/README.md

@@ -10,8 +10,10 @@ GROWI Official docker image
 Supported tags and respective Dockerfile links
 ------------------------------------------------
 
-* [`4.5.2`, `4.5`, `4`, `latest` (Dockerfile)](https://github.com/weseek/growi/blob/v4.5.2/docker/Dockerfile)
-* [`4.5.2-nocdn`, `4.5-nocdn`, `4-nocdn`, `latest-nocdn` (Dockerfile)](https://github.com/weseek/growi/blob/v4.5.2/docker/Dockerfile)
+* [`5.0.0`, `5.0`, `5`, `latest` (Dockerfile)](https://github.com/weseek/growi/blob/v5.0.0/docker/Dockerfile)
+* [`5.0.0-nocdn`, `5.0-nocdn`, `5-nocdn`, `latest-nocdn` (Dockerfile)](https://github.com/weseek/growi/blob/v5.0.0/docker/Dockerfile)
+* [`4.5.3`, `4.5`, `4` (Dockerfile)](https://github.com/weseek/growi/blob/v4.5.3/docker/Dockerfile)
+* [`4.5.3-nocdn`, `4.5-nocdn`, `4-nocdn` (Dockerfile)](https://github.com/weseek/growi/blob/v4.5.3/docker/Dockerfile)
 * [`4.4.13`, `4.4` (Dockerfile)](https://github.com/weseek/growi/blob/v4.4.13/docker/Dockerfile)
 * [`4.4.13-nocdn`, `4.4-nocdn` (Dockerfile)](https://github.com/weseek/growi/blob/v4.4.13/docker/Dockerfile)
 

+ 10 - 11
packages/app/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/app",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "license": "MIT",
   "scripts": {
     "//// for production": "",
@@ -58,13 +58,13 @@
     "@browser-bunyan/console-formatted-stream": "^1.6.2",
     "@godaddy/terminus": "^4.9.0",
     "@google-cloud/storage": "^5.8.5",
-    "@growi/codemirror-textlint": "^4.5.3-RC.0",
-    "@growi/plugin-attachment-refs": "^4.5.3-RC.0",
-    "@growi/plugin-lsx": "^4.5.3-RC.0",
-    "@growi/plugin-pukiwiki-like-linker": "^4.5.3-RC.0",
-    "@growi/slack": "^4.5.3-RC.0",
-    "@promster/express": "^5.1.0",
-    "@promster/server": "^6.0.3",
+    "@growi/codemirror-textlint": "^5.0.0-RC.0",
+    "@growi/plugin-attachment-refs": "^5.0.0-RC.0",
+    "@growi/plugin-lsx": "^5.0.0-RC.0",
+    "@growi/plugin-pukiwiki-like-linker": "^5.0.0-RC.0",
+    "@growi/slack": "^5.0.0-RC.0",
+    "@promster/express": "^7.0.2",
+    "@promster/server": "^7.0.4",
     "@slack/events-api": "^3.0.0",
     "@slack/web-api": "^6.2.4",
     "@slack/webhook": "^6.0.0",
@@ -99,7 +99,6 @@
     "express-validator": "^6.1.1",
     "express-webpack-assets": "^0.1.0",
     "graceful-fs": "^4.1.11",
-    "growi-commons": "^5.0.4",
     "helmet": "^4.6.0",
     "http-errors": "~1.8.0",
     "i18next": "^20.3.2",
@@ -148,7 +147,7 @@
     "unzipper": "^0.10.5",
     "url-join": "^4.0.0",
     "validator": "^13.6.0",
-    "ws": "^7.4.6",
+    "ws": "^8.3.0",
     "xss": "^1.0.6"
   },
   "// comments for defDependencies": {
@@ -158,7 +157,7 @@
   },
   "devDependencies": {
     "@alienfast/i18next-loader": "^1.0.16",
-    "@growi/ui": "^4.5.3-RC.0",
+    "@growi/ui": "^5.0.0-RC.0",
     "@handsontable/react": "=2.1.0",
     "@types/compression": "^1.7.0",
     "@types/express": "^4.17.11",

+ 2 - 0
packages/app/resource/locales/en_US/admin/admin.json

@@ -20,6 +20,8 @@
     "submit_bug_report": "<a href='https://github.com/weseek/growi/issues/new?assignees=&labels=bug&template=bug-report.md&title=Bug%3A' target='_blank' rel='noreferrer'>then submit your issue to GitHub.</a>"
   },
   "v5_page_migration": {
+    "page_tree_not_avaliable" : "Page tree feature is not available yet.",
+    "go_to_settings": "Go to settings to enable the feature",
     "migration_desc": "Some of the public pages have the old schema. To take advantage of new features such as page trees and easy renaming, please upgrade the schema of all your pages.",
     "migration_note": "Note: You will lose unique constraints from the page paths.",
     "upgrade_to_v5": "Upgrade to V5",

+ 2 - 0
packages/app/resource/locales/ja_JP/admin/admin.json

@@ -20,6 +20,8 @@
     "submit_bug_report": "<a href='https://github.com/weseek/growi/issues/new?assignees=&labels=bug&template=bug-report.md&title=Bug%3A' target='_blank' rel='noreferrer'>次に GitHub で Issue を投稿してください。</a>"
   },
   "v5_page_migration": {
+    "page_tree_not_avaliable" : "Page Tree 機能は現在使用できません。",
+    "go_to_settings": "設定する",
     "migration_desc": "公開されているページに古いスキーマのものが存在します。ページツリーや簡単なリネームなどの新機能を利用するには、全てのページのスキーマをアップグレードしてください。",
     "migration_note": "注意: ページパスからユニーク制約が失われます。",
     "upgrade_to_v5": "V5 にアップグレード",

+ 2 - 0
packages/app/resource/locales/zh_CN/admin/admin.json

@@ -20,6 +20,8 @@
     "submit_bug_report": "<a href='https://github.com/weseek/growi/issues/new?assignees=&labels=bug&template=bug-report.md&title=Bug%3A' target='_blank' rel='noreferrer'>然后提交你的问题到GitHub。</a>"
   },
   "v5_page_migration": {
+    "page_tree_not_avaliable": "Page Tree 功能不可用",
+    "go_to_settings": "进入设置,启用该功能",
     "migration_desc": "Some of the public pages have the old schema. To take advantage of new features such as page trees and easy renaming, please upgrade the schema of all your pages. ",
     "migration_note": "Note: You will lose unique constraints from the page paths.",
     "upgrade_to_v5": "Upgrade to V5",

+ 1 - 1
packages/app/src/client/services/ContextExtractor.tsx

@@ -60,7 +60,7 @@ const ContextExtractorOnce: FC = () => {
   const hasDraftOnHackmd = !!mainContent?.getAttribute('data-page-has-draft-on-hackmd');
   const creator = JSON.parse(mainContent?.getAttribute('data-page-creator') || jsonNull);
   const revisionAuthor = JSON.parse(mainContent?.getAttribute('data-page-revision-author') || jsonNull);
-  const targetAndAncestors = JSON.parse(mainContent?.getAttribute('data-target-and-ancestors') || jsonNull);
+  const targetAndAncestors = JSON.parse(document.getElementById('growi-pagetree-target-and-ancestors')?.textContent || jsonNull);
   const slackChannels = mainContent?.getAttribute('data-slack-channels') || '';
 
   /*

+ 0 - 1
packages/app/src/client/services/PageContainer.js

@@ -82,7 +82,6 @@ export default class PageContainer extends Container {
       templateTagData: mainContent.getAttribute('data-template-tags') || null,
       shareLinksNumber: mainContent.getAttribute('data-share-links-number'),
       shareLinkId: JSON.parse(mainContent.getAttribute('data-share-link-id') || null),
-      targetAndAncestors: JSON.parse(mainContent.getAttribute('data-target-and-ancestors') || null),
 
       // latest(on remote) information
       remoteRevisionId: revisionId,

+ 1 - 1
packages/app/src/client/util/interceptor/detach-code-blocks.js

@@ -1,4 +1,4 @@
-import { BasicInterceptor } from 'growi-commons';
+import { BasicInterceptor } from '@growi/core';
 
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
packages/app/src/client/util/interceptor/drawio-interceptor.js

@@ -2,7 +2,7 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
 import { Provider } from 'unstated';
-import { BasicInterceptor } from 'growi-commons';
+import { BasicInterceptor } from '@growi/core';
 
 import Drawio from '~/components/Drawio';
 

+ 1 - 1
packages/app/src/components/PageEditor.jsx

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
 import detectIndent from 'detect-indent';
 
 import { throttle, debounce } from 'throttle-debounce';
-import { envUtils } from 'growi-commons';
+import { envUtils } from '@growi/core';
 import loggerFactory from '~/utils/logger';
 
 import AppContainer from '~/client/services/AppContainer';

+ 1 - 1
packages/app/src/components/PageEditor/MarkdownTableInterceptor.js

@@ -1,4 +1,4 @@
-import { BasicInterceptor } from 'growi-commons';
+import { BasicInterceptor } from '@growi/core';
 
 import mtu from './MarkdownTableUtil';
 import MarkdownTable from '~/client/models/MarkdownTable';

+ 1 - 1
packages/app/src/components/PageEditor/PreventMarkdownListInterceptor.js

@@ -1,4 +1,4 @@
-import { BasicInterceptor } from 'growi-commons';
+import { BasicInterceptor } from '@growi/core';
 
 import mlu from './MarkdownListUtil';
 

+ 1 - 1
packages/app/src/components/SearchForm.jsx

@@ -40,7 +40,7 @@ class SearchForm extends React.Component {
 
     // navigate to page
     if (page != null) {
-      window.location = page.path;
+      window.location = page.pageData._id;
     }
   }
 

+ 6 - 1
packages/app/src/components/SearchPage/SortControl.tsx

@@ -26,7 +26,12 @@ const SortControl: FC <Props> = (props: Props) => {
   };
 
   const renderSortItem = (sort, order) => {
-    return <div className="d-flex align-items-center"><span className="mr-3">{t(`search_result.sort_axis.${sort}`)}</span>{renderOrderIcon(order)}</div>;
+    return (
+      <div className="d-flex align-items-center justify-content-between w-100">
+        <span className="mr-3">{t(`search_result.sort_axis.${sort}`)}</span>
+        {renderOrderIcon(order)}
+      </div>
+    );
   };
 
   return (

+ 29 - 1
packages/app/src/components/Sidebar/PageTree.tsx

@@ -19,12 +19,40 @@ const PageTree: FC = memo(() => {
   const { data: targetId } = useCurrentPageId();
   const { data: targetAndAncestorsData } = useTargetAndAncestors();
 
-  const { data: migrationStatus } = useSWRxV5MigrationStatus(!isGuestUser);
+  const { data: migrationStatus } = useSWRxV5MigrationStatus();
 
   // for delete modal
   const [isDeleteModalOpen, setDeleteModalOpen] = useState(false);
   const [pagesToDelete, setPagesToDelete] = useState<IPageForPageDeleteModal[]>([]);
 
+  if (migrationStatus == null) {
+    return (
+      <>
+        <div className="grw-sidebar-content-header p-3">
+          <h3 className="mb-0">{t('Page Tree')}</h3>
+        </div>
+        <div className="mt-5 mx-2 text-center">
+          <h3 className="text-gray">Page Tree now loading...</h3>
+        </div>
+      </>
+    );
+  }
+
+  if (!migrationStatus?.isV5Compatible) {
+    // TODO : improve design
+    // Story : https://redmine.weseek.co.jp/issues/83755
+    return (
+      <>
+        <div className="grw-sidebar-content-header p-3">
+          <h3 className="mb-0">{t('Page Tree')}</h3>
+        </div>
+        <div className="mt-5 mx-2 text-center">
+          <h3 className="text-gray">{t('admin:v5_page_migration.page_tree_not_avaliable')}</h3>
+          <a href="/admin">{t('admin:v5_page_migration.go_to_settings')}</a>
+        </div>
+      </>
+    );
+  }
   /*
    * dependencies
    */

+ 2 - 5
packages/app/src/components/Sidebar/PageTree/ItemsTree.tsx

@@ -1,4 +1,4 @@
-import React, { FC, useState } from 'react';
+import React, { FC } from 'react';
 
 import { IPageHasId } from '../../../interfaces/page';
 import { ItemNode } from './ItemNode';
@@ -93,8 +93,6 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
   const { data: ancestorsChildrenData, error: error1 } = useSWRxPageAncestorsChildren(targetPath);
   const { data: rootPageData, error: error2 } = useSWRxRootPage();
 
-  const [isRenderedCompletely, setRenderedCompletely] = useState(false);
-
   const DeleteModal = (
     <PageDeleteModal
       isOpen={isDeleteModalOpen}
@@ -114,9 +112,8 @@ const ItemsTree: FC<ItemsTreeProps> = (props: ItemsTreeProps) => {
   /*
    * Render completely
    */
-  if (!isRenderedCompletely && ancestorsChildrenData != null && rootPageData != null) {
+  if (ancestorsChildrenData != null && rootPageData != null) {
     const initialNode = generateInitialNodeAfterResponse(ancestorsChildrenData.ancestorsChildren, new ItemNode(rootPageData.rootPage));
-    setRenderedCompletely(true); // render once
     return renderByInitialNode(initialNode, DeleteModal, isEnableActions, targetId, onClickDeleteByPage);
   }
 

+ 1 - 0
packages/app/src/interfaces/page-listing-results.ts

@@ -24,5 +24,6 @@ export interface TargetAndAncestors {
 
 
 export interface V5MigrationStatus {
+  isV5Compatible : boolean,
   migratablePagesCount: number
 }

+ 1 - 1
packages/app/src/server/models/GlobalNotificationSetting/index.js

@@ -1,6 +1,6 @@
 const mongoose = require('mongoose');
 const nodePath = require('path');
-const { pathUtils } = require('growi-commons');
+const { pathUtils } = require('@growi/core');
 
 /**
  * parent schema for GlobalNotificationSetting model

+ 39 - 21
packages/app/src/server/models/obsolete-page.js

@@ -12,7 +12,7 @@ const urljoin = require('url-join');
 const mongoose = require('mongoose');
 const differenceInYears = require('date-fns/differenceInYears');
 
-const { pathUtils } = require('growi-commons');
+const { pathUtils } = require('@growi/core');
 const escapeStringRegexp = require('escape-string-regexp');
 
 const { isTopPage, isTrashPage } = pagePathUtils;
@@ -79,8 +79,17 @@ const populateDataToShowRevision = (page, userPublicFields) => {
 
 export class PageQueryBuilder {
 
-  constructor(query) {
+  constructor(query, includeEmpty = false) {
     this.query = query;
+    if (!includeEmpty) {
+      this.query = this.query
+        .and({
+          $or: [
+            { isEmpty: false },
+            { isEmpty: null }, // for v4 compatibility
+          ],
+        });
+    }
   }
 
   addConditionToExcludeTrashed() {
@@ -249,12 +258,18 @@ export class PageQueryBuilder {
   /*
    * Add this condition when get any ancestor pages including the target's parent
    */
-  addConditionToSortAncestorPages() {
+  addConditionToSortPagesByDescPath() {
     this.query = this.query.sort('-path');
 
     return this;
   }
 
+  addConditionToSortPagesByAscPath() {
+    this.query = this.query.sort('path');
+
+    return this;
+  }
+
   addConditionToMinimizeDataForRendering() {
     this.query = this.query.select('_id path isEmpty grant revision');
 
@@ -586,7 +601,7 @@ export const getPageSchema = (crowi) => {
    * @param {User} user User instance
    * @param {UserGroup[]} userGroups List of UserGroup instances
    */
-  pageSchema.statics.findByIdAndViewer = async function(id, user, userGroups) {
+  pageSchema.statics.findByIdAndViewer = async function(id, user, userGroups, includeEmpty = false) {
     const baseQuery = this.findOne({ _id: id });
 
     let relatedUserGroups = userGroups;
@@ -596,18 +611,21 @@ export const getPageSchema = (crowi) => {
       relatedUserGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     }
 
-    const queryBuilder = new PageQueryBuilder(baseQuery);
+    const queryBuilder = new PageQueryBuilder(baseQuery, includeEmpty);
     queryBuilder.addConditionToFilteringByViewer(user, relatedUserGroups, true);
 
-    return await queryBuilder.query.exec();
+    return queryBuilder.query.exec();
   };
 
   // find page by path
-  pageSchema.statics.findByPath = function(path) {
+  pageSchema.statics.findByPath = function(path, includeEmpty = false) {
     if (path == null) {
       return null;
     }
-    return this.findOne({ path });
+
+    const builder = new PageQueryBuilder(this.findOne({ path }), includeEmpty);
+
+    return builder.query.exec();
   };
 
   /**
@@ -615,7 +633,7 @@ export const getPageSchema = (crowi) => {
    * @param {User} user User instance
    * @param {UserGroup[]} userGroups List of UserGroup instances
    */
-  pageSchema.statics.findAncestorByPathAndViewer = async function(path, user, userGroups) {
+  pageSchema.statics.findAncestorByPathAndViewer = async function(path, user, userGroups, includeEmpty = false) {
     if (path == null) {
       throw new Error('path is required.');
     }
@@ -636,10 +654,10 @@ export const getPageSchema = (crowi) => {
       relatedUserGroups = await UserGroupRelation.findAllUserGroupIdsRelatedToUser(user);
     }
 
-    const queryBuilder = new PageQueryBuilder(baseQuery);
+    const queryBuilder = new PageQueryBuilder(baseQuery, includeEmpty);
     queryBuilder.addConditionToFilteringByViewer(user, relatedUserGroups);
 
-    return await queryBuilder.query.exec();
+    return queryBuilder.query.exec();
   };
 
   pageSchema.statics.findByRedirectTo = function(path) {
@@ -649,22 +667,22 @@ export const getPageSchema = (crowi) => {
   /**
    * find pages that is match with `path` and its descendants
    */
-  pageSchema.statics.findListWithDescendants = async function(path, user, option = {}) {
-    const builder = new PageQueryBuilder(this.find());
+  pageSchema.statics.findListWithDescendants = async function(path, user, option = {}, includeEmpty = false) {
+    const builder = new PageQueryBuilder(this.find(), includeEmpty);
     builder.addConditionToListWithDescendants(path, option);
 
-    return await findListFromBuilderAndViewer(builder, user, false, option);
+    return findListFromBuilderAndViewer(builder, user, false, option);
   };
 
   /**
    * find pages that is match with `path` and its descendants whitch user is able to manage
    */
-  pageSchema.statics.findManageableListWithDescendants = async function(page, user, option = {}) {
+  pageSchema.statics.findManageableListWithDescendants = async function(page, user, option = {}, includeEmpty = false) {
     if (user == null) {
       return null;
     }
 
-    const builder = new PageQueryBuilder(this.find());
+    const builder = new PageQueryBuilder(this.find(), includeEmpty);
     builder.addConditionToListWithDescendants(page.path, option);
     builder.addConditionToExcludeRedirect();
 
@@ -685,11 +703,11 @@ export const getPageSchema = (crowi) => {
   /**
    * find pages that start with `path`
    */
-  pageSchema.statics.findListByStartWith = async function(path, user, option) {
-    const builder = new PageQueryBuilder(this.find());
+  pageSchema.statics.findListByStartWith = async function(path, user, option, includeEmpty = false) {
+    const builder = new PageQueryBuilder(this.find(), includeEmpty);
     builder.addConditionToListByStartWith(path, option);
 
-    return await findListFromBuilderAndViewer(builder, user, false, option);
+    return findListFromBuilderAndViewer(builder, user, false, option);
   };
 
   /**
@@ -1096,8 +1114,8 @@ export const getPageSchema = (crowi) => {
     await this.removeRedirectOriginPageByPath(redirectPage.path);
   };
 
-  pageSchema.statics.findListByPathsArray = async function(paths) {
-    const queryBuilder = new PageQueryBuilder(this.find());
+  pageSchema.statics.findListByPathsArray = async function(paths, includeEmpty = false) {
+    const queryBuilder = new PageQueryBuilder(this.find(), includeEmpty);
     queryBuilder.addConditionToListByPathsArray(paths);
 
     return await queryBuilder.query.exec();

+ 22 - 15
packages/app/src/server/models/page.ts

@@ -41,7 +41,7 @@ export interface PageModel extends Model<PageDocument> {
   [x: string]: any; // for obsolete methods
   createEmptyPagesByPaths(paths: string[], publicOnly?: boolean): Promise<void>
   getParentIdAndFillAncestors(path: string): Promise<string | null>
-  findByPathAndViewer(path: string | null, user, userGroups?, useFindOne?: boolean): Promise<PageDocument[]>
+  findByPathAndViewer(path: string | null, user, userGroups?, useFindOne?: boolean, includeEmpty?: boolean): Promise<PageDocument[]>
   findTargetAndAncestorsByPathOrId(pathOrId: string): Promise<TargetAndAncestorsResult>
   findChildrenByParentPathOrIdAndViewer(parentPathOrId: string, user, userGroups?): Promise<PageDocument[]>
   findAncestorsChildrenByPathAndViewer(path: string, user, userGroups?): Promise<Record<string, PageDocument[]>>
@@ -143,7 +143,7 @@ const generateChildrenRegExp = (path: string): RegExp => {
  */
 schema.statics.createEmptyPagesByPaths = async function(paths: string[], publicOnly = false): Promise<void> {
   // find existing parents
-  const builder = new PageQueryBuilder(this.find(publicOnly ? { grant: GRANT_PUBLIC } : {}, { _id: 0, path: 1 }));
+  const builder = new PageQueryBuilder(this.find(publicOnly ? { grant: GRANT_PUBLIC } : {}, { _id: 0, path: 1 }), true);
   const existingPages = await builder
     .addConditionToListByPathsArray(paths)
     .query
@@ -165,7 +165,7 @@ schema.statics.createEmptyPagesByPaths = async function(paths: string[], publicO
 };
 
 /*
- * Find the pages parent and update if the parent exists.
+ * Find the parent and update if the parent exists.
  * If not,
  *   - first   run createEmptyPagesByPaths with ancestor's paths to ensure all the ancestors exist
  *   - second  update ancestor pages' parent
@@ -175,25 +175,27 @@ schema.statics.getParentIdAndFillAncestors = async function(path: string): Promi
   const parentPath = nodePath.dirname(path);
 
   const parent = await this.findOne({ path: parentPath }); // find the oldest parent which must always be the true parent
-  if (parent != null) { // fill parents if parent is null
+  if (parent != null) {
     return parent._id;
   }
 
+  /*
+   * Fill parents if parent is null
+   */
   const ancestorPaths = collectAncestorPaths(path); // paths of parents need to be created
 
   // just create ancestors with empty pages
   await this.createEmptyPagesByPaths(ancestorPaths);
 
   // find ancestors
-  const builder = new PageQueryBuilder(this.find({}, { _id: 1, path: 1 }));
+  const builder = new PageQueryBuilder(this.find({}, { _id: 1, path: 1 }), true);
   const ancestors = await builder
     .addConditionToListByPathsArray(ancestorPaths)
-    .addConditionToSortAncestorPages()
+    .addConditionToSortPagesByDescPath()
     .query
     .lean()
     .exec();
 
-
   const ancestorsMap = new Map(); // Map<path, _id>
   ancestors.forEach(page => ancestorsMap.set(page.path, page._id));
 
@@ -234,14 +236,14 @@ const addViewerCondition = async(queryBuilder: PageQueryBuilder, user, userGroup
  * Find a page by path and viewer. Pass false to useFindOne to use findOne method.
  */
 schema.statics.findByPathAndViewer = async function(
-    path: string | null, user, userGroups = null, useFindOne = true,
+    path: string | null, user, userGroups = null, useFindOne = true, includeEmpty = false,
 ): Promise<PageDocument | PageDocument[] | null> {
   if (path == null) {
     throw new Error('path is required.');
   }
 
   const baseQuery = useFindOne ? this.findOne({ path }) : this.find({ path });
-  const queryBuilder = new PageQueryBuilder(baseQuery);
+  const queryBuilder = new PageQueryBuilder(baseQuery, includeEmpty);
   await addViewerCondition(queryBuilder, user, userGroups);
 
   return queryBuilder.query.exec();
@@ -269,14 +271,14 @@ schema.statics.findTargetAndAncestorsByPathOrId = async function(pathOrId: strin
   ancestorPaths.push(path); // include target
 
   // Do not populate
-  const queryBuilder = new PageQueryBuilder(this.find());
+  const queryBuilder = new PageQueryBuilder(this.find(), true);
   await addViewerCondition(queryBuilder, user, userGroups);
 
   const _targetAndAncestors: PageDocument[] = await queryBuilder
     .addConditionAsMigrated()
     .addConditionToListByPathsArray(ancestorPaths)
     .addConditionToMinimizeDataForRendering()
-    .addConditionToSortAncestorPages()
+    .addConditionToSortPagesByDescPath()
     .query
     .lean()
     .exec();
@@ -298,15 +300,19 @@ schema.statics.findChildrenByParentPathOrIdAndViewer = async function(parentPath
   if (hasSlash(parentPathOrId)) {
     const path = parentPathOrId;
     const regexp = generateChildrenRE2(path);
-    queryBuilder = new PageQueryBuilder(this.find({ path: { $regex: regexp.source } }));
+    queryBuilder = new PageQueryBuilder(this.find({ path: { $regex: regexp.source } }), true);
   }
   else {
     const parentId = parentPathOrId;
-    queryBuilder = new PageQueryBuilder(this.find({ parent: parentId }));
+    queryBuilder = new PageQueryBuilder(this.find({ parent: parentId }), true);
   }
   await addViewerCondition(queryBuilder, user, userGroups);
 
-  return queryBuilder.query.lean().exec();
+  return queryBuilder
+    .addConditionToSortPagesByAscPath()
+    .query
+    .lean()
+    .exec();
 };
 
 schema.statics.findAncestorsChildrenByPathAndViewer = async function(path: string, user, userGroups = null): Promise<Record<string, PageDocument[]>> {
@@ -314,11 +320,12 @@ schema.statics.findAncestorsChildrenByPathAndViewer = async function(path: strin
   const regexps = ancestorPaths.map(path => new RegExp(generateChildrenRegExp(path))); // cannot use re2
 
   // get pages at once
-  const queryBuilder = new PageQueryBuilder(this.find({ path: { $in: regexps } }));
+  const queryBuilder = new PageQueryBuilder(this.find({ path: { $in: regexps } }), true);
   await addViewerCondition(queryBuilder, user, userGroups);
   const _pages = await queryBuilder
     .addConditionAsMigrated()
     .addConditionToMinimizeDataForRendering()
+    .addConditionToSortPagesByAscPath()
     .query
     .lean()
     .exec();

+ 1 - 1
packages/app/src/server/routes/apiv3/app-settings.js

@@ -7,7 +7,7 @@ const debug = require('debug')('growi:routes:admin');
 
 const express = require('express');
 
-const { pathUtils } = require('growi-commons');
+const { pathUtils } = require('@growi/core');
 const { listLocaleIds } = require('~/utils/locale-utils');
 
 const router = express.Router();

+ 3 - 2
packages/app/src/server/routes/apiv3/pages.js

@@ -3,7 +3,7 @@ import loggerFactory from '~/utils/logger';
 
 const logger = loggerFactory('growi:routes:apiv3:pages'); // eslint-disable-line no-unused-vars
 const express = require('express');
-const pathUtils = require('growi-commons').pathUtils;
+const { pathUtils } = require('@growi/core');
 const mongoose = require('mongoose');
 
 const { body } = require('express-validator');
@@ -715,8 +715,9 @@ module.exports = (crowi) => {
 
   router.get('/v5-migration-status', accessTokenParser, loginRequired, async(req, res) => {
     try {
+      const isV5Compatible = crowi.configManager.getConfig('crowi', 'app:isV5Compatible');
       const migratablePagesCount = await crowi.pageService.v5MigratablePrivatePagesCount(req.user);
-      return res.apiv3({ migratablePagesCount });
+      return res.apiv3({ isV5Compatible, migratablePagesCount });
     }
     catch (err) {
       return res.apiv3Err(new ErrorV3('Failed to obtain migration status'));

+ 9 - 7
packages/app/src/server/routes/page.js

@@ -138,7 +138,7 @@ module.exports = function(crowi, app) {
   const logger = loggerFactory('growi:routes:page');
   const swig = require('swig-templates');
 
-  const pathUtils = require('growi-commons').pathUtils;
+  const { pathUtils } = require('@growi/core');
 
   const Page = crowi.model('Page');
   const User = crowi.model('User');
@@ -264,10 +264,10 @@ module.exports = function(crowi, app) {
     renderVars.pages = result.pages;
   }
 
-  async function addRenderVarsForPageTree(renderVars, path, user) {
-    const { targetAndAncestors, rootPage } = await Page.findTargetAndAncestorsByPathOrId(path, user);
+  async function addRenderVarsForPageTree(renderVars, pathOrId, user) {
+    const { targetAndAncestors, rootPage } = await Page.findTargetAndAncestorsByPathOrId(pathOrId, user);
 
-    if (targetAndAncestors.length === 0 && !isTopPage(path)) {
+    if (targetAndAncestors.length === 0 && pathOrId.includes('/') && !isTopPage(pathOrId)) {
       throw new Error('Ancestors must have at least one page.');
     }
 
@@ -291,6 +291,7 @@ module.exports = function(crowi, app) {
 
   async function _notFound(req, res) {
     const path = getPathFromRequest(req);
+    const pathOrId = req.params.id || path;
 
     let view;
     const renderVars = { path };
@@ -326,6 +327,7 @@ module.exports = function(crowi, app) {
     const limit = 50;
     const offset = parseInt(req.query.offset) || 0;
     await addRenderVarsForDescendants(renderVars, path, req.user, offset, limit, true);
+    await addRenderVarsForPageTree(renderVars, pathOrId, req.user);
 
     return res.render(view, renderVars);
   }
@@ -334,7 +336,7 @@ module.exports = function(crowi, app) {
     const id = req.params.id;
     const { revisionId } = req.query;
 
-    let page = await Page.findByIdAndViewer(id, req.user);
+    let page = await Page.findByIdAndViewer(id, req.user, null, true, true);
 
     if (page == null) {
       next();
@@ -395,7 +397,7 @@ module.exports = function(crowi, app) {
     const id = req.params.id;
     const revisionId = req.query.revision;
 
-    let page = await Page.findByIdAndViewer(id, req.user);
+    let page = await Page.findByIdAndViewer(id, req.user, null, true, true);
 
     if (page == null) {
       // check the page is forbidden or just does not exist.
@@ -592,7 +594,7 @@ module.exports = function(crowi, app) {
    * redirector
    */
   async function redirector(req, res, next, path) {
-    const pages = await Page.findByPathAndViewer(path, req.user, null, false);
+    const pages = await Page.findByPathAndViewer(path, req.user, null, false, true);
     const { redirectFrom } = req.query;
 
     if (pages.length >= 2) {

+ 1 - 1
packages/app/src/server/service/config-loader.ts

@@ -1,4 +1,4 @@
-import { envUtils } from 'growi-commons';
+import { envUtils } from '@growi/core';
 
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
packages/app/src/server/service/page.js

@@ -1001,7 +1001,7 @@ class PageService {
         await Page.createEmptyPagesByPaths(parentPaths, publicOnly);
 
         // find parents again
-        const builder = new PageQueryBuilder(Page.find({}, { _id: 1, path: 1 }));
+        const builder = new PageQueryBuilder(Page.find({}, { _id: 1, path: 1 }), true);
         const parents = await builder
           .addConditionToListByPathsArray(parentPaths)
           .query

+ 1 - 1
packages/app/src/server/service/slack-command-handler/create-page-service.js

@@ -3,7 +3,7 @@ import loggerFactory from '~/utils/logger';
 const logger = loggerFactory('growi:service:CreatePageService');
 const { reshapeContentsBody, respond, markdownSectionBlock } = require('@growi/slack');
 const mongoose = require('mongoose');
-const pathUtils = require('growi-commons').pathUtils;
+const { pathUtils } = require('@growi/core');
 
 class CreatePageService {
 

+ 1 - 1
packages/app/src/server/service/slack-command-handler/search.js

@@ -41,7 +41,7 @@ module.exports = (crowi) => {
 
     const { searchService } = crowi;
     const options = { limit: PAGINGLIMIT, offset };
-    const results = await searchService.searchKeyword(keywords, null, {}, options);
+    const [results] = await searchService.searchKeyword(keywords, null, {}, options);
     const resultsTotal = results.meta.total;
 
     const pages = results.data.map((data) => {

+ 1 - 1
packages/app/src/server/util/middlewares.js

@@ -5,7 +5,7 @@ import loggerFactory from '~/utils/logger';
 // eslint-disable-next-line no-unused-vars
 
 const { formatDistanceStrict } = require('date-fns');
-const pathUtils = require('growi-commons').pathUtils;
+const { pathUtils } = require('@growi/core');
 const md5 = require('md5');
 const entities = require('entities');
 

+ 1 - 1
packages/app/src/server/util/swigFunctions.js

@@ -2,7 +2,7 @@ module.exports = function(crowi, req, locals) {
   const debug = require('debug')('growi:lib:swigFunctions');
   const stringWidth = require('string-width');
 
-  const { pathUtils } = require('growi-commons');
+  const { pathUtils } = require('@growi/core');
 
   const Page = crowi.model('Page');
   const User = crowi.model('User');

+ 5 - 0
packages/app/src/server/views/layout/layout.html

@@ -125,6 +125,11 @@
   {{ userUISettings|json|safe }}
   </script>
 {% endif %}
+{% if targetAndAncestors != null %}
+  <script type="application/json" id="growi-pagetree-target-and-ancestors">
+  {{ targetAndAncestors|json|safe }}
+  </script>
+{% endif %}
 
 
 {% block custom_script %}

+ 0 - 1
packages/app/src/server/views/widget/page_content.html

@@ -27,7 +27,6 @@
   data-page-user="{% if pageUser %}{{ pageUser|json }}{% else %}null{% endif %}"
   data-share-links-number="{% if page %}{{ sharelinksNumber }}{% endif %}"
   data-share-link-id="{% if sharelink %}{{ sharelink._id|json }}{% endif %}"
-  data-target-and-ancestors="{% if targetAndAncestors %}{{ targetAndAncestors|json }}{% endif %}"
   >
 {% else %}
 <div id="content-main" class="content-main d-flex"

+ 1 - 1
packages/app/src/services/cdn-resources-service.js

@@ -4,7 +4,7 @@ import { resolveFromRoot } from '~/utils/project-dir-utils';
 const { URL } = require('url');
 const urljoin = require('url-join');
 
-const { envUtils } = require('growi-commons');
+const { envUtils } = require('@growi/core');
 
 const cdnLocalScriptRoot = 'public/static/js/cdn';
 const cdnLocalScriptWebRoot = '/static/js/cdn';

+ 2 - 2
packages/app/src/stores/page-listing.tsx

@@ -46,12 +46,12 @@ export const useSWRxPageChildren = (
 };
 
 export const useSWRxV5MigrationStatus = (
-    shouldFetch = true,
 ): SWRResponse<V5MigrationStatus, Error> => {
   return useSWR(
-    shouldFetch ? '/pages/v5-migration-status' : null,
+    '/pages/v5-migration-status',
     endpoint => apiv3Get(endpoint).then((response) => {
       return {
+        isV5Compatible: response.data.isV5Compatible,
         migratablePagesCount: response.data.migratablePagesCount,
       };
     }),

+ 0 - 129
packages/app/src/test/integration/service/page.test.js

@@ -821,133 +821,4 @@ describe('PageService', () => {
     });
   });
 
-  describe('v5MigrationByPageIds()', () => {
-    test('should migrate all pages specified by pageIds', async() => {
-      jest.restoreAllMocks();
-
-      // initialize pages for test
-      const pages = await Page.insertMany([
-        {
-          path: '/private1',
-          grant: Page.GRANT_OWNER,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-        {
-          path: '/dummyParent/private1',
-          grant: Page.GRANT_OWNER,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-        {
-          path: '/dummyParent/private1/private2',
-          grant: Page.GRANT_OWNER,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-        {
-          path: '/dummyParent/private1/private3',
-          grant: Page.GRANT_OWNER,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-      ]);
-
-      const pageIds = pages.map(page => page._id);
-      // migrate
-      await crowi.pageService.v5MigrationByPageIds(pageIds);
-
-      const migratedPages = await Page.find({
-        path: {
-          $in: ['/private1', '/dummyParent', '/dummyParent/private1', '/dummyParent/private1/private2', '/dummyParent/private1/private3'],
-        },
-      });
-      const migratedPagePaths = migratedPages.filter(doc => doc.parent != null).map(doc => doc.path);
-
-      const expected = ['/private1', '/dummyParent', '/dummyParent/private1', '/dummyParent/private1/private2', '/dummyParent/private1/private3'];
-
-      expect(migratedPagePaths.sort()).toStrictEqual(expected.sort());
-    });
-
-  });
-
-  describe('v5InitialMigration()', () => {
-    test('should migrate all public pages & replace private parents with empty pages', async() => {
-      jest.restoreAllMocks();
-
-      // initialize pages for test
-      const pages = await Page.insertMany([
-        {
-          path: '/publicA',
-          grant: Page.GRANT_PUBLIC,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-        {
-          path: '/publicA/privateB',
-          grant: Page.GRANT_OWNER,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-        {
-          path: '/publicA/privateB/publicC',
-          grant: Page.GRANT_PUBLIC,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-        {
-          path: '/parenthesis/(a)[b]{c}d',
-          grant: Page.GRANT_PUBLIC,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-        {
-          path: '/parenthesis/(a)[b]{c}d/public',
-          grant: Page.GRANT_PUBLIC,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-        },
-      ]);
-
-      const parent = await Page.find({ path: '/' });
-      await Page.insertMany([
-        {
-          path: '/migratedD',
-          grant: Page.GRANT_PUBLIC,
-          creator: testUser1,
-          lastUpdateUser: testUser1,
-          parent: parent._id,
-        },
-      ]);
-
-      // migrate
-      await crowi.pageService.v5InitialMigration(Page.GRANT_PUBLIC);
-
-      const nMigratedPages = await Page.count({
-        path: {
-          $in: ['/publicA', '/publicA/privateB/publicC', '/parenthesis/(a)[b]{c}d', '/parenthesis/(a)[b]{c}d/public', '/migratedD'],
-        },
-        isEmpty: false,
-        parent: { $ne: null },
-      });
-      const nMigratedEmptyPages = await Page.count({
-        path: {
-          $in: ['/publicA/privateB', '/parenthesis'],
-        },
-        isEmpty: true,
-        parent: { $ne: null },
-      });
-      const nNonMigratedPages = await Page.count({
-        path: {
-          $in: ['/publicA/privateB'],
-        },
-        parent: null,
-      });
-
-      expect(nMigratedPages).toBe(5);
-      expect(nMigratedEmptyPages).toBe(2);
-      expect(nNonMigratedPages).toBe(1);
-    });
-  });
-
 });

+ 194 - 0
packages/app/src/test/integration/service/v5-migration.test.js

@@ -0,0 +1,194 @@
+const mongoose = require('mongoose');
+
+const { getInstance } = require('../setup-crowi');
+
+describe('V5 page migration', () => {
+  let crowi;
+  let Page;
+
+  let testUser1;
+
+  beforeAll(async() => {
+    jest.restoreAllMocks();
+
+    crowi = await getInstance();
+    Page = mongoose.model('Page');
+  });
+
+
+  describe('v5MigrationByPageIds()', () => {
+    test('should migrate all pages specified by pageIds', async() => {
+      jest.restoreAllMocks();
+
+      // initialize pages for test
+      const pages = await Page.insertMany([
+        {
+          path: '/private1',
+          grant: Page.GRANT_OWNER,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+        {
+          path: '/dummyParent/private1',
+          grant: Page.GRANT_OWNER,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+        {
+          path: '/dummyParent/private1/private2',
+          grant: Page.GRANT_OWNER,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+        {
+          path: '/dummyParent/private1/private3',
+          grant: Page.GRANT_OWNER,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+      ]);
+
+      const pageIds = pages.map(page => page._id);
+      // migrate
+      await crowi.pageService.v5MigrationByPageIds(pageIds);
+
+      const migratedPages = await Page.find({
+        path: {
+          $in: ['/private1', '/dummyParent', '/dummyParent/private1', '/dummyParent/private1/private2', '/dummyParent/private1/private3'],
+        },
+      });
+      const migratedPagePaths = migratedPages.filter(doc => doc.parent != null).map(doc => doc.path);
+
+      const expected = ['/private1', '/dummyParent', '/dummyParent/private1', '/dummyParent/private1/private2', '/dummyParent/private1/private3'];
+
+      expect(migratedPagePaths.sort()).toStrictEqual(expected.sort());
+    });
+
+  });
+
+  describe('v5InitialMigration()', () => {
+    let createPagePaths;
+    let allPossiblePagePaths;
+    beforeAll(async() => {
+      createPagePaths = [
+        '/publicA', '/publicA/privateB', '/publicA/privateB/publicC', '/parenthesis/(a)[b]{c}d', '/parenthesis/(a)[b]{c}d/public', '/migratedD',
+      ];
+      allPossiblePagePaths = [...createPagePaths, '/parenthesis', '/'];
+
+      // initialize pages for test
+      await Page.insertMany([
+        {
+          path: '/publicA',
+          grant: Page.GRANT_PUBLIC,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+        {
+          path: '/publicA/privateB',
+          grant: Page.GRANT_OWNER,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+        {
+          path: '/publicA/privateB/publicC',
+          grant: Page.GRANT_PUBLIC,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+        {
+          path: '/parenthesis/(a)[b]{c}d',
+          grant: Page.GRANT_PUBLIC,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+        {
+          path: '/parenthesis/(a)[b]{c}d/public',
+          grant: Page.GRANT_PUBLIC,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+        },
+      ]);
+
+      const parent = await Page.find({ path: '/' });
+      await Page.insertMany([
+        {
+          path: '/migratedD',
+          grant: Page.GRANT_PUBLIC,
+          creator: testUser1,
+          lastUpdateUser: testUser1,
+          parent: parent._id,
+        },
+      ]);
+
+      // migrate
+      await crowi.pageService.v5InitialMigration(Page.GRANT_PUBLIC);
+    });
+
+    test('should migrate all public pages', async() => {
+      const migratedPages = await Page.find({
+        path: {
+          $in: allPossiblePagePaths,
+        },
+        parent: { $ne: null },
+      });
+      const migratedEmptyPages = await Page.find({
+        path: {
+          $in: allPossiblePagePaths,
+        },
+        isEmpty: true,
+        parent: { $ne: null },
+      });
+      const nonMigratedPages = await Page.find({
+        path: {
+          $in: allPossiblePagePaths,
+        },
+        parent: null,
+      });
+
+      const migratedPaths = migratedPages.map(page => page.path).sort();
+      const migratedEmptyPaths = migratedEmptyPages.map(page => page.path).sort();
+      const nonMigratedPaths = nonMigratedPages.map(page => page.path).sort();
+
+      const expectedMigratedPaths = allPossiblePagePaths.filter(path => path !== '/').sort();
+      const expectedMigratedEmptyPaths = ['/publicA/privateB', '/parenthesis'].sort();
+      const expectedNonMigratedPaths = ['/publicA/privateB', '/'].sort();
+
+      expect(migratedPaths).toStrictEqual(expectedMigratedPaths);
+      expect(migratedEmptyPaths).toStrictEqual(expectedMigratedEmptyPaths);
+      expect(nonMigratedPaths).toStrictEqual(expectedNonMigratedPaths);
+    });
+  });
+
+  test('replace private parents with empty pages', async() => {
+    const replacedPathPages = await Page.find({ path: '/publicA/privateB' }); // ex-private page
+
+    const _newEmptyPage = replacedPathPages.filter(page => page.parent != null)[0];
+    const newEmptyPage = {
+      path: _newEmptyPage.path,
+      grant: _newEmptyPage.grant,
+      isEmpty: _newEmptyPage.isEmpty,
+    };
+    const expectedNewEmptyPage = {
+      path: '/publicA/privateB',
+      grant: Page.GRANT_PUBLIC,
+      isEmpty: true,
+    };
+
+    const _privatePage = replacedPathPages.filter(page => page.parent == null)[0];
+    const privatePage = {
+      path: _privatePage.path,
+      grant: _privatePage.grant,
+      isEmpty: _privatePage.isEmpty,
+    };
+    const expectedPrivatePage = {
+      path: '/publicA/privateB',
+      grant: Page.GRANT_OWNER,
+      isEmpty: false,
+    };
+
+    expect(replacedPathPages.length).toBe(2);
+    expect(newEmptyPage).toStrictEqual(expectedNewEmptyPage);
+    expect(privatePage).toStrictEqual(expectedPrivatePage);
+  });
+
+});

+ 1 - 1
packages/codemirror-textlint/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/codemirror-textlint",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "license": "MIT",
   "main": "dist/index.js",
   "scripts": {

+ 0 - 27
packages/core/README.md

@@ -1,27 +0,0 @@
-# growi-commons
-
-[![dependencies status](https://david-dm.org/weseek/growi-commons.svg)](https://david-dm.org/weseek/growi-commons)
-[![devDependencies Status](https://david-dm.org/weseek/growi-commons/dev-status.svg)](https://david-dm.org/weseek/growi-commons?type=dev)
-[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
-
-[GROWI](https://growi.org) Commons Libraries to develop GROWI and plugins
-
-
-Overview
---------
-
-growi-commons package is includes some functions, classes and modules to develop GROWI substance and GROWI plugins.
-
-Install
---------
-
-1. install plugin
-
-    ```
-    $ npm install --save growi-commons
-    ```
-
-Documentation
-------------
-
-See https://docs.growi.org/api/commons/

+ 1 - 1
packages/core/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/core",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "description": "GROWI Core Libraries",
   "license": "MIT",
   "keywords": [

+ 11 - 14
packages/core/src/index.js

@@ -1,22 +1,19 @@
 import * as _pathUtils from './utils/path-utils';
+import * as _envUtils from './utils/env-utils';
 import * as _pagePathUtils from './utils/page-path-utils';
 import * as _templateChecker from './utils/template-checker';
-
-// module.exports = {
-//   BasicInterceptor: require('./utils/basic-interceptor'),
-//   envUtils: require('./utils/env-utils'),
-//   // plugin
-//   customTagUtils: require('./plugin/util/custom-tag-utils'),
-//   TagCacheManager: require('./plugin/service/tag-cache-manager'),
-//   // service
-//   LocalStorageManager: require('./service/localstorage-manager'),
-// };
-
-export * from './plugin/interfaces/plugin-definition-v4';
-export * from './models/devided-page-path';
-export * from './utils/mongoose-utils';
+import * as _customTagUtils from './plugin/util/custom-tag-utils';
 
 // export utils
 export const pathUtils = _pathUtils;
+export const envUtils = _envUtils;
 export const pagePathUtils = _pagePathUtils;
 export const templateChecker = _templateChecker;
+export const customTagUtils = _customTagUtils;
+
+export * from './plugin/interfaces/plugin-definition-v4';
+export * from './plugin/service/tag-cache-manager';
+export * from './models/devided-page-path';
+export * from './service/localstorage-manager';
+export * from './utils/basic-interceptor';
+export * from './utils/mongoose-utils';

+ 2 - 4
packages/core/src/plugin/service/tag-cache-manager.js

@@ -1,9 +1,9 @@
-const LocalStorageManager = require('../../service/localstorage-manager');
+import { LocalStorageManager } from '../../service/localstorage-manager';
 
 /**
  * Service Class for caching React state and TagContext
  */
-class TagCacheManager {
+export class TagCacheManager {
 
   /**
    * @callback generateCacheKey
@@ -67,5 +67,3 @@ class TagCacheManager {
   }
 
 }
-
-module.exports = TagCacheManager;

+ 1 - 3
packages/core/src/service/localstorage-manager.js

@@ -1,5 +1,5 @@
 let _instance = null;
-class LocalStorageManager {
+export class LocalStorageManager {
 
   static getInstance() {
     if (_instance == null) {
@@ -52,5 +52,3 @@ class LocalStorageManager {
   }
 
 }
-
-module.exports = LocalStorageManager;

+ 1 - 3
packages/core/src/utils/basic-interceptor.js

@@ -1,7 +1,7 @@
 /**
  * Basic Interceptor class
  */
-class BasicInterceptor {
+export class BasicInterceptor {
 
   /**
    * getter for id
@@ -43,5 +43,3 @@ class BasicInterceptor {
   }
 
 }
-
-module.exports = BasicInterceptor;

+ 1 - 1
packages/plugin-attachment-refs/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/plugin-attachment-refs",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "description": "GROWI Plugin to add ref/refimg/refs/refsimg tags",
   "license": "MIT",
   "keywords": [

+ 1 - 1
packages/plugin-attachment-refs/src/client/js/util/Interceptor/RefsPostRenderInterceptor.js

@@ -1,7 +1,7 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
 
-import { BasicInterceptor } from 'growi-commons';
+import { BasicInterceptor } from '@growi/core';
 
 import RefsContext from '../RefsContext';
 import GalleryContext from '../GalleryContext';

+ 1 - 1
packages/plugin-attachment-refs/src/client/js/util/Interceptor/RefsPreRenderInterceptor.js

@@ -1,4 +1,4 @@
-import { customTagUtils, BasicInterceptor } from 'growi-commons';
+import { customTagUtils, BasicInterceptor } from '@growi/core';
 
 import TagCacheManagerFactory from '../TagCacheManagerFactory';
 

+ 1 - 1
packages/plugin-attachment-refs/src/client/js/util/RefsContext.js

@@ -1,6 +1,6 @@
 import * as url from 'url';
 
-import { customTagUtils, pathUtils } from 'growi-commons';
+import { customTagUtils, pathUtils } from '@growi/core';
 
 const { TagContext, ArgsParser, OptionParser } = customTagUtils;
 

+ 1 - 1
packages/plugin-attachment-refs/src/client/js/util/TagCacheManagerFactory.js

@@ -1,4 +1,4 @@
-import { TagCacheManager } from 'growi-commons';
+import { TagCacheManager } from '@growi/core';
 
 const STATE_CACHE_NS = 'refs-state-cache';
 

+ 1 - 1
packages/plugin-attachment-refs/src/server/routes/refs.js

@@ -1,6 +1,6 @@
 import loggerFactory from '../../utils/logger';
 
-const { customTagUtils } = require('growi-commons');
+const { customTagUtils } = require('@growi/core');
 
 const { OptionParser } = customTagUtils;
 

+ 1 - 1
packages/plugin-lsx/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/plugin-lsx",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "description": "GROWI plugin to list pages",
   "license": "MIT",
   "keywords": [

+ 1 - 1
packages/plugin-lsx/src/client/js/components/Lsx.jsx

@@ -3,7 +3,7 @@ import PropTypes from 'prop-types';
 
 import * as url from 'url';
 
-import { pathUtils } from 'growi-commons';
+import { pathUtils } from '@growi/core';
 
 // eslint-disable-next-line no-unused-vars
 import styles from '../../css/index.css';

+ 1 - 1
packages/plugin-lsx/src/client/js/components/LsxPageList/LsxPage.jsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import PropTypes from 'prop-types';
 
-import { pathUtils } from 'growi-commons';
+import { pathUtils } from '@growi/core';
 
 import { PageListMeta } from '@growi/ui';
 

+ 1 - 1
packages/plugin-lsx/src/client/js/util/Interceptor/LsxLogoutInterceptor.js

@@ -1,4 +1,4 @@
-import { BasicInterceptor } from 'growi-commons';
+import { BasicInterceptor } from '@growi/core';
 
 import { TagCacheManagerFactory } from '../TagCacheManagerFactory';
 

+ 1 - 1
packages/plugin-lsx/src/client/js/util/Interceptor/LsxPostRenderInterceptor.js

@@ -1,7 +1,7 @@
 import React from 'react';
 import ReactDOM from 'react-dom';
 
-import { BasicInterceptor } from 'growi-commons';
+import { BasicInterceptor } from '@growi/core';
 
 import { LsxContext } from '../LsxContext';
 import { Lsx } from '../../components/Lsx';

+ 1 - 1
packages/plugin-lsx/src/client/js/util/Interceptor/LsxPreRenderInterceptor.js

@@ -1,5 +1,5 @@
 import ReactDOM from 'react-dom';
-import { customTagUtils, BasicInterceptor } from 'growi-commons';
+import { customTagUtils, BasicInterceptor } from '@growi/core';
 
 /**
  * The interceptor for lsx

+ 1 - 1
packages/plugin-lsx/src/client/js/util/LsxContext.js

@@ -1,6 +1,6 @@
 import * as url from 'url';
 
-import { customTagUtils, pathUtils } from 'growi-commons';
+import { customTagUtils, pathUtils } from '@growi/core';
 
 const { TagContext, ArgsParser, OptionParser } = customTagUtils;
 

+ 1 - 18
packages/plugin-lsx/src/client/js/util/TagCacheManagerFactory.js

@@ -1,29 +1,12 @@
-import { TagCacheManager } from 'growi-commons';
+import { TagCacheManager } from '@growi/core';
 
 const LSX_STATE_CACHE_NS = 'lsx-state-cache';
 
 
-// validate growi-commons version
-function validateGrowiCommonsVersion() {
-  // TagCacheManager was created on growi-commons@4.0.7
-  if (TagCacheManager == null) {
-    throw new Error(
-      'This version of \'growi-plugin-lsx\' requires \'growi-commons >= 4.0.7\'.\n'
-      + 'To resolve this, please process  either a) or b).\n'
-      + '\n'
-      + 'a) Use \'growi-plugin-lsx@3.0.0\'\n'
-      + 'b) Edit \'package.json\' of growi and upgrade \'growi-commons\' to v4.0.7 or above.',
-    );
-  }
-}
-
-
 let _instance;
 export class TagCacheManagerFactory {
 
   static getInstance() {
-    validateGrowiCommonsVersion();
-
     if (_instance == null) {
       // create generateCacheKey implementation
       const generateCacheKey = (lsxContext) => {

+ 1 - 1
packages/plugin-lsx/src/server/routes/lsx.js

@@ -1,4 +1,4 @@
-const { customTagUtils } = require('growi-commons');
+const { customTagUtils } = require('@growi/core');
 
 const { OptionParser } = customTagUtils;
 

+ 1 - 1
packages/plugin-pukiwiki-like-linker/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/plugin-pukiwiki-like-linker",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "description": "GROWI plugin to add PukiwikiLikeLinker",
   "license": "MIT",
   "keywords": [

+ 1 - 1
packages/slack/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/slack",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "license": "MIT",
   "main": "dist/index.js",
   "typings": "dist/index.d.ts",

+ 3 - 3
packages/slackbot-proxy/docker/Dockerfile

@@ -3,7 +3,7 @@
 ##
 ## deps-resolver-base
 ##
-FROM node:14-slim AS deps-resolver-base
+FROM node:16-slim AS deps-resolver-base
 
 ENV appDir /opt
 
@@ -46,7 +46,7 @@ RUN tar cf dependencies.tar \
 ##
 ## builder
 ##
-FROM node:14-slim AS builder
+FROM node:16-slim AS builder
 
 ENV appDir /opt
 
@@ -83,7 +83,7 @@ RUN tar cf packages.tar \
 ##
 ## release
 ##
-FROM node:14-slim
+FROM node:16-slim
 LABEL maintainer Yuki Takei <yuki@weseek.co.jp>
 
 ENV NODE_ENV production

+ 2 - 2
packages/slackbot-proxy/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/slackbot-proxy",
-  "version": "4.5.3-slackbot-proxy.1",
+  "version": "5.0.0-slackbot-proxy.0",
   "license": "MIT",
   "scripts": {
     "build": "yarn tsc && tsc-alias -p tsconfig.build.json",
@@ -25,7 +25,7 @@
   },
   "dependencies": {
     "@godaddy/terminus": "^4.9.0",
-    "@growi/slack": "^4.5.3-RC.0",
+    "@growi/slack": "^5.0.0-RC.0",
     "@slack/oauth": "^2.0.1",
     "@slack/web-api": "^6.2.4",
     "@tsed/common": "^6.43.0",

+ 0 - 27
packages/ui/README.md

@@ -1,27 +0,0 @@
-# growi-commons
-
-[![dependencies status](https://david-dm.org/weseek/growi-commons.svg)](https://david-dm.org/weseek/growi-commons)
-[![devDependencies Status](https://david-dm.org/weseek/growi-commons/dev-status.svg)](https://david-dm.org/weseek/growi-commons?type=dev)
-[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat)](LICENSE)
-
-[GROWI](https://growi.org) Commons Libraries to develop GROWI and plugins
-
-
-Overview
---------
-
-growi-commons package is includes some functions, classes and modules to develop GROWI substance and GROWI plugins.
-
-Install
---------
-
-1. install plugin
-
-    ```
-    $ npm install --save growi-commons
-    ```
-
-Documentation
-------------
-
-See https://docs.growi.org/api/commons/

+ 1 - 1
packages/ui/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/ui",
-  "version": "4.5.3-RC.0",
+  "version": "5.0.0-RC.0",
   "description": "GROWI UI Libraries",
   "license": "MIT",
   "keywords": [

+ 114 - 83
yarn.lock

@@ -1856,6 +1856,21 @@
     google-libphonenumber ">=3.2.10"
     lodash ">=4.17.15"
 
+"@mapbox/node-pre-gyp@^1.0.5":
+  version "1.0.8"
+  resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.8.tgz#32abc8a5c624bc4e46c43d84dfb8b26d33a96f58"
+  integrity sha512-CMGKi28CF+qlbXh26hDe6NxCd7amqeAzEqnS6IHeO6LoaKyM/n+Xw3HT1COdq8cuioOdlKdqn/hCmqPUOMOywg==
+  dependencies:
+    detect-libc "^1.0.3"
+    https-proxy-agent "^5.0.0"
+    make-dir "^3.1.0"
+    node-fetch "^2.6.5"
+    nopt "^5.0.0"
+    npmlog "^5.0.1"
+    rimraf "^3.0.2"
+    semver "^7.3.5"
+    tar "^6.1.11"
+
 "@nodelib/fs.scandir@2.1.3":
   version "2.1.3"
   resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b"
@@ -2147,46 +2162,46 @@
   dependencies:
     "@octokit/openapi-types" "^10.0.0"
 
-"@promster/express@^5.1.0":
-  version "5.1.0"
-  resolved "https://registry.yarnpkg.com/@promster/express/-/express-5.1.0.tgz#6b0b3e0bc713b7f76792c3a99babe06172652c8e"
-  integrity sha512-IFGtCzxByLMSLdqQK8AT1NIIQPqvOO1GfOSg25smlCVUZvnhgBQOj8MzWCuMNL4v6efeuQVVrZWmOA6Yo3w40Q==
+"@promster/express@^7.0.2":
+  version "7.0.2"
+  resolved "https://registry.yarnpkg.com/@promster/express/-/express-7.0.2.tgz#d60b10d373fd572275714426dc90a7049fd26d4f"
+  integrity sha512-HnNxb9bVZpUPbPU6/1UjACe2PeZEJmVw3tVxzZA8CdzGvPMwewe1e1TXNR9PASWRA/pJj6FBHHUPuTq0daEcgg==
   dependencies:
-    "@promster/metrics" "^7.0.0"
+    "@promster/metrics" "^9.1.1"
     merge-options "3.0.4"
     tslib "2.3.1"
 
-"@promster/metrics@^7.0.0":
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/@promster/metrics/-/metrics-7.0.0.tgz#19ec55ab5472f5d0b690b15ffd7f88181e8b2fe7"
-  integrity sha512-SHZtSgETJETjGYdw7e9NVcpC7CxrSmxup+kbtvPN7Pgc9u35B5hYylOaIzj5r9HDwKBpARKIbDFYMs18LLBpQw==
+"@promster/metrics@^9.1.1", "@promster/metrics@^9.1.2":
+  version "9.1.2"
+  resolved "https://registry.yarnpkg.com/@promster/metrics/-/metrics-9.1.2.tgz#2468fae02adf87febdba8a25a4203111ea347f66"
+  integrity sha512-kKcawgTJahHUFjnX/TOr6vju+196rSKlGQUfjC6am6sBxqFbccsBW/nEPusUEUswvnC4zv+ddbNz4uLJcu1w7A==
   dependencies:
     lodash.memoize "4.1.2"
     lodash.once "4.1.1"
     merge-options "3.0.4"
     optional "0.1.4"
-    ts-essentials "8.1.0"
+    ts-essentials "9.0.0"
     tslib "2.3.1"
     url "0.11.0"
-    url-value-parser "2.0.3"
+    url-value-parser "2.1.0"
   optionalDependencies:
-    "@sematext/gc-stats" "1.5.3"
+    "@sematext/gc-stats" "1.5.5"
 
-"@promster/server@^6.0.3":
-  version "6.0.3"
-  resolved "https://registry.yarnpkg.com/@promster/server/-/server-6.0.3.tgz#92409f97012dc7bd8c0437cb3cd95dae6ae78d91"
-  integrity sha512-d5VoeT2dwpe5Yk5BlFfjyXEa/ch4yq9AP/SymUM4df3nvdX0jnc/D2MuG/nZDKsMuRxUzf8bn38bXs71d3KJpA==
+"@promster/server@^7.0.4":
+  version "7.0.4"
+  resolved "https://registry.yarnpkg.com/@promster/server/-/server-7.0.4.tgz#b4c6babb6dd4d185c164020054a78f2d5da03755"
+  integrity sha512-JDOBVBe2Iqd29kLL5J3HuNyHuVhiX65sJdmZkY3GTBAOmmZFom/k+rT+JIBZRefhALhzU3pzMbpvxpvXlm0TOA==
   dependencies:
-    "@promster/metrics" "^7.0.0"
+    "@promster/metrics" "^9.1.2"
     tslib "2.3.1"
 
-"@sematext/gc-stats@1.5.3":
-  version "1.5.3"
-  resolved "https://registry.yarnpkg.com/@sematext/gc-stats/-/gc-stats-1.5.3.tgz#66a1345b637b1d9e4f6415d9c82c13568d4afb3e"
-  integrity sha512-buh5fs+2ZIehfVY4+2mFZO5gxGXpX9mAOrR8duO3Spbb5y2aHJyvO0yxn2suWprKIPY1J337IndIdAf/WIyTYw==
+"@sematext/gc-stats@1.5.5":
+  version "1.5.5"
+  resolved "https://registry.yarnpkg.com/@sematext/gc-stats/-/gc-stats-1.5.5.tgz#3461e818454b95de26085b65f0d95417b9f183d6"
+  integrity sha512-OetiHJ7vVPy2xvM+qyTuGoDvnSy4B6JGEhoIRmAONhaa8oOL2NaBiBg2HEI+DQPwOpUeCTUVBV3/uiBt24Ru7Q==
   dependencies:
-    nan "^2.14.2"
-    node-pre-gyp "^0.15.0"
+    "@mapbox/node-pre-gyp" "^1.0.5"
+    nan "^2.15.0"
 
 "@sindresorhus/is@^0.7.0":
   version "0.7.0"
@@ -6828,7 +6843,7 @@ detect-indent@^7.0.0:
   resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-7.0.0.tgz#cab58e6ab1129c669e2101181a6c677917d43577"
   integrity sha512-/6kJlmVv6RDFPqaHC/ZDcU8bblYcoph2dUQ3kB47QqhkUEqXe3VZPELK9BaEMrC73qu+wn0AQ7iSteceN+yuMw==
 
-detect-libc@^1.0.2:
+detect-libc@^1.0.3:
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
   integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
@@ -8905,6 +8920,21 @@ functional-red-black-tree@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
 
+gauge@^3.0.0:
+  version "3.0.2"
+  resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"
+  integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==
+  dependencies:
+    aproba "^1.0.3 || ^2.0.0"
+    color-support "^1.1.2"
+    console-control-strings "^1.0.0"
+    has-unicode "^2.0.1"
+    object-assign "^4.1.1"
+    signal-exit "^3.0.0"
+    string-width "^4.2.3"
+    strip-ansi "^6.0.1"
+    wide-align "^1.1.2"
+
 gauge@^4.0.0:
   version "4.0.0"
   resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.0.tgz#afba07aa0374a93c6219603b1fb83eaa2264d8f8"
@@ -9440,11 +9470,6 @@ grapheme-splitter@^1.0.4:
   resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
   integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
 
-growi-commons@^5.0.4:
-  version "5.0.4"
-  resolved "https://registry.yarnpkg.com/growi-commons/-/growi-commons-5.0.4.tgz#1235b7955a3f492803e8c714fef5c4a797e442b7"
-  integrity sha512-K282Pe97SnJgbZWAuMz9pNDTmvmw4JYPf/oYQaPmBsUjaxG4FDwd7+p5UFc5GqZUWcLwXvtJZQZMZEH/xpg+nA==
-
 growly@^1.3.0:
   version "1.3.0"
   resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081"
@@ -9988,7 +10013,7 @@ iconv-lite@0.4.23:
   dependencies:
     safer-buffer ">= 2.1.2 < 3"
 
-iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4:
+iconv-lite@0.4.24, iconv-lite@^0.4.24:
   version "0.4.24"
   resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
   dependencies:
@@ -10022,7 +10047,7 @@ iferr@^0.1.5:
   version "0.1.5"
   resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501"
 
-ignore-walk@^3.0.1, ignore-walk@^3.0.3:
+ignore-walk@^3.0.3:
   version "3.0.3"
   resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.3.tgz#017e2447184bfeade7c238e4aefdd1e8f95b1e37"
   integrity sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==
@@ -12387,7 +12412,7 @@ make-dir@^3.0.0:
   dependencies:
     semver "^6.0.0"
 
-make-dir@^3.0.2:
+make-dir@^3.0.2, make-dir@^3.1.0:
   version "3.1.0"
   resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
   integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@@ -13331,7 +13356,7 @@ mkdirp@1.0.4, mkdirp@1.x, mkdirp@^1.0.0, mkdirp@^1.0.3, mkdirp@^1.0.4:
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
   integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
 
-"mkdirp@>=0.5 0", mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@^0.5.5, mkdirp@~0.5.1:
+"mkdirp@>=0.5 0", mkdirp@^0.5, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.1:
   version "0.5.5"
   resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
   integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
@@ -13628,7 +13653,7 @@ nan@^2.12.1, nan@^2.14.0:
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
   integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
 
-nan@^2.14.2, nan@^2.15.0:
+nan@^2.15.0:
   version "2.15.0"
   resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
   integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
@@ -13663,15 +13688,6 @@ ncp@~2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3"
 
-needle@^2.5.0:
-  version "2.9.1"
-  resolved "https://registry.yarnpkg.com/needle/-/needle-2.9.1.tgz#22d1dffbe3490c2b83e301f7709b6736cd8f2684"
-  integrity sha512-6R9fqJ5Zcmf+uYaFgdIHmLwNldn5HbK8L5ybn7Uz+ylX/rnOsSp1AHcvQSrCaFN+qNM1wpymHqD7mVasEOlHGQ==
-  dependencies:
-    debug "^3.2.6"
-    iconv-lite "^0.4.4"
-    sax "^1.2.4"
-
 negotiator@0.6.1:
   version "0.6.1"
   resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"
@@ -13782,6 +13798,13 @@ node-fetch@^2.6.1:
   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
   integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
 
+node-fetch@^2.6.5:
+  version "2.6.6"
+  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89"
+  integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==
+  dependencies:
+    whatwg-url "^5.0.0"
+
 node-forge@^0.10.0:
   version "0.10.0"
   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3"
@@ -13908,22 +13931,6 @@ node-object-hash@^1.2.0:
   resolved "https://registry.yarnpkg.com/node-object-hash/-/node-object-hash-1.4.2.tgz#385833d85b229902b75826224f6077be969a9e94"
   integrity sha512-UdS4swXs85fCGWWf6t6DMGgpN/vnlKeSGEQ7hJcrs7PBFoxoKLmibc3QRb7fwiYsjdL7PX8iI/TMSlZ90dgHhQ==
 
-node-pre-gyp@^0.15.0:
-  version "0.15.0"
-  resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.15.0.tgz#c2fc383276b74c7ffa842925241553e8b40f1087"
-  integrity sha512-7QcZa8/fpaU/BKenjcaeFF9hLz2+7S9AqyXFhlH/rilsQ/hPZKK32RtR5EQHJElgu+q5RfbJ34KriI79UWaorA==
-  dependencies:
-    detect-libc "^1.0.2"
-    mkdirp "^0.5.3"
-    needle "^2.5.0"
-    nopt "^4.0.1"
-    npm-packlist "^1.1.6"
-    npmlog "^4.0.2"
-    rc "^1.2.7"
-    rimraf "^2.6.1"
-    semver "^5.3.0"
-    tar "^4.4.2"
-
 node-readfiles@^0.2.0:
   version "0.2.0"
   resolved "https://registry.yarnpkg.com/node-readfiles/-/node-readfiles-0.2.0.tgz#dbbd4af12134e2e635c245ef93ffcf6f60673a5d"
@@ -14045,7 +14052,7 @@ normalize-url@^3.3.0:
   resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559"
   integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==
 
-npm-bundled@^1.0.1, npm-bundled@^1.1.1:
+npm-bundled@^1.1.1:
   version "1.1.1"
   resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.1.tgz#1edd570865a94cdb1bc8220775e29466c9fb234b"
   integrity sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==
@@ -14087,15 +14094,6 @@ npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.0, npm-pack
     semver "^7.3.4"
     validate-npm-package-name "^3.0.0"
 
-npm-packlist@^1.1.6:
-  version "1.4.8"
-  resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
-  integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
-  dependencies:
-    ignore-walk "^3.0.1"
-    npm-bundled "^1.0.1"
-    npm-normalize-package-bin "^1.0.1"
-
 npm-packlist@^2.1.4:
   version "2.1.5"
   resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.1.5.tgz#43ef5bbb9f59b7c0ef91e0905f1dd707b4cfb33c"
@@ -14158,7 +14156,7 @@ npm-run-path@^4.0.1:
   dependencies:
     path-key "^3.0.0"
 
-npmlog@^4.0.2, npmlog@^4.1.2:
+npmlog@^4.1.2:
   version "4.1.2"
   resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
   integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
@@ -14168,6 +14166,16 @@ npmlog@^4.0.2, npmlog@^4.1.2:
     gauge "~2.7.3"
     set-blocking "~2.0.0"
 
+npmlog@^5.0.1:
+  version "5.0.1"
+  resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0"
+  integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==
+  dependencies:
+    are-we-there-yet "^2.0.0"
+    console-control-strings "^1.1.0"
+    gauge "^3.0.0"
+    set-blocking "^2.0.0"
+
 npmlog@^6.0.0:
   version "6.0.0"
   resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.0.tgz#ba9ef39413c3d936ea91553db7be49c34ad0520c"
@@ -16296,7 +16304,7 @@ rc-config-loader@^3.0.0:
     json5 "^2.1.1"
     require-from-string "^2.0.2"
 
-rc@>=1.2.8, rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
+rc@>=1.2.8, rc@^1.0.1, rc@^1.1.6:
   version "1.2.8"
   resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
   integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
@@ -17434,7 +17442,7 @@ sax@1.2.1:
   version "1.2.1"
   resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a"
 
-sax@>=0.6.0, sax@^1.2.1, sax@^1.2.4, sax@~1.2.4:
+sax@>=0.6.0, sax@^1.2.1, sax@~1.2.4:
   version "1.2.4"
   resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
   integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
@@ -17525,7 +17533,7 @@ semver@>=7.3.2:
   resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
   integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
 
-semver@^5.1.0, semver@^5.3.0:
+semver@^5.1.0:
   version "5.4.1"
   resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e"
 
@@ -19204,7 +19212,7 @@ tar-stream@^2.2.0:
     inherits "^2.0.3"
     readable-stream "^3.1.1"
 
-tar@^4.4.12, tar@^4.4.2:
+tar@^4.4.12:
   version "4.4.19"
   resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3"
   integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==
@@ -19229,7 +19237,7 @@ tar@^6.0.2, tar@^6.1.0:
     mkdirp "^1.0.3"
     yallist "^4.0.0"
 
-tar@^6.1.2:
+tar@^6.1.11, tar@^6.1.2:
   version "6.1.11"
   resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621"
   integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==
@@ -19887,6 +19895,11 @@ tr46@^3.0.0:
   dependencies:
     punycode "^2.1.1"
 
+tr46@~0.0.3:
+  version "0.0.3"
+  resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
+  integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=
+
 "traverse@>=0.3.0 <0.4":
   version "0.3.9"
   resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9"
@@ -19950,10 +19963,10 @@ tryer@^1.0.0:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
 
-ts-essentials@8.1.0:
-  version "8.1.0"
-  resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-8.1.0.tgz#bc982b242db226b84c89477d3d42630ee2954513"
-  integrity sha512-34xALeQADWRYq9kbtprP4KdpTQ3v3BBIs/U4SpaP+C4++B8ijXY5NnILRJLchQVMzw7YBzKuGMUMrI9uT+ALVw==
+ts-essentials@9.0.0:
+  version "9.0.0"
+  resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-9.0.0.tgz#6196b7f390926429256c70951c8edd260e8e5097"
+  integrity sha512-pow5YBSknf/PyoDhr8vsb93+hZah/jSzhdHA3GMjSzUuZIDZH+rV7tvN5DCbN4hi7QJXdteDv8D9HdDCSwXBUw==
 
 ts-jest@^27.0.4:
   version "27.0.4"
@@ -20631,10 +20644,10 @@ url-to-options@^1.0.1:
   resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9"
   integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=
 
-url-value-parser@2.0.3:
-  version "2.0.3"
-  resolved "https://registry.yarnpkg.com/url-value-parser/-/url-value-parser-2.0.3.tgz#cd4b8d6754e458d65e8125260c09718d926e6e21"
-  integrity sha512-FjIX+Q9lYmDM9uYIGdMYfQW0uLbWVwN2NrL2ayAI7BTOvEwzH+VoDdNquwB9h4dFAx+u6mb0ONLa3sHD5DvyvA==
+url-value-parser@2.1.0:
+  version "2.1.0"
+  resolved "https://registry.yarnpkg.com/url-value-parser/-/url-value-parser-2.1.0.tgz#fe1ae776122b2eea4bbf284896bbdcd7fc75e1fa"
+  integrity sha512-gIYPWXujdUdwd/9TGCHTf5Vvgw6lOxjE5Q/k+7WNByYyS0vW5WX0k+xuVlhvPq6gRNhzXVv/ezC+OfeAet5Kcw==
 
 url@0.10.3:
   version "0.10.3"
@@ -20914,6 +20927,11 @@ web-namespaces@^1.1.2:
   resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec"
   integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==
 
+webidl-conversions@^3.0.0:
+  version "3.0.1"
+  resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871"
+  integrity sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=
+
 webidl-conversions@^5.0.0:
   version "5.0.0"
   resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff"
@@ -21057,6 +21075,14 @@ whatwg-url@^11.0.0:
     tr46 "^3.0.0"
     webidl-conversions "^7.0.0"
 
+whatwg-url@^5.0.0:
+  version "5.0.0"
+  resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d"
+  integrity sha1-lmRU6HZUYuN2RNNib2dCzotwll0=
+  dependencies:
+    tr46 "~0.0.3"
+    webidl-conversions "^3.0.0"
+
 whatwg-url@^8.0.0, whatwg-url@^8.5.0:
   version "8.7.0"
   resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77"
@@ -21295,6 +21321,11 @@ ws@^7.4.6:
   resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.1.tgz#44fc000d87edb1d9c53e51fbc69a0ac1f6871d66"
   integrity sha512-2c6faOUH/nhoQN6abwMloF7Iyl0ZS2E9HGtsiLrWn0zOOMWlhtDmdf/uihDt6jnuCxgtwGBNy6Onsoy2s2O2Ow==
 
+ws@^8.3.0:
+  version "8.3.0"
+  resolved "https://registry.yarnpkg.com/ws/-/ws-8.3.0.tgz#7185e252c8973a60d57170175ff55fdbd116070d"
+  integrity sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==
+
 ws@~7.4.2:
   version "7.4.6"
   resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"