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

Merge branch 'master' into feat/enhanced-access-token

Shun Miyazawa 10 месяцев назад
Родитель
Сommit
e6d78133ce

+ 16 - 1
CHANGELOG.md

@@ -1,9 +1,24 @@
 # Changelog
 # Changelog
 
 
-## [Unreleased](https://github.com/weseek/growi/compare/v7.2.6...HEAD)
+## [Unreleased](https://github.com/weseek/growi/compare/v7.2.7...HEAD)
 
 
 *Please do not manually update this file. We've automated the process.*
 *Please do not manually update this file. We've automated the process.*
 
 
+## [v7.2.7](https://github.com/weseek/growi/compare/v7.2.6...v7.2.7) - 2025-06-11
+
+### 🐛 Bug Fixes
+
+* fix: Input values ​​in the admin settings form are sometimes not reflected (#10051) @yuki-takei
+* fix: Hide Google OAuth client secret field (#10049) @yuki-takei
+* fix: Prevent unnecessary API request when the user is guest (#10046) @yuki-takei
+* fix(ai): Prevent unnecessary API request when GROWI AI is disabled (#10044) @yuki-takei
+
+### 🧰 Maintenance
+
+* support: Configure biome for preset-templates package (#10058) @arafubeatbox
+* support: Configure biome for preset-themes package (#10055) @arafubeatbox
+* support: Configure biome for remark-drawio package (#10033) @arafubeatbox
+
 ## [v7.2.6](https://github.com/weseek/growi/compare/v7.2.5...v7.2.6) - 2025-06-10
 ## [v7.2.6](https://github.com/weseek/growi/compare/v7.2.5...v7.2.6) - 2025-06-10
 
 
 ### 💎 Features
 ### 💎 Features

+ 1 - 1
apps/app/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@growi/app",
   "name": "@growi/app",
-  "version": "7.2.7-RC.0",
+  "version": "7.2.8-RC.0",
   "license": "MIT",
   "license": "MIT",
   "private": "true",
   "private": "true",
   "scripts": {
   "scripts": {

+ 0 - 20
apps/app/src/server/models/openapi/v1-response.js

@@ -1,20 +0,0 @@
-/**
- * @swagger
- *
- *  components:
- *    schemas:
- *      V1ResponseOK:
- *        description: API is succeeded
- *        type: boolean
- *      V1Response:
- *        description: Response v1
- *        type: object
- *        properties:
- *          ok:
- *            $ref: '#/components/schemas/V1ResponseOK'
- *    responses:
- *      403:
- *        description: 'Forbidden'
- *      500:
- *        description: 'Internal Server Error'
- */

+ 131 - 0
apps/app/src/server/models/openapi/v1-response.ts

@@ -0,0 +1,131 @@
+/**
+ * @swagger
+ *
+ *  components:
+ *    schemas:
+ *
+ *      # Common API Response Schemas (modern pattern)
+ *      ApiResponseBase:
+ *        type: object
+ *        required:
+ *          - ok
+ *        properties:
+ *          ok:
+ *            type: boolean
+ *            description: Indicates if the request was successful
+ *
+ *      ApiResponseSuccess:
+ *        description: Successful API response
+ *        allOf:
+ *          - $ref: '#/components/schemas/ApiResponseBase'
+ *          - type: object
+ *            properties:
+ *              ok:
+ *                type: boolean
+ *                enum: [true]
+ *                example: true
+ *                description: Success indicator (always true for successful responses)
+ *
+ *      ApiResponseError:
+ *        description: Error API response
+ *        allOf:
+ *          - $ref: '#/components/schemas/ApiResponseBase'
+ *          - type: object
+ *            properties:
+ *              ok:
+ *                type: boolean
+ *                enum: [false]
+ *                example: false
+ *                description: Success indicator (always false for error responses)
+ *              error:
+ *                oneOf:
+ *                  - type: string
+ *                    description: Simple error message
+ *                    example: "Invalid parameter"
+ *                  - type: object
+ *                    description: Detailed error object
+ *                    example: { "code": "VALIDATION_ERROR", "message": "Field validation failed" }
+ *                description: Error message or error object containing details about the failure
+ *
+ *    responses:
+ *      # Common error responses
+ *      BadRequest:
+ *        description: Bad request
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ApiResponseError'
+ *            examples:
+ *              missingParameter:
+ *                summary: Missing required parameter
+ *                value:
+ *                  ok: false
+ *                  error: "Invalid parameter"
+ *              validationError:
+ *                summary: Validation error
+ *                value:
+ *                  ok: false
+ *                  error: "Validation failed"
+ *
+ *      Forbidden:
+ *        description: Forbidden - insufficient permissions
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ApiResponseError'
+ *            example:
+ *              ok: false
+ *              error: "Access denied"
+ *
+ *      NotFound:
+ *        description: Resource not found
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ApiResponseError'
+ *            examples:
+ *              resourceNotFound:
+ *                summary: Resource not found
+ *                value:
+ *                  ok: false
+ *                  error: "Resource not found"
+ *              notFoundOrForbidden:
+ *                summary: Resource not found or forbidden
+ *                value:
+ *                  ok: false
+ *                  error: "notfound_or_forbidden"
+ *
+ *      Conflict:
+ *        description: Conflict
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ApiResponseError'
+ *            examples:
+ *              resourceConflict:
+ *                summary: Resource conflict
+ *                value:
+ *                  ok: false
+ *                  error: "Resource conflict"
+ *              outdated:
+ *                summary: Resource was updated by someone else
+ *                value:
+ *                  ok: false
+ *                  error: "outdated"
+ *              alreadyExists:
+ *                summary: Resource already exists
+ *                value:
+ *                  ok: false
+ *                  error: "already_exists"
+ *
+ *      InternalServerError:
+ *        description: Internal server error
+ *        content:
+ *          application/json:
+ *            schema:
+ *              $ref: '#/components/schemas/ApiResponseError'
+ *            example:
+ *              ok: false
+ *              error: "Internal server error"
+ *
+ */

+ 4 - 4
apps/app/src/server/routes/apiv3/app-settings.js

@@ -893,9 +893,8 @@ module.exports = (crowi) => {
    *                      type: object
    *                      type: object
    *                      $ref: '#/components/schemas/FileUploadSettingParams'
    *                      $ref: '#/components/schemas/FileUploadSettingParams'
    */
    */
-  router.put('/file-upload-setting',
-    accessTokenParser([SCOPE.WRITE.ADMIN.APP]), loginRequiredStrictly, adminRequired,
-    addActivity, validator.fileUploadSetting, apiV3FormValidator, async(req, res) => {
+  router.put('/file-upload-setting', accessTokenParser([SCOPE.WRITE.ADMIN.APP]),
+    loginRequiredStrictly, adminRequired, addActivity, validator.fileUploadSetting, apiV3FormValidator, async(req, res) => {
       const { fileUploadType } = req.body;
       const { fileUploadType } = req.body;
 
 
       if (fileUploadType === 'aws') {
       if (fileUploadType === 'aws') {
@@ -920,7 +919,7 @@ module.exports = (crowi) => {
           },
           },
           { skipPubsub: true });
           { skipPubsub: true });
           await configManager.updateConfigs({
           await configManager.updateConfigs({
-            'app:s3CustomEndpoint': toNonBlankStringOrUndefined(req.body.s3CustomEndpoint),
+            'aws:s3CustomEndpoint': toNonBlankStringOrUndefined(req.body.s3CustomEndpoint),
             'aws:s3AccessKeyId': toNonBlankStringOrUndefined(req.body.s3AccessKeyId),
             'aws:s3AccessKeyId': toNonBlankStringOrUndefined(req.body.s3AccessKeyId),
             'aws:s3SecretAccessKey': toNonBlankStringOrUndefined(req.body.s3SecretAccessKey),
             'aws:s3SecretAccessKey': toNonBlankStringOrUndefined(req.body.s3SecretAccessKey),
           },
           },
@@ -1019,6 +1018,7 @@ module.exports = (crowi) => {
         logger.error('Error', err);
         logger.error('Error', err);
         return res.apiv3Err(new ErrorV3(msg, 'update-fileUploadType-failed'));
         return res.apiv3Err(new ErrorV3(msg, 'update-fileUploadType-failed'));
       }
       }
+
     });
     });
 
 
   /**
   /**

+ 4 - 4
apps/app/src/server/routes/apiv3/attachment.js

@@ -270,9 +270,9 @@ module.exports = (crowi) => {
    *                      description: uploadable
    *                      description: uploadable
    *                      example: true
    *                      example: true
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   router.get('/limit',
   router.get('/limit',
     accessTokenParser([SCOPE.READ.FEATURES.ATTACHMENT], { acceptLegacy: true }), loginRequiredStrictly, validator.retrieveFileLimit, apiV3FormValidator,
     accessTokenParser([SCOPE.READ.FEATURES.ATTACHMENT], { acceptLegacy: true }), loginRequiredStrictly, validator.retrieveFileLimit, apiV3FormValidator,
@@ -338,9 +338,9 @@ module.exports = (crowi) => {
    *                    revision:
    *                    revision:
    *                      type: string
    *                      type: string
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   router.post('/', uploads.single('file'), accessTokenParser([SCOPE.WRITE.FEATURES.ATTACHMENT], { acceptLegacy: true }),
   router.post('/', uploads.single('file'), accessTokenParser([SCOPE.WRITE.FEATURES.ATTACHMENT], { acceptLegacy: true }),
     loginRequiredStrictly, excludeReadOnlyUser, validator.retrieveAddAttachment, apiV3FormValidator, addActivity,
     loginRequiredStrictly, excludeReadOnlyUser, validator.retrieveAddAttachment, apiV3FormValidator, addActivity,

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

@@ -412,9 +412,9 @@ module.exports = (crowi) => {
    *                        revision:
    *                        revision:
    *                          $ref: '#/components/schemas/Revision'
    *                          $ref: '#/components/schemas/Revision'
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   router.put('/', updatePageHandlersFactory(crowi));
   router.put('/', updatePageHandlersFactory(crowi));
 
 

+ 2 - 2
apps/app/src/server/routes/apiv3/users.js

@@ -1229,9 +1229,9 @@ module.exports = (crowi) => {
    *                          $ref: '#/components/schemas/User'
    *                          $ref: '#/components/schemas/User'
    *                        description: user list
    *                        description: user list
    *            403:
    *            403:
-   *              $ref: '#/components/responses/403'
+   *              $ref: '#/components/responses/Forbidden'
    *            500:
    *            500:
-   *              $ref: '#/components/responses/500'
+   *              $ref: '#/components/responses/InternalServerError'
    */
    */
   router.get('/list', accessTokenParser([SCOPE.READ.USER_SETTINGS.INFO], { acceptLegacy: true }), loginRequired, async(req, res) => {
   router.get('/list', accessTokenParser([SCOPE.READ.USER_SETTINGS.INFO], { acceptLegacy: true }), loginRequired, async(req, res) => {
     const userIds = req.query.userIds ?? null;
     const userIds = req.query.userIds ?? null;

+ 15 - 18
apps/app/src/server/routes/attachment/api.js

@@ -1,4 +1,3 @@
-
 import { SupportedAction } from '~/interfaces/activity';
 import { SupportedAction } from '~/interfaces/activity';
 import { AttachmentType } from '~/server/interfaces/attachment';
 import { AttachmentType } from '~/server/interfaces/attachment';
 import loggerFactory from '~/utils/logger';
 import loggerFactory from '~/utils/logger';
@@ -220,15 +219,17 @@ export const routesFactory = (crowi) => {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    attachment:
-   *                      $ref: '#/components/schemas/AttachmentProfile'
+   *                  allOf:
+   *                    - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                    - type: object
+   *                      properties:
+   *                        attachment:
+   *                          $ref: '#/components/schemas/AttachmentProfile'
+   *                          description: The uploaded profile image attachment
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {post} /attachments.uploadProfileImage Add attachment for profile image
    * @api {post} /attachments.uploadProfileImage Add attachment for profile image
@@ -298,13 +299,11 @@ export const routesFactory = (crowi) => {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
+   *                  $ref: '#/components/schemas/ApiResponseSuccess'
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {post} /attachments.remove Remove attachments
    * @api {post} /attachments.remove Remove attachments
@@ -363,13 +362,11 @@ export const routesFactory = (crowi) => {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
+   *                  $ref: '#/components/schemas/ApiResponseSuccess'
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {post} /attachments.removeProfileImage Remove profile image attachments
    * @api {post} /attachments.removeProfileImage Remove profile image attachments

+ 32 - 31
apps/app/src/server/routes/comment.js

@@ -1,4 +1,3 @@
-
 import { getIdStringForRef } from '@growi/core';
 import { getIdStringForRef } from '@growi/core';
 import { serializeUserSecurely } from '@growi/core/dist/models/serializers';
 import { serializeUserSecurely } from '@growi/core/dist/models/serializers';
 
 
@@ -101,17 +100,19 @@ module.exports = function(crowi, app) {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    comments:
-   *                      type: array
-   *                      items:
-   *                        $ref: '#/components/schemas/Comment'
+   *                  allOf:
+   *                    - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                    - type: object
+   *                      properties:
+   *                        comments:
+   *                          type: array
+   *                          items:
+   *                            $ref: '#/components/schemas/Comment'
+   *                          description: List of comments for the page revision
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {get} /comments.get Get comments of the page of the revision
    * @api {get} /comments.get Get comments of the page of the revision
@@ -207,15 +208,17 @@ module.exports = function(crowi, app) {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    comment:
-   *                      $ref: '#/components/schemas/Comment'
+   *                  allOf:
+   *                    - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                    - type: object
+   *                      properties:
+   *                        comment:
+   *                          $ref: '#/components/schemas/Comment'
+   *                          description: The newly created comment
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {post} /comments.add Post comment for the page
    * @api {post} /comments.add Post comment for the page
@@ -353,15 +356,17 @@ module.exports = function(crowi, app) {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    comment:
-   *                      $ref: '#/components/schemas/Comment'
+   *                  allOf:
+   *                    - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                    - type: object
+   *                      properties:
+   *                        comment:
+   *                          $ref: '#/components/schemas/Comment'
+   *                          description: The updated comment
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {post} /comments.update Update comment dody
    * @api {post} /comments.update Update comment dody
@@ -444,15 +449,11 @@ module.exports = function(crowi, app) {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    comment:
-   *                      $ref: '#/components/schemas/Comment'
+   *                  $ref: '#/components/schemas/ApiResponseSuccess'
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {post} /comments.remove Remove specified comment
    * @api {post} /comments.remove Remove specified comment

+ 331 - 117
apps/app/src/server/routes/page.js

@@ -14,54 +14,6 @@ import UpdatePost from '../models/update-post';
  *    name: Pages
  *    name: Pages
  */
  */
 
 
-/**
- * @swagger
- *
- *  components:
- *    schemas:
- *
- *      UpdatePost:
- *        description: UpdatePost
- *        type: object
- *        properties:
- *          _id:
- *            type: string
- *            description: update post ID
- *            example: 5e0734e472560e001761fa68
- *          __v:
- *            type: number
- *            description: DB record version
- *            example: 0
- *          pathPattern:
- *            type: string
- *            description: path pattern
- *            example: /test
- *          patternPrefix:
- *            type: string
- *            description: patternPrefix prefix
- *            example: /
- *          patternPrefix2:
- *            type: string
- *            description: path
- *            example: test
- *          channel:
- *            type: string
- *            description: channel
- *            example: general
- *          provider:
- *            type: string
- *            description: provider
- *            enum:
- *              - slack
- *            example: slack
- *          creator:
- *            $ref: '#/components/schemas/User'
- *          createdAt:
- *            type: string
- *            description: date created at
- *            example: 2010-01-01T00:00:00.000Z
- */
-
 /* eslint-disable no-use-before-define */
 /* eslint-disable no-use-before-define */
 /** @param {import('~/server/crowi').default} crowi Crowi instance */
 /** @param {import('~/server/crowi').default} crowi Crowi instance */
 module.exports = function(crowi, app) {
 module.exports = function(crowi, app) {
@@ -134,37 +86,57 @@ module.exports = function(crowi, app) {
   const validator = {};
   const validator = {};
 
 
   actions.api = api;
   actions.api = api;
-  actions.validator = validator;
-
-  /**
+  actions.validator = validator; /**
    * @swagger
    * @swagger
    *
    *
-   *    /pages.getPageTag:
-   *      get:
-   *        tags: [Pages]
-   *        operationId: getPageTag
-   *        summary: /pages.getPageTag
-   *        description: Get page tag
-   *        parameters:
-   *          - in: query
-   *            name: pageId
-   *            schema:
-   *              $ref: '#/components/schemas/ObjectId'
-   *        responses:
-   *          200:
-   *            description: Succeeded to get page tags.
-   *            content:
-   *              application/json:
-   *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    tags:
-   *                      $ref: '#/components/schemas/Tags'
-   *          403:
-   *            $ref: '#/components/responses/403'
-   *          500:
-   *            $ref: '#/components/responses/500'
+   * components:
+   *   schemas:
+   *     PageTagsData:
+   *       type: object
+   *       properties:
+   *         tags:
+   *           type: array
+   *           items:
+   *             type: string
+   *           description: Array of tag names associated with the page
+   *           example: ["javascript", "tutorial", "backend"]
+   *
+   *   responses:
+   *     PageTagsSuccess:
+   *       description: Successfully retrieved page tags
+   *       content:
+   *         application/json:
+   *           schema:
+   *             allOf:
+   *               - $ref: '#/components/schemas/ApiResponseSuccess'
+   *               - $ref: '#/components/schemas/PageTagsData'
+   *
+   * /pages.getPageTag:
+   *   get:
+   *     tags: [Pages]
+   *     operationId: getPageTag
+   *     summary: Get page tags
+   *     description: Retrieve all tags associated with a specific page
+   *     parameters:
+   *       - in: query
+   *         name: pageId
+   *         required: true
+   *         description: Unique identifier of the page
+   *         schema:
+   *           type: string
+   *           format: ObjectId
+   *           example: "507f1f77bcf86cd799439011"
+   *     responses:
+   *       200:
+   *         $ref: '#/components/responses/PageTagsSuccess'
+   *       400:
+   *         $ref: '#/components/responses/BadRequest'
+   *       403:
+   *         $ref: '#/components/responses/Forbidden'
+   *       404:
+   *         $ref: '#/components/responses/NotFound'
+   *       500:
+   *         $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {get} /pages.getPageTag get page tags
    * @api {get} /pages.getPageTag get page tags
@@ -187,32 +159,58 @@ module.exports = function(crowi, app) {
   /**
   /**
    * @swagger
    * @swagger
    *
    *
-   *    /pages.updatePost:
-   *      get:
-   *        tags: [Pages]
-   *        operationId: getUpdatePostPage
-   *        summary: /pages.updatePost
-   *        description: Get UpdatePost setting list
-   *        parameters:
-   *          - in: query
-   *            name: path
-   *            schema:
-   *              $ref: '#/components/schemas/PagePath'
-   *        responses:
-   *          200:
-   *            description: Succeeded to get UpdatePost setting list.
-   *            content:
-   *              application/json:
-   *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    updatePost:
-   *                      $ref: '#/components/schemas/UpdatePost'
-   *          403:
-   *            $ref: '#/components/responses/403'
-   *          500:
-   *            $ref: '#/components/responses/500'
+   * components:
+   *   schemas:
+   *     UpdatePostData:
+   *       type: object
+   *       properties:
+   *         updatePost:
+   *           type: array
+   *           items:
+   *             type: string
+   *           description: Array of channel names for notifications
+   *           example: ["general", "development", "notifications"]
+   *
+   *   responses:
+   *     UpdatePostSuccess:
+   *       description: Successfully retrieved UpdatePost settings
+   *       content:
+   *         application/json:
+   *           schema:
+   *             allOf:
+   *               - $ref: '#/components/schemas/ApiResponseSuccess'
+   *               - $ref: '#/components/schemas/UpdatePostData'
+   *
+   * /pages.updatePost:
+   *   get:
+   *     tags: [Pages]
+   *     operationId: getUpdatePost
+   *     summary: Get UpdatePost settings
+   *     description: Retrieve UpdatePost notification settings for a specific path
+   *     parameters:
+   *       - in: query
+   *         name: path
+   *         required: true
+   *         description: Page path to get UpdatePost settings for
+   *         schema:
+   *           type: string
+   *           example: "/user/example"
+   *         examples:
+   *           userPage:
+   *             value: "/user/john"
+   *             description: User page path
+   *           projectPage:
+   *             value: "/project/myproject"
+   *             description: Project page path
+   *     responses:
+   *       200:
+   *         $ref: '#/components/responses/UpdatePostSuccess'
+   *       400:
+   *         $ref: '#/components/responses/BadRequest'
+   *       403:
+   *         $ref: '#/components/responses/Forbidden'
+   *       500:
+   *         $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {get} /pages.updatePost
    * @api {get} /pages.updatePost
@@ -254,12 +252,101 @@ module.exports = function(crowi, app) {
   ];
   ];
 
 
   /**
   /**
-   * @api {post} /pages.remove Remove page
-   * @apiName RemovePage
-   * @apiGroup Page
+   * @swagger
+   *
+   * components:
+   *   schemas:
+   *     PageRemoveData:
+   *       type: object
+   *       properties:
+   *         path:
+   *           type: string
+   *           required: true
+   *           description: Path of the deleted page
+   *           example: "/user/example"
+   *         isRecursively:
+   *           type: boolean
+   *           description: Whether deletion was recursive
+   *           example: true
+   *         isCompletely:
+   *           type: boolean
+   *           description: Whether deletion was complete
+   *           example: false
+   *
+   *   responses:
+   *     PageRemoveSuccess:
+   *       description: Page successfully deleted
+   *       content:
+   *         application/json:
+   *           schema:
+   *             allOf:
+   *               - $ref: '#/components/schemas/ApiResponseSuccess'
+   *               - $ref: '#/components/schemas/PageRemoveData'
    *
    *
-   * @apiParam {String} page_id Page Id.
-   * @apiParam {String} revision_id
+   * /pages.remove:
+   *   post:
+   *     tags: [Pages]
+   *     operationId: removePage
+   *     summary: Remove page
+   *     description: Delete a page either softly or completely, with optional recursive deletion
+   *     requestBody:
+   *       required: true
+   *       content:
+   *         application/json:
+   *           schema:
+   *             type: object
+   *             required:
+   *               - page_id
+   *             properties:
+   *               page_id:
+   *                 type: string
+   *                 format: ObjectId
+   *                 description: Unique identifier of the page to delete
+   *                 example: "507f1f77bcf86cd799439011"
+   *               revision_id:
+   *                 type: string
+   *                 format: ObjectId
+   *                 description: Revision ID for conflict detection
+   *                 example: "507f1f77bcf86cd799439012"
+   *               completely:
+   *                 type: boolean
+   *                 description: Whether to delete the page completely (true) or soft delete (false)
+   *                 default: false
+   *                 example: false
+   *               recursively:
+   *                 type: boolean
+   *                 description: Whether to delete child pages recursively
+   *                 default: false
+   *                 example: true
+   *           examples:
+   *             softDelete:
+   *               summary: Soft delete single page
+   *               value:
+   *                 page_id: "507f1f77bcf86cd799439011"
+   *                 revision_id: "507f1f77bcf86cd799439012"
+   *             recursiveDelete:
+   *               summary: Recursive soft delete
+   *               value:
+   *                 page_id: "507f1f77bcf86cd799439011"
+   *                 recursively: true
+   *             completeDelete:
+   *               summary: Complete deletion
+   *               value:
+   *                 page_id: "507f1f77bcf86cd799439011"
+   *                 completely: true
+   *     responses:
+   *       200:
+   *         $ref: '#/components/responses/PageRemoveSuccess'
+   *       400:
+   *         $ref: '#/components/responses/BadRequest'
+   *       403:
+   *         $ref: '#/components/responses/Forbidden'
+   *       404:
+   *         $ref: '#/components/responses/NotFound'
+   *       409:
+   *         $ref: '#/components/responses/Conflict'
+   *       500:
+   *         $ref: '#/components/responses/InternalServerError'
    */
    */
   api.remove = async function(req, res) {
   api.remove = async function(req, res) {
     const pageId = req.body.page_id;
     const pageId = req.body.page_id;
@@ -365,11 +452,89 @@ module.exports = function(crowi, app) {
   ];
   ];
 
 
   /**
   /**
-   * @api {post} /pages.revertRemove Revert removed page
-   * @apiName RevertRemovePage
-   * @apiGroup Page
+   * @swagger
+   *
+   * components:
+   *   schemas:
+   *     PageRevertData:
+   *       type: object
+   *       properties:
+   *         page:
+   *           type: object
+   *           description: Restored page object
+   *           properties:
+   *             _id:
+   *               type: string
+   *               format: ObjectId
+   *               example: "507f1f77bcf86cd799439011"
+   *             path:
+   *               type: string
+   *               example: "/user/example"
+   *             title:
+   *               type: string
+   *               example: "Example Page"
+   *             status:
+   *               type: string
+   *               example: "published"
    *
    *
-   * @apiParam {String} page_id Page Id.
+   *   responses:
+   *     PageRevertSuccess:
+   *       description: Page successfully restored
+   *       content:
+   *         application/json:
+   *           schema:
+   *             allOf:
+   *               - $ref: '#/components/schemas/ApiResponseSuccess'
+   *               - $ref: '#/components/schemas/PageRevertData'
+   *
+   * /pages.revertRemove:
+   *   post:
+   *     tags: [Pages]
+   *     operationId: revertRemovePage
+   *     summary: Revert removed page
+   *     description: Restore a previously deleted (soft-deleted) page
+   *     requestBody:
+   *       required: true
+   *       content:
+   *         application/json:
+   *           schema:
+   *             type: object
+   *             required:
+   *               - page_id
+   *             properties:
+   *               page_id:
+   *                 type: string
+   *                 format: ObjectId
+   *                 description: Unique identifier of the page to restore
+   *                 example: "507f1f77bcf86cd799439011"
+   *               recursively:
+   *                 type: boolean
+   *                 description: Whether to restore child pages recursively
+   *                 default: false
+   *                 example: true
+   *           examples:
+   *             singleRevert:
+   *               summary: Revert single page
+   *               value:
+   *                 page_id: "507f1f77bcf86cd799439011"
+   *             recursiveRevert:
+   *               summary: Revert page and children
+   *               value:
+   *                 page_id: "507f1f77bcf86cd799439011"
+   *                 recursively: true
+   *     responses:
+   *       200:
+   *         $ref: '#/components/responses/PageRevertSuccess'
+   *       400:
+   *         $ref: '#/components/responses/BadRequest'
+   *       403:
+   *         $ref: '#/components/responses/Forbidden'
+   *       404:
+   *         $ref: '#/components/responses/NotFound'
+   *       409:
+   *         $ref: '#/components/responses/Conflict'
+   *       500:
+   *         $ref: '#/components/responses/InternalServerError'
    */
    */
   api.revertRemove = async function(req, res, options) {
   api.revertRemove = async function(req, res, options) {
     const pageId = req.body.page_id;
     const pageId = req.body.page_id;
@@ -406,12 +571,61 @@ module.exports = function(crowi, app) {
   };
   };
 
 
   /**
   /**
-   * @api {post} /pages.unlink Remove the redirecting page
-   * @apiName UnlinkPage
-   * @apiGroup Page
+   * @swagger
+   *
+   * components:
+   *   schemas:
+   *     PageUnlinkData:
+   *       type: object
+   *       properties:
+   *         path:
+   *           type: string
+   *           description: Path for which redirects were removed
+   *           example: "/user/example"
+   *
+   *   responses:
+   *     PageUnlinkSuccess:
+   *       description: Successfully removed page redirects
+   *       content:
+   *         application/json:
+   *           schema:
+   *             allOf:
+   *               - $ref: '#/components/schemas/ApiResponseSuccess'
+   *               - $ref: '#/components/schemas/PageUnlinkData'
    *
    *
-   * @apiParam {String} page_id Page Id.
-   * @apiParam {String} revision_id
+   * /pages.unlink:
+   *   post:
+   *     tags: [Pages]
+   *     operationId: unlinkPage
+   *     summary: Remove page redirects
+   *     description: Remove all redirect entries that point to the specified page path
+   *     requestBody:
+   *       required: true
+   *       content:
+   *         application/json:
+   *           schema:
+   *             type: object
+   *             required:
+   *               - path
+   *             properties:
+   *               path:
+   *                 type: string
+   *                 description: Target path to remove redirects for
+   *                 example: "/user/example"
+   *           examples:
+   *             unlinkPage:
+   *               summary: Remove redirects to a page
+   *               value:
+   *                 path: "/user/example"
+   *     responses:
+   *       200:
+   *         $ref: '#/components/responses/PageUnlinkSuccess'
+   *       400:
+   *         $ref: '#/components/responses/BadRequest'
+   *       403:
+   *         $ref: '#/components/responses/Forbidden'
+   *       500:
+   *         $ref: '#/components/responses/InternalServerError'
    */
    */
   api.unlink = async function(req, res) {
   api.unlink = async function(req, res) {
     const path = req.body.path;
     const path = req.body.path;

+ 18 - 16
apps/app/src/server/routes/search.ts

@@ -79,24 +79,26 @@ module.exports = function(crowi: Crowi, app) {
    *           content:
    *           content:
    *             application/json:
    *             application/json:
    *               schema:
    *               schema:
-   *                 properties:
-   *                   ok:
-   *                     $ref: '#/components/schemas/V1ResponseOK'
-   *                   meta:
-   *                     $ref: '#/components/schemas/ElasticsearchResultMeta'
-   *                   totalCount:
-   *                     type: integer
-   *                     description: total count of pages
-   *                     example: 35
-   *                   data:
-   *                     type: array
-   *                     items:
-   *                       $ref: '#/components/schemas/Page'
-   *                     description: page list
+   *                 allOf:
+   *                   - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                   - type: object
+   *                     properties:
+   *                       meta:
+   *                         $ref: '#/components/schemas/ElasticsearchResultMeta'
+   *                         description: Elasticsearch metadata
+   *                       totalCount:
+   *                         type: integer
+   *                         description: total count of pages
+   *                         example: 35
+   *                       data:
+   *                         type: array
+   *                         items:
+   *                           $ref: '#/components/schemas/Page'
+   *                         description: page list
    *         403:
    *         403:
-   *           $ref: '#/components/responses/403'
+   *           $ref: '#/components/responses/Forbidden'
    *         500:
    *         500:
-   *           $ref: '#/components/responses/500'
+   *           $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {get} /search search page
    * @api {get} /search search page

+ 29 - 23
apps/app/src/server/routes/tag.js

@@ -37,15 +37,17 @@ module.exports = function(crowi, app) {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    tags:
-   *                      $ref: '#/components/schemas/Tags'
+   *                  allOf:
+   *                    - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                    - type: object
+   *                      properties:
+   *                        tags:
+   *                          $ref: '#/components/schemas/Tags'
+   *                          description: List of matching tags
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {get} /tags.search search tags
    * @api {get} /tags.search search tags
@@ -91,15 +93,17 @@ module.exports = function(crowi, app) {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    tags:
-   *                      $ref: '#/components/schemas/Tags'
+   *                  allOf:
+   *                    - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                    - type: object
+   *                      properties:
+   *                        tags:
+   *                          $ref: '#/components/schemas/Tags'
+   *                          description: Updated tags for the page
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {post} /tags.update update tags on view-mode (not edit-mode)
    * @api {post} /tags.update update tags on view-mode (not edit-mode)
@@ -168,17 +172,19 @@ module.exports = function(crowi, app) {
    *            content:
    *            content:
    *              application/json:
    *              application/json:
    *                schema:
    *                schema:
-   *                  properties:
-   *                    ok:
-   *                      $ref: '#/components/schemas/V1ResponseOK'
-   *                    data:
-   *                      type: array
-   *                      items:
-   *                        $ref: '#/components/schemas/Tag'
+   *                  allOf:
+   *                    - $ref: '#/components/schemas/ApiResponseSuccess'
+   *                    - type: object
+   *                      properties:
+   *                        data:
+   *                          type: array
+   *                          items:
+   *                            $ref: '#/components/schemas/Tag'
+   *                          description: List of tags with count information
    *          403:
    *          403:
-   *            $ref: '#/components/responses/403'
+   *            $ref: '#/components/responses/Forbidden'
    *          500:
    *          500:
-   *            $ref: '#/components/responses/500'
+   *            $ref: '#/components/responses/InternalServerError'
    */
    */
   /**
   /**
    * @api {get} /tags.list get tagnames and count pages relate each tag
    * @api {get} /tags.list get tagnames and count pages relate each tag

+ 1 - 1
apps/slackbot-proxy/package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "@growi/slackbot-proxy",
   "name": "@growi/slackbot-proxy",
-  "version": "7.2.7-slackbot-proxy.0",
+  "version": "7.2.8-slackbot-proxy.0",
   "license": "MIT",
   "license": "MIT",
   "private": "true",
   "private": "true",
   "scripts": {
   "scripts": {

+ 0 - 2
biome.json

@@ -26,8 +26,6 @@
       "./packages/pdf-converter-client/**",
       "./packages/pdf-converter-client/**",
       "./packages/pluginkit/**",
       "./packages/pluginkit/**",
       "./packages/presentation/**",
       "./packages/presentation/**",
-      "./packages/preset-templates/**",
-      "./packages/preset-themes/**",
       "./packages/remark-attachment-refs/**"
       "./packages/remark-attachment-refs/**"
     ]
     ]
   },
   },

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
 {
   "name": "growi",
   "name": "growi",
-  "version": "7.2.7-RC.0",
+  "version": "7.2.8-RC.0",
   "description": "Team collaboration software using markdown",
   "description": "Team collaboration software using markdown",
   "license": "MIT",
   "license": "MIT",
   "private": "true",
   "private": "true",

+ 1 - 0
packages/preset-templates/.eslintignore

@@ -0,0 +1 @@
+*

+ 0 - 5
packages/preset-templates/.eslintrc.js

@@ -1,5 +0,0 @@
-module.exports = {
-  extends: [
-    'plugin:vitest/recommended',
-  ],
-};

+ 2 - 1
packages/preset-templates/package.json

@@ -5,7 +5,8 @@
   "license": "MIT",
   "license": "MIT",
   "private": "true",
   "private": "true",
   "scripts": {
   "scripts": {
-    "test": "vitest run"
+    "test": "vitest run",
+    "lint": "biome check"
   },
   },
   "dependencies": {},
   "dependencies": {},
   "devDependencies": {
   "devDependencies": {

+ 7 - 8
packages/preset-templates/test/index.test.ts

@@ -1,13 +1,14 @@
 import path from 'node:path';
 import path from 'node:path';
 
 
-import { scanAllTemplates, validateTemplatePluginGrowiDirective, validateAllTemplateLocales } from '@growi/pluginkit/dist/v4/server';
-
+import {
+  scanAllTemplates,
+  validateAllTemplateLocales,
+  validateTemplatePluginGrowiDirective,
+} from '@growi/pluginkit/dist/v4/server';
 
 
 const projectDirRoot = path.resolve(__dirname, '../');
 const projectDirRoot = path.resolve(__dirname, '../');
 
 
-
 it('Validation for package.json should be passed', () => {
 it('Validation for package.json should be passed', () => {
-
   // when
   // when
   const caller = () => validateTemplatePluginGrowiDirective(projectDirRoot);
   const caller = () => validateTemplatePluginGrowiDirective(projectDirRoot);
 
 
@@ -16,7 +17,6 @@ it('Validation for package.json should be passed', () => {
 });
 });
 
 
 it('Validation for package.json should be return data', () => {
 it('Validation for package.json should be return data', () => {
-
   // when
   // when
   const data = validateTemplatePluginGrowiDirective(projectDirRoot);
   const data = validateTemplatePluginGrowiDirective(projectDirRoot);
 
 
@@ -24,7 +24,7 @@ it('Validation for package.json should be return data', () => {
   expect(data).not.toBeNull();
   expect(data).not.toBeNull();
 });
 });
 
 
-it('Scanning the templates ends up with no errors', async() => {
+it('Scanning the templates ends up with no errors', async () => {
   // when
   // when
   const results = await scanAllTemplates(projectDirRoot);
   const results = await scanAllTemplates(projectDirRoot);
 
 
@@ -32,8 +32,7 @@ it('Scanning the templates ends up with no errors', async() => {
   expect(results).not.toBeNull();
   expect(results).not.toBeNull();
 });
 });
 
 
-it('Scanning the templates ends up with no errors with opts.data', async() => {
-
+it('Scanning the templates ends up with no errors with opts.data', async () => {
   // setup
   // setup
   const data = validateTemplatePluginGrowiDirective(projectDirRoot);
   const data = validateTemplatePluginGrowiDirective(projectDirRoot);
 
 

+ 1 - 3
packages/preset-templates/tsconfig.json

@@ -3,8 +3,6 @@
   "compilerOptions": {
   "compilerOptions": {
     "esModuleInterop": true,
     "esModuleInterop": true,
     "resolveJsonModule": true,
     "resolveJsonModule": true,
-    "types": [
-      "vitest/globals"
-    ]
+    "types": ["vitest/globals"]
   }
   }
 }
 }

+ 1 - 1
packages/preset-themes/.eslintignore

@@ -1 +1 @@
-/dist/**
+*

+ 0 - 2
packages/preset-themes/.eslintrc.js

@@ -1,2 +0,0 @@
-module.exports = {
-};

+ 1 - 1
packages/preset-themes/package.json

@@ -21,7 +21,7 @@
     "watch": "run-p watch:*",
     "watch": "run-p watch:*",
     "watch:libs": "pnpm run dev:libs -w --emptyOutDir=false",
     "watch:libs": "pnpm run dev:libs -w --emptyOutDir=false",
     "watch:themes": "pnpm run dev:themes -w --emptyOutDir=false",
     "watch:themes": "pnpm run dev:themes -w --emptyOutDir=false",
-    "lint:eslint": "eslint \"**/*.{js,jsx,ts,tsx}\"",
+    "lint:biome": "biome check",
     "lint:styles": "stylelint \"src/**/*.scss\"",
     "lint:styles": "stylelint \"src/**/*.scss\"",
     "lint:typecheck": "vue-tsc --noEmit",
     "lint:typecheck": "vue-tsc --noEmit",
     "lint": "run-p lint:*",
     "lint": "run-p lint:*",

+ 21 - 11
packages/preset-themes/src/consts/preset-themes.ts

@@ -21,7 +21,7 @@ export const PresetThemes = {
   WOOD: 'wood',
   WOOD: 'wood',
   CLASSIC: 'classic',
   CLASSIC: 'classic',
 } as const;
 } as const;
-export type PresetThemes = typeof PresetThemes[keyof typeof PresetThemes];
+export type PresetThemes = (typeof PresetThemes)[keyof typeof PresetThemes];
 
 
 /* eslint-disable no-multi-spaces, */
 /* eslint-disable no-multi-spaces, */
 
 
@@ -74,7 +74,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#94351E',
     lightIcon: '#94351E',
     darkIcon: '#EE775B',
     darkIcon: '#EE775B',
     createBtn: '#EA5532',
     createBtn: '#EA5532',
-  }, {
+  },
+  {
     name: PresetThemes.JADE_GREEN,
     name: PresetThemes.JADE_GREEN,
     schemeType: BOTH,
     schemeType: BOTH,
     lightBg: '#FFFFFF',
     lightBg: '#FFFFFF',
@@ -84,7 +85,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#3A8F6F',
     lightIcon: '#3A8F6F',
     darkIcon: '#5FC2A2',
     darkIcon: '#5FC2A2',
     createBtn: '#49B38A',
     createBtn: '#49B38A',
-  }, {
+  },
+  {
     name: PresetThemes.CLASSIC,
     name: PresetThemes.CLASSIC,
     schemeType: BOTH,
     schemeType: BOTH,
     lightBg: '#FFFFFF',
     lightBg: '#FFFFFF',
@@ -94,7 +96,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#53687E',
     lightIcon: '#53687E',
     darkIcon: '#869BB1',
     darkIcon: '#869BB1',
     createBtn: '#3491CB',
     createBtn: '#3491CB',
-  }, {
+  },
+  {
     name: PresetThemes.CHRISTMAS,
     name: PresetThemes.CHRISTMAS,
     schemeType: BOTH,
     schemeType: BOTH,
     lightBg: '#FFFFFF',
     lightBg: '#FFFFFF',
@@ -116,7 +119,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#3F8421',
     lightIcon: '#3F8421',
     darkIcon: '#1F4210',
     darkIcon: '#1F4210',
     createBtn: '#4FA529',
     createBtn: '#4FA529',
-  }, {
+  },
+  {
     name: PresetThemes.WOOD,
     name: PresetThemes.WOOD,
     schemeType: LIGHT,
     schemeType: LIGHT,
     lightBg: '#FFFFF5',
     lightBg: '#FFFFF5',
@@ -126,7 +130,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#86651A',
     lightIcon: '#86651A',
     darkIcon: '#43320D',
     darkIcon: '#43320D',
     createBtn: '#A77E21',
     createBtn: '#A77E21',
-  }, {
+  },
+  {
     name: PresetThemes.ISLAND,
     name: PresetThemes.ISLAND,
     schemeType: LIGHT,
     schemeType: LIGHT,
     lightBg: '#FFFFFF',
     lightBg: '#FFFFFF',
@@ -136,7 +141,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#51C2D3',
     lightIcon: '#51C2D3',
     darkIcon: '#204D54',
     darkIcon: '#204D54',
     createBtn: '#51C2D3',
     createBtn: '#51C2D3',
-  }, {
+  },
+  {
     name: PresetThemes.ANTARCTIC,
     name: PresetThemes.ANTARCTIC,
     schemeType: LIGHT,
     schemeType: LIGHT,
     lightBg: '#FAFEFF',
     lightBg: '#FAFEFF',
@@ -146,7 +152,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#2631AF',
     lightIcon: '#2631AF',
     darkIcon: '#131857',
     darkIcon: '#131857',
     createBtn: '#303DDB',
     createBtn: '#303DDB',
-  }, {
+  },
+  {
     name: PresetThemes.SPRING,
     name: PresetThemes.SPRING,
     schemeType: LIGHT,
     schemeType: LIGHT,
     lightBg: '#FFFFFF',
     lightBg: '#FFFFFF',
@@ -156,7 +163,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#D76F7D',
     lightIcon: '#D76F7D',
     darkIcon: '#8A423F',
     darkIcon: '#8A423F',
     createBtn: '#6ABA55',
     createBtn: '#6ABA55',
-  }, {
+  },
+  {
     name: PresetThemes.KIBELA,
     name: PresetThemes.KIBELA,
     schemeType: LIGHT,
     schemeType: LIGHT,
     lightBg: '#FFFFFF',
     lightBg: '#FFFFFF',
@@ -178,7 +186,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#3F999B',
     lightIcon: '#3F999B',
     darkIcon: '#99E5E6',
     darkIcon: '#99E5E6',
     createBtn: '#03A2A8',
     createBtn: '#03A2A8',
-  }, {
+  },
+  {
     name: PresetThemes.HALLOWEEN,
     name: PresetThemes.HALLOWEEN,
     schemeType: DARK,
     schemeType: DARK,
     lightBg: '#240E3E',
     lightBg: '#240E3E',
@@ -188,7 +197,8 @@ export const PresetThemesMetadatas: GrowiThemeMetadata[] = [
     lightIcon: '#8C3C03',
     lightIcon: '#8C3C03',
     darkIcon: '#DDB69B',
     darkIcon: '#DDB69B',
     createBtn: '#AA4A04',
     createBtn: '#AA4A04',
-  }, {
+  },
+  {
     name: PresetThemes.BLACKBOARD,
     name: PresetThemes.BLACKBOARD,
     schemeType: DARK,
     schemeType: DARK,
     lightBg: '#223323',
     lightBg: '#223323',

+ 2 - 5
packages/preset-themes/tsconfig.json

@@ -1,9 +1,6 @@
 {
 {
   "$schema": "http://json.schemastore.org/tsconfig",
   "$schema": "http://json.schemastore.org/tsconfig",
   "extends": "../../tsconfig.base.json",
   "extends": "../../tsconfig.base.json",
-  "compilerOptions": {
-  },
-  "include": [
-    "src"
-  ]
+  "compilerOptions": {},
+  "include": ["src"]
 }
 }

+ 2 - 5
packages/preset-themes/vite.libs.config.ts

@@ -3,9 +3,7 @@ import dts from 'vite-plugin-dts';
 
 
 // https://vitejs.dev/config/
 // https://vitejs.dev/config/
 export default defineConfig({
 export default defineConfig({
-  plugins: [
-    dts({ copyDtsFiles: true }),
-  ],
+  plugins: [dts({ copyDtsFiles: true })],
   build: {
   build: {
     outDir: 'dist/libs',
     outDir: 'dist/libs',
     sourcemap: true,
     sourcemap: true,
@@ -16,8 +14,7 @@ export default defineConfig({
       formats: ['es', 'umd'],
       formats: ['es', 'umd'],
     },
     },
     rollupOptions: {
     rollupOptions: {
-      external: [
-      ],
+      external: [],
     },
     },
   },
   },
 });
 });

+ 1 - 3
packages/preset-themes/vite.themes.config.ts

@@ -28,9 +28,7 @@ export default defineConfig(({ mode }) => {
           '/src/styles/classic.scss',
           '/src/styles/classic.scss',
         ],
         ],
         output: {
         output: {
-          assetFileNames: isProd
-            ? undefined
-            : 'assets/[name].[ext]', // not attach hash
+          assetFileNames: isProd ? undefined : 'assets/[name].[ext]', // not attach hash
         },
         },
       },
       },
     },
     },