Przeglądaj źródła

Merge branch 'master' into imprv/types-for-crowi-and-config-manager

Yuki Takei 1 rok temu
rodzic
commit
584a876774

+ 6 - 7
apps/app/src/client/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -9,11 +9,10 @@ import type {
 import { pagePathUtils } from '@growi/core/dist/utils';
 import { GlobalCodeMirrorEditorKey } from '@growi/editor';
 import { useCodeMirrorEditorIsolated } from '@growi/editor/dist/client/stores/codemirror-editor';
-import { auto } from '@popperjs/core';
-import { useTranslation } from 'next-i18next';
 import dynamic from 'next/dynamic';
 import Link from 'next/link';
 import { useRouter } from 'next/router';
+import { useTranslation } from 'next-i18next';
 import Sticky from 'react-stickynode';
 import { DropdownItem, UncontrolledTooltip } from 'reactstrap';
 
@@ -22,11 +21,6 @@ import { toastSuccess, toastError, toastWarning } from '~/client/util/toastr';
 import { GroundGlassBar } from '~/components/Navbar/GroundGlassBar';
 import type { OnDuplicatedFunction, OnRenamedFunction, OnDeletedFunction } from '~/interfaces/ui';
 import { useShouldExpandContent } from '~/services/layout/use-should-expand-content';
-import {
-  useCurrentPathname,
-  useCurrentUser, useIsGuestUser, useIsReadOnlyUser, useIsLocalAccountRegistrationEnabled, useIsSharedUser, useShareLinkId,
-} from '~/stores-universal/context';
-import { useEditorMode } from '~/stores-universal/ui';
 import {
   usePageAccessoriesModal, PageAccessoriesModalContents, type IPageForPageDuplicateModal,
   usePageDuplicateModal, usePageRenameModal, usePageDeleteModal, usePagePresentationModal,
@@ -40,6 +34,11 @@ import {
   useIsAbleToChangeEditorMode,
   useIsDeviceLargerThanMd,
 } from '~/stores/ui';
+import {
+  useCurrentPathname,
+  useCurrentUser, useIsGuestUser, useIsReadOnlyUser, useIsLocalAccountRegistrationEnabled, useIsSharedUser, useShareLinkId,
+} from '~/stores-universal/context';
+import { useEditorMode } from '~/stores-universal/ui';
 
 import { NotAvailable } from '../NotAvailable';
 import { Skeleton } from '../Skeleton';

+ 8 - 0
apps/app/src/client/components/PagePathNavSticky/PagePathNavSticky.module.scss

@@ -13,3 +13,11 @@
     }
   }
 }
+
+@media print {
+  .grw-page-path-nav-sticky :global {
+    .sticky-inner-wrapper {
+      position: static !important;
+    }
+  }
+}

+ 1 - 1
apps/app/src/components/Layout/BasicLayout.tsx

@@ -46,7 +46,7 @@ export const BasicLayout = ({ children, className }: Props): JSX.Element => {
   return (
     <RawLayout className={`${moduleClass} ${className ?? ''}`}>
       <div className="page-wrapper flex-row">
-        <div className="z-2">
+        <div className="z-2 d-print-none">
           <Sidebar />
         </div>
 

+ 1 - 1
apps/app/src/components/PageView/PageContentFooter.module.scss

@@ -1,7 +1,7 @@
 @use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .page-content-footer :global {
-  border-top: solid 1px transparent;
+  border-top: solid 1px var(--bs-border-color);
   .page-meta {
     font-size: 0.95em;
   }

+ 4 - 6
apps/app/src/components/PageView/PageContentFooter.tsx

@@ -22,12 +22,10 @@ export const PageContentFooter = (props: PageContentFooterProps): JSX.Element =>
   }
 
   return (
-    <div className={`${styles['page-content-footer']} page-content-footer py-4 d-edit-none d-print-none}`}>
-      <div className="container-lg grw-container-convertible">
-        <div className="page-meta">
-          <AuthorInfo user={creator} date={createdAt} mode="create" locate="footer" />
-          <AuthorInfo user={lastUpdateUser} date={updatedAt} mode="update" locate="footer" />
-        </div>
+    <div className={`${styles['page-content-footer']} my-4 pt-4 d-edit-none d-print-none}`}>
+      <div className="page-meta">
+        <AuthorInfo user={creator} date={createdAt} mode="create" locate="footer" />
+        <AuthorInfo user={lastUpdateUser} date={updatedAt} mode="update" locate="footer" />
       </div>
     </div>
   );

+ 1 - 1
apps/app/src/components/PageView/PageViewLayout.tsx

@@ -51,7 +51,7 @@ export const PageViewLayout = (props: Props): JSX.Element => {
       </div>
 
       { footerContents != null && (
-        <footer className={`footer d-edit-none wide-gutter-x-lg ${fluidLayoutClass}`}>
+        <footer className={`footer d-edit-none container-lg wide-gutter-x-lg ${fluidLayoutClass}`}>
           {footerContents}
         </footer>
       ) }

+ 15 - 0
apps/app/src/server/routes/apiv3/logout.js

@@ -14,6 +14,21 @@ module.exports = (crowi) => {
   const activityEvent = crowi.event('activity');
   const addActivity = generateAddActivityMiddleware(crowi);
 
+  /**
+   * @swagger
+   *  /logout:
+   *    post:
+   *      tags: [Users]
+   *      security:
+   *        - cookieAuth: []
+   *      summary: Logout user
+   *      description: Logout the currently authenticated user
+   *      responses:
+   *        200:
+   *          description: Successfully logged out
+   *        500:
+   *          description: Internal server error
+   */
   router.post('/', addActivity, async(req, res) => {
     req.session.destroy();
 

+ 88 - 12
apps/app/src/server/routes/apiv3/markdown-setting.js

@@ -38,6 +38,37 @@ const validator = {
  *
  *  components:
  *    schemas:
+ *      MarkdownParams:
+ *        description: MarkdownParams
+ *        type: object
+ *        properties:
+ *          isEnabledLinebreaks:
+ *            type: boolean
+ *            description: enable lineBreak
+ *          isEnabledLinebreaksInComments:
+ *            type: boolean
+ *            description: enable lineBreak in comment
+ *          adminPreferredIndentSize:
+ *            type: number
+ *            description: preferred indent size
+ *          isIndentSizeForced:
+ *            type: boolean
+ *            description: force indent size
+ *          isEnabledXss:
+ *            type: boolean
+ *            description: enable xss
+ *          xssOption:
+ *            type: number
+ *            description: number of xss option
+ *          tagWhitelist:
+ *            type: array
+ *            description: array of tag whitelist
+ *            items:
+ *              type: string
+ *              description: tag whitelist
+ *          attrWhitelist:
+ *            type: string
+ *            description: attr whitelist
  *      LineBreakParams:
  *        description: LineBreakParams
  *        type: object
@@ -62,7 +93,7 @@ const validator = {
  *        description: XssParams
  *        type: object
  *        properties:
- *          isEnabledPrevention:
+ *          isEnabledXss:
  *            type: boolean
  *            description: enable xss
  *          xssOption:
@@ -75,11 +106,18 @@ const validator = {
  *              type: string
  *              description: tag whitelist
  *          attrWhitelist:
- *            type: array
- *            description: array of attr whitelist
- *            items:
- *              type: string
- *              description: attr whitelist
+ *            type: string
+ *            description: attr whitelist
+ *      IndentParams:
+ *        description: IndentParams
+ *        type: object
+ *        properties:
+ *          adminPreferredIndentSize:
+ *            type: number
+ *            description: preferred indent size
+ *          isIndentSizeForced:
+ *            type: boolean
+ *            description: force indent size
  */
 
 /** @param {import('~/server/crowi').default} crowi Crowi instance */
@@ -96,9 +134,10 @@ module.exports = (crowi) => {
    *    /markdown-setting:
    *      get:
    *        tags: [MarkDownSetting]
+   *        security:
+   *          - cookieAuth: []
    *        operationId: getMarkdownSetting
-   *        summary: /markdown-setting
-   *        description: Get markdown parameters
+   *        summary: Get markdown parameters
    *        responses:
    *          200:
    *            description: params of markdown
@@ -109,6 +148,7 @@ module.exports = (crowi) => {
    *                    markdownParams:
    *                      type: object
    *                      description: markdown params
+   *                      $ref: '#/components/schemas/MarkdownParams'
    */
   router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
     const markdownParams = {
@@ -131,9 +171,10 @@ module.exports = (crowi) => {
    *    /markdown-setting/lineBreak:
    *      put:
    *        tags: [MarkDownSetting]
+   *        security:
+   *          - cookieAuth: []
    *        operationId: updateLineBreakMarkdownSetting
-   *        summary: /markdown-setting/lineBreak
-   *        description: Update lineBreak setting
+   *        summary: Update lineBreak setting
    *        requestBody:
    *          required: true
    *          content:
@@ -146,7 +187,11 @@ module.exports = (crowi) => {
    *            content:
    *              application/json:
    *                schema:
-  *                   $ref: '#/components/schemas/LineBreakParams'
+   *                  type: object
+   *                  properties:
+   *                    lineBreaksParams:
+   *                      type: object
+   *                      $ref: '#/components/schemas/LineBreakParams'
    */
   router.put('/lineBreak', loginRequiredStrictly, adminRequired, addActivity, validator.lineBreak, apiV3FormValidator, async(req, res) => {
 
@@ -175,6 +220,35 @@ module.exports = (crowi) => {
 
   });
 
+  /**
+   * @swagger
+   *
+   *    /markdown-setting/indent:
+   *      put:
+   *        tags: [MarkDownSetting]
+   *        security:
+   *          - cookieAuth: []
+   *        operationId: updateIndentMarkdownSetting
+   *        summary: Update indent setting
+   *        requestBody:
+   *          required: true
+   *          content:
+   *            application/json:
+   *              schema:
+   *                $ref: '#/components/schemas/IndentParams'
+   *        responses:
+   *          200:
+   *            description: Succeeded to update indent setting
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  type: object
+   *                  properties:
+   *                    indentParams:
+   *                      type: object
+   *                      description: indent params
+   *                      $ref: '#/components/schemas/IndentParams'
+   */
   router.put('/indent', loginRequiredStrictly, adminRequired, addActivity, validator.indent, apiV3FormValidator, async(req, res) => {
 
     const requestIndentParams = {
@@ -208,8 +282,10 @@ module.exports = (crowi) => {
    *    /markdown-setting/xss:
    *      put:
    *        tags: [MarkDownSetting]
+   *        security:
+   *          - cookieAuth: []
    *        operationId: updateXssMarkdownSetting
-   *        summary: /markdown-setting/xss
+   *        summary: Update XSS setting
    *        description: Update xss
    *        requestBody:
    *          required: true

+ 3 - 0
apps/app/src/server/routes/apiv3/mongo.js

@@ -28,6 +28,9 @@ module.exports = (crowi) => {
    *            application/json:
    *              schema:
    *                properties:
+   *                  ok:
+   *                    type: boolean
+   *                    description: whether the request is succeeded
    *                  collections:
    *                    type: array
    *                    items:

+ 149 - 19
apps/app/src/server/routes/apiv3/notification-setting.js

@@ -47,6 +47,66 @@ const validator = {
  *
  *  components:
  *    schemas:
+ *      NotificationParams:
+ *        type: object
+ *        properties:
+ *          isSlackbotConfigured:
+ *            type: boolean
+ *            description: status of slack integration
+ *          isSlackLegacyConfigured:
+ *            type: boolean
+ *            description: status of slack legacy integration
+ *          currentBotType:
+ *            type: string
+ *            description: current bot type
+ *          userNotifications:
+ *            type: array
+ *            items:
+ *              $ref: '#/components/schemas/UserNotification'
+ *          isNotificationForOwnerPageEnabled:
+ *            type: boolean
+ *            description: Whether to notify on owner page
+ *          isNotificationForGroupPageEnabled:
+ *            type: boolean
+ *            description: Whether to notify on group page
+ *          globalNotifications:
+ *            type: array
+ *            items:
+ *              $ref: '#/components/schemas/GlobalNotificationParams'
+ *            description: global notifications
+ *      UserNotification:
+ *        type: object
+ *        properties:
+ *          channel:
+ *            type: string
+ *            description: slack channel name without '#'
+ *          pathPattern:
+ *            type: string
+ *            description: path name of wiki
+ *          createdAt:
+ *            type: string
+ *            description: created date
+ *          creator:
+ *            $ref: '#/components/schemas/User'
+ *            description: user who set notification
+ *          patternPrefix:
+ *            type: string
+ *            description: path pattern prefix
+ *          patternPrefix2:
+ *            type: string
+ *            description: path pattern prefix2
+ *          provider:
+ *            type: string
+ *            description: provider
+ *          updatedAt:
+ *            type: string
+ *            description: updated date
+ *          __v:
+ *            type: number
+ *            description: version
+ *          _id:
+ *            type: string
+ *            description: id
  *      UserNotificationParams:
  *        type: object
  *        properties:
@@ -60,11 +120,37 @@ const validator = {
  *        type: object
  *        properties:
  *          isNotificationForOwnerPageEnabled:
- *            type: string
+ *            type: boolean
  *            description: Whether to notify on owner page
  *          isNotificationForGroupPageEnabled:
- *            type: string
+ *            type: boolean
  *            description: Whether to notify on group page
+ *      GlobalNotification:
+ *        type: object
+ *        properties:
+ *          _id:
+ *            type: string
+ *            description: id
+ *          isEnabled:
+ *            type: boolean
+ *            description: is notification enabled
+ *          triggerEvents:
+ *            type: array
+ *            items:
+ *              type: string
+ *            description: trigger events for notify
+ *          __t:
+ *            type: string
+ *            description: type of notification
+ *          slackChannels:
+ *            type: string
+ *            description: channels for notify
+ *          triggerPath:
+ *            type: string
+ *            description: trigger path for notify
+ *          __v:
+ *            type: number
+ *            description: version
  *      GlobalNotificationParams:
  *        type: object
  *        properties:
@@ -84,7 +170,7 @@ const validator = {
  *            type: array
  *            items:
  *              type: string
- *              description: trigger events for notify
+ *            description: trigger events for notify
  */
 /** @param {import('~/server/crowi').default} crowi Crowi instance */
 module.exports = (crowi) => {
@@ -105,6 +191,8 @@ module.exports = (crowi) => {
    *    /notification-setting/:
    *      get:
    *        tags: [NotificationSetting]
+   *        security:
+   *          - cookieAuth: []
    *        description: Get notification paramators
    *        responses:
    *          200:
@@ -116,6 +204,7 @@ module.exports = (crowi) => {
    *                    notificationParams:
    *                      type: object
    *                      description: notification params
+   *                      $ref: '#/components/schemas/NotificationParams'
    */
   router.get('/', loginRequiredStrictly, adminRequired, async(req, res) => {
 
@@ -139,6 +228,8 @@ module.exports = (crowi) => {
   *    /notification-setting/user-notification:
   *      post:
   *        tags: [NotificationSetting]
+  *        security:
+  *         - cookieAuth: []
   *        description: add user notification setting
   *        requestBody:
   *          required: true
@@ -153,12 +244,18 @@ module.exports = (crowi) => {
   *              application/json:
   *                schema:
   *                  properties:
-  *                    createdUser:
-  *                      type: object
-  *                      description: user who set notification
-  *                    userNotifications:
+  *                    responseParams:
   *                      type: object
-  *                      description: user trigger notifications for updated
+  *                      description: response params
+  *                      properties:
+  *                        createdUser:
+  *                          $ref: '#/components/schemas/User'
+  *                          description: user who set notification
+  *                        userNotifications:
+  *                          type: array
+  *                          items:
+  *                            $ref: '#/components/schemas/UserNotification'
+  *                            description: user notification settings
   */
   // eslint-disable-next-line max-len
   router.post('/user-notification', loginRequiredStrictly, adminRequired, addActivity, validator.userNotification, apiV3FormValidator, async(req, res) => {
@@ -190,6 +287,8 @@ module.exports = (crowi) => {
    *    /notification-setting/user-notification/{id}:
    *      delete:
    *        tags: [NotificationSetting]
+   *        security:
+   *          - cookieAuth: []
    *        description: delete user trigger notification pattern
    *        parameters:
    *          - name: id
@@ -204,10 +303,7 @@ module.exports = (crowi) => {
    *            content:
    *              application/json:
    *                schema:
-   *                  properties:
-   *                    deletedNotificaton:
-   *                      type: object
-   *                      description: deleted notification
+   *                  $ref: '#/components/schemas/UserNotification'
    */
   router.delete('/user-notification/:id', loginRequiredStrictly, adminRequired, addActivity, async(req, res) => {
     const { id } = req.params;
@@ -230,6 +326,32 @@ module.exports = (crowi) => {
   });
 
 
+  /**
+   * @swagger
+   *
+   *    /notification-setting/global-notification/{id}:
+   *      get:
+   *        tags: [NotificationSetting]
+   *        security:
+   *          - cookieAuth: []
+   *        description: get global notification setting
+   *        parameters:
+   *          - name: id
+   *            in: path
+   *            required: true
+   *            description: id of global notification
+   *            schema:
+   *              type: string
+   *        responses:
+   *          200:
+   *            description: Succeeded to get global notification setting
+   *            content:
+   *              application/json:
+   *                schema:
+   *                  properties:
+   *                    globalNotification:
+   *                      $ref: '#/components/schemas/GlobalNotification'
+   */
   router.get('/global-notification/:id', loginRequiredStrictly, adminRequired, validator.globalNotification, async(req, res) => {
 
     const notificationSettingId = req.params.id;
@@ -253,6 +375,8 @@ module.exports = (crowi) => {
    *    /notification-setting/global-notification:
    *      post:
    *        tags: [NotificationSetting]
+   *        security:
+   *          - cookieAuth: []
    *        description: add global notification
    *        requestBody:
    *          required: true
@@ -270,6 +394,7 @@ module.exports = (crowi) => {
    *                    createdNotification:
    *                      type: object
    *                      description: notification param created
+   *                      $ref: '#/components/schemas/GlobalNotification'
    */
   // eslint-disable-next-line max-len
   router.post('/global-notification', loginRequiredStrictly, adminRequired, addActivity, validator.globalNotification, apiV3FormValidator, async(req, res) => {
@@ -338,6 +463,7 @@ module.exports = (crowi) => {
    *                    createdNotification:
    *                      type: object
    *                      description: notification param updated
+   *                      $ref: '#/components/schemas/GlobalNotification'
    */
   // eslint-disable-next-line max-len
   router.put('/global-notification/:id', loginRequiredStrictly, adminRequired, addActivity, validator.globalNotification, apiV3FormValidator, async(req, res) => {
@@ -400,6 +526,8 @@ module.exports = (crowi) => {
    *    /notification-setting/notify-for-page-grant:
    *      put:
    *        tags: [NotificationSetting]
+   *        security:
+   *          - cookieAuth: []
    *        description: Update settings for notify for page grant
    *        requestBody:
    *          required: true
@@ -451,6 +579,8 @@ module.exports = (crowi) => {
    *    /notification-setting/global-notification/{id}/enabled:
    *      put:
    *        tags: [NotificationSetting]
+   *        security:
+   *          - cookieAuth: []
    *        description: toggle enabled global notification
    *        parameters:
    *          - name: id
@@ -475,9 +605,9 @@ module.exports = (crowi) => {
    *              application/json:
    *                schema:
    *                  properties:
-   *                    deletedNotificaton:
-   *                      type: object
-   *                      description: notification id for updated
+   *                    id:
+   *                      type: string
+   *                      description: notification id
    */
   router.put('/global-notification/:id/enabled', loginRequiredStrictly, adminRequired, addActivity, async(req, res) => {
     const { id } = req.params;
@@ -515,6 +645,8 @@ module.exports = (crowi) => {
   *    /notification-setting/global-notification/{id}:
   *      delete:
   *        tags: [NotificationSetting]
+  *        security:
+  *          - cookieAuth: []
   *        description: delete global notification pattern
   *        parameters:
   *          - name: id
@@ -529,10 +661,8 @@ module.exports = (crowi) => {
   *            content:
   *              application/json:
   *                schema:
-  *                  properties:
-  *                    deletedNotificaton:
-  *                      type: object
-  *                      description: deleted notification
+  *                  description: deleted notification
+  *                  $ref: '#/components/schemas/GlobalNotification'
   */
   router.delete('/global-notification/:id', loginRequiredStrictly, adminRequired, addActivity, async(req, res) => {
     const { id } = req.params;

+ 22 - 2
apps/app/src/server/routes/apiv3/page/index.ts

@@ -340,15 +340,35 @@ module.exports = (crowi) => {
    *                properties:
    *                  body:
    *                    $ref: '#/components/schemas/Revision/properties/body'
-   *                  page_id:
+   *                  pageId:
    *                    $ref: '#/components/schemas/Page/properties/_id'
    *                  revisionId:
    *                    $ref: '#/components/schemas/Revision/properties/_id'
    *                  grant:
    *                    $ref: '#/components/schemas/Page/properties/grant'
+   *                  userRelatedGrantUserGroupIds:
+   *                    type: array
+   *                    items:
+   *                      type: string
+   *                      description: UserGroup ID
+   *                  overwriteScopesOfDescendants:
+   *                    type: boolean
+   *                    description: Determine whether the scopes of descendants should be overwritten
+   *                  isSlackEnabled:
+   *                    type: boolean
+   *                    description: Determine whether the page is enabled to be posted to Slack
+   *                  slackChannels:
+   *                    type: string
+   *                    description: Slack channel IDs
+   *                  origin:
+   *                    type: string
+   *                    description: Origin is "view" or "editor"
+   *                  wip:
+   *                    type: boolean
+   *                    description: Determine whether the page is WIP
    *                required:
    *                  - body
-   *                  - page_id
+   *                  - pageId
    *                  - revisionId
    *        responses:
    *          200:

+ 32 - 20
bin/data-migrations/src/index.js

@@ -5,13 +5,14 @@
 /**
  * @typedef {import('./types').MigrationModule} MigrationModule
  * @typedef {import('./types').ReplaceLatestRevisions} ReplaceLatestRevisions
+ * @typedef {import('./types').Operatioins } Operations
  */
 
 var pagesCollection = db.getCollection('pages');
 var revisionsCollection = db.getCollection('revisions');
 
-var batchSize = process.env.BATCH_SIZE ?? 100; // default 100 revisions in 1 bulkwrite
-var batchSizeInterval = process.env.BATCH_INTERVAL ?? 3000; // default 3 sec
+var batchSize = Number(process.env.BATCH_SIZE ?? 100); // default 100 revisions in 1 bulkwrite
+var batchSizeInterval = Number(process.env.BATCH_INTERVAL ?? 3000); // default 3 sec
 
 var migrationModule = process.env.MIGRATION_MODULE;
 
@@ -31,27 +32,38 @@ function replaceLatestRevisions(body, migrationModules) {
   return replacedBody;
 }
 
+/** @type {Operations} */
 var operations = [];
-pagesCollection.find({}).forEach((doc) => {
+pagesCollection.find({}).forEach((/** @type {any} */ doc) => {
   if (doc.revision) {
-    var revision = revisionsCollection.findOne({ _id: doc.revision });
-    var replacedBody = replaceLatestRevisions(revision.body, [...migrationModules]);
-    var operation = {
-      updateOne: {
-        filter: { _id: revision._id },
-        update: {
-          $set: { body: replacedBody },
+    try {
+      var revision = revisionsCollection.findOne({ _id: doc.revision });
+
+      if (revision == null || revision.body == null) {
+        return;
+      }
+
+      var replacedBody = replaceLatestRevisions(revision.body, [...migrationModules]);
+      var operation = {
+        updateOne: {
+          filter: { _id: revision._id },
+          update: {
+            $set: { body: replacedBody },
+          },
         },
-      },
-    };
-    operations.push(operation);
-
-    // bulkWrite per 100 revisions
-    if (operations.length > (batchSize - 1)) {
-      revisionsCollection.bulkWrite(operations);
-      // sleep time can be set from env var
-      sleep(batchSizeInterval);
-      operations = [];
+      };
+      operations.push(operation);
+
+      // bulkWrite per 100 revisions
+      if (operations.length > (batchSize - 1)) {
+        revisionsCollection.bulkWrite(operations);
+        // sleep time can be set from env var
+        sleep(batchSizeInterval);
+        operations = [];
+      }
+    }
+    catch (err) {
+      print(`Error in updating revision ${doc.revision}: ${err}`);
     }
   }
 });

+ 1 - 1
bin/data-migrations/src/migrations/custom.js

@@ -1,5 +1,5 @@
 /**
- * @typedef {import('../../types').MigrationModule} MigrationModule
+ * @typedef {import('../types').MigrationModule} MigrationModule
  */
 
 module.exports = [

+ 16 - 0
bin/data-migrations/src/types.d.ts

@@ -1,2 +1,18 @@
 export type MigrationModule = (body: string) => string;
 export type ReplaceLatestRevisions = (body: string, migrationModules: MigrationModule[]) => string;
+
+export type Operatioins = Array<
+  {
+    updateOne: {
+      filter: { _id: string }
+      update: { $set: { body: string }}
+    }
+  }
+>
+
+export declare global {
+  const db;
+  const sleep;
+
+  function print(arg: string): void;
+}

+ 8 - 0
bin/data-migrations/tsconfig.json

@@ -0,0 +1,8 @@
+{
+  "$schema": "http://json.schemastore.org/tsconfig",
+  "extends": "../../tsconfig.base.json",
+  "compilerOptions": {
+    "checkJs": true,
+    "strict": true,
+  }
+}

+ 0 - 1
packages/presentation/package.json

@@ -39,7 +39,6 @@
     "lint": "run-p lint:*"
   },
   "dependencies": {
-    "@growi/core": "workspace:^"
   },
   "devDependencies": {
     "@marp-team/marp-core": "^3.9.1",

+ 28 - 0
packages/remark-attachment-refs/turbo.json

@@ -0,0 +1,28 @@
+{
+  "$schema": "https://turbo.build/schema.json",
+  "extends": ["//"],
+  "tasks": {
+    "build": {
+      "dependsOn": ["@growi/core#build", "@growi/remark-growi-directive#build", "@growi/ui#build"],
+      "outputs": ["dist/**"],
+      "outputLogs": "new-only"
+    },
+    "dev": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
+      "outputs": ["dist/**"],
+      "outputLogs": "new-only"
+    },
+    "watch": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
+      "outputs": ["dist/**"],
+      "outputLogs": "new-only"
+    },
+    "lint": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"]
+    },
+    "test": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
+      "outputLogs": "new-only"
+    }
+  }
+}

+ 28 - 0
packages/remark-lsx/turbo.json

@@ -0,0 +1,28 @@
+{
+  "$schema": "https://turbo.build/schema.json",
+  "extends": ["//"],
+  "tasks": {
+    "build": {
+      "dependsOn": ["@growi/core#build", "@growi/remark-growi-directive#build", "@growi/ui#build"],
+      "outputs": ["dist/**"],
+      "outputLogs": "new-only"
+    },
+    "dev": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
+      "outputs": ["dist/**"],
+      "outputLogs": "new-only"
+    },
+    "watch": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
+      "outputs": ["dist/**"],
+      "outputLogs": "new-only"
+    },
+    "lint": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"]
+    },
+    "test": {
+      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
+      "outputLogs": "new-only"
+    }
+  }
+}

+ 2 - 3
pnpm-lock.yaml

@@ -1265,9 +1265,6 @@ importers:
 
   packages/presentation:
     dependencies:
-      '@growi/core':
-        specifier: workspace:^
-        version: link:../core
       next:
         specifier: ^14
         version: 14.2.22(@babel/core@7.24.6)(@opentelemetry/api@1.9.0)(@playwright/test@1.49.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0)(sass@1.77.6)
@@ -8881,6 +8878,7 @@ packages:
 
   lodash.get@4.4.2:
     resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
+    deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
 
   lodash.has@4.5.2:
     resolution: {integrity: sha512-rnYUdIo6xRCJnQmbVFEwcxF144erlD+M3YcJUVesflU9paQaE8p+fJDcIQrlMYbxoANFL+AB9hZrzSBBk5PL+g==}
@@ -8893,6 +8891,7 @@ packages:
 
   lodash.isequal@4.5.0:
     resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==}
+    deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead.
 
   lodash.isfinite@3.3.2:
     resolution: {integrity: sha512-7FGG40uhC8Mm633uKW1r58aElFlBlxCrg9JfSi3P6aYiWmfiWF0PgMd86ZUsxE5GwWPdHoS2+48bwTh2VPkIQA==}

+ 0 - 30
turbo.json

@@ -19,16 +19,6 @@
       "cache": false
     },
 
-    "@growi/remark-attachment-refs#build": {
-      "dependsOn": ["@growi/core#build", "@growi/remark-growi-directive#build", "@growi/ui#build"],
-      "outputs": ["dist/**"],
-      "outputLogs": "new-only"
-    },
-    "@growi/remark-lsx#build": {
-      "dependsOn": ["@growi/core#build", "@growi/remark-growi-directive#build", "@growi/ui#build"],
-      "outputs": ["dist/**"],
-      "outputLogs": "new-only"
-    },
     "@growi/ui#build": {
       "dependsOn": ["@growi/core#build"],
       "outputs": ["dist/**"],
@@ -47,16 +37,6 @@
       "outputLogs": "new-only"
     },
 
-    "@growi/remark-attachment-refs#dev": {
-      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
-      "outputs": ["dist/**"],
-      "outputLogs": "new-only"
-    },
-    "@growi/remark-lsx#dev": {
-      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"],
-      "outputs": ["dist/**"],
-      "outputLogs": "new-only"
-    },
     "@growi/ui#dev": {
       "dependsOn": ["@growi/core#dev"],
       "outputs": ["dist/**"],
@@ -87,12 +67,6 @@
       "persistent": true
     },
 
-    "@growi/remark-attachment-refs#lint": {
-      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"]
-    },
-    "@growi/remark-lsx#lint": {
-      "dependsOn": ["@growi/core#dev", "@growi/remark-growi-directive#dev", "@growi/ui#dev"]
-    },
     "@growi/ui#lint": {
       "dependsOn": ["@growi/core#dev"]
     },
@@ -103,10 +77,6 @@
       "dependsOn": ["@growi/pluginkit#dev"],
       "outputLogs": "new-only"
     },
-    "@growi/remark-lsx#test": {
-      "dependsOn": ["@growi/core#dev"],
-      "outputLogs": "new-only"
-    },
     "test": {
       "outputLogs": "new-only"
     },