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

Merge pull request #8961 from weseek/fix/healthcheck

fix: Healthcheck with checkServices=mongo
Yuki Takei 1 год назад
Родитель
Сommit
60cb3d92c9
27 измененных файлов с 81 добавлено и 91 удалено
  1. 2 2
      apps/app/package.json
  2. 6 4
      apps/app/src/features/questionnaire/server/service/questionnaire.ts
  3. 1 1
      apps/app/src/migrations/20180927102719-init-serverurl.js
  4. 1 1
      apps/app/src/migrations/20190618055300-abolish-crowi-classic-auth.js
  5. 1 1
      apps/app/src/migrations/20190618104011-add-config-app-installed.js
  6. 1 1
      apps/app/src/migrations/20200420160390-remove-crowi-layout.js
  7. 1 1
      apps/app/src/migrations/20200512005851-remove-behavior-type.js
  8. 1 1
      apps/app/src/migrations/20200514001356-update-theme-color-for-dark.js
  9. 1 1
      apps/app/src/migrations/20200620203632-normalize-locale-id.js
  10. 1 1
      apps/app/src/migrations/20200827045151-remove-layout-setting.js
  11. 1 1
      apps/app/src/migrations/20200828024025-copy-aws-setting.js
  12. 1 1
      apps/app/src/migrations/20200901034313-update-mail-transmission.js
  13. 1 1
      apps/app/src/migrations/20200903080025-remove-timeline-type.js.js
  14. 1 1
      apps/app/src/migrations/20200915035234-rename-s3-config.js
  15. 1 1
      apps/app/src/migrations/20210830074539-update-configs-for-slackbot.js
  16. 1 1
      apps/app/src/migrations/20211005131430-config-without-proxy-command-permission-for-renaming.js
  17. 2 3
      apps/app/src/migrations/20220311011114-convert-page-delete-config.js
  18. 1 1
      apps/app/src/migrations/20221014130200-remove-customize-is-saved-states-of-tab-changes.js
  19. 1 1
      apps/app/src/migrations/20221219011829-remove-basic-auth-related-config.js
  20. 1 1
      apps/app/src/migrations/20230213090921-remove-presentation-configurations.js
  21. 1 3
      apps/app/src/migrations/20230731075753-add_installed_date_to_config.js
  22. 3 3
      apps/app/src/server/models/config.ts
  23. 12 7
      apps/app/src/server/routes/apiv3/healthcheck.ts
  24. 4 3
      apps/app/src/server/service/config-loader.ts
  25. 5 5
      apps/app/src/server/service/config-manager.spec.ts
  26. 3 3
      apps/app/src/server/service/config-manager.ts
  27. 26 41
      yarn.lock

+ 2 - 2
apps/app/package.json

@@ -148,7 +148,7 @@
     "next-i18next": "^15.2.0",
     "next-superjson": "^0.0.4",
     "next-themes": "^0.2.1",
-    "nocache": "^3.0.1",
+    "nocache": "^4.0.0",
     "node-cron": "^3.0.2",
     "nodemailer": "^6.6.2",
     "nodemailer-ses-transport": "~1.5.0",
@@ -230,7 +230,7 @@
     "@swc/jest": "^0.2.36",
     "@testing-library/react": "^14.1.2",
     "@testing-library/user-event": "^14.5.2",
-    "@types/express": "^4.17.11",
+    "@types/express": "^4.17.21",
     "@types/jest": "^29.5.2",
     "@types/react-input-autosize": "^2.2.4",
     "@types/react-scroll": "^1.8.4",

+ 6 - 4
apps/app/src/features/questionnaire/server/service/questionnaire.ts

@@ -3,19 +3,21 @@ import * as os from 'node:os';
 
 import type { IUserHasId } from '@growi/core';
 
-import { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
+import type { ObjectIdLike } from '~/server/interfaces/mongoose-utils';
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { aclService } from '~/server/service/acl';
 import loggerFactory from '~/utils/logger';
 
+import type { IGrowiInfo } from '../../interfaces/growi-info';
 import {
-  GrowiWikiType, GrowiExternalAuthProviderType, IGrowiInfo, GrowiServiceType, GrowiAttachmentType, GrowiDeploymentType,
+  GrowiWikiType, GrowiExternalAuthProviderType, GrowiServiceType, GrowiAttachmentType, GrowiDeploymentType,
 } from '../../interfaces/growi-info';
 import { StatusType } from '../../interfaces/questionnaire-answer-status';
 import { type IUserInfo, UserType } from '../../interfaces/user-info';
 import QuestionnaireAnswerStatus from '../models/questionnaire-answer-status';
-import QuestionnaireOrder, { QuestionnaireOrderDocument } from '../models/questionnaire-order';
+import type { QuestionnaireOrderDocument } from '../models/questionnaire-order';
+import QuestionnaireOrder from '../models/questionnaire-order';
 import { isShowableCondition } from '../util/condition';
 
 

+ 1 - 1
apps/app/src/migrations/20180927102719-init-serverurl.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20190618055300-abolish-crowi-classic-auth.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20190618104011-add-config-app-installed.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getModelSafely, getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200420160390-remove-crowi-layout.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200512005851-remove-behavior-type.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200514001356-update-theme-color-for-dark.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200620203632-normalize-locale-id.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getModelSafely, getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200827045151-remove-layout-setting.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200828024025-copy-aws-setting.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200901034313-update-mail-transmission.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200903080025-remove-timeline-type.js.js

@@ -1,5 +1,5 @@
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20200915035234-rename-s3-config.js

@@ -1,5 +1,5 @@
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20210830074539-update-configs-for-slackbot.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20211005131430-config-without-proxy-command-permission-for-renaming.js

@@ -1,7 +1,7 @@
 import mongoose from 'mongoose';
 
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 2 - 3
apps/app/src/migrations/20220311011114-convert-page-delete-config.js

@@ -3,8 +3,8 @@ import mongoose from 'mongoose';
 import {
   PageRecursiveDeleteConfigValue, PageRecursiveDeleteCompConfigValue,
 } from '~/interfaces/page-delete-config';
-import ConfigModel from '~/server/models/config';
-import { getModelSafely, getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
+import { Config } from '~/server/models/config';
+import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 
 const logger = loggerFactory('growi:migrate:convert-page-delete-config');
@@ -13,7 +13,6 @@ const logger = loggerFactory('growi:migrate:convert-page-delete-config');
 module.exports = {
   async up(db, client) {
     mongoose.connect(getMongoUri(), mongoOptions);
-    const Config = getModelSafely('Config') || ConfigModel;
 
     const isNewConfigExists = await Config.count({
       ns: 'crowi',

+ 1 - 1
apps/app/src/migrations/20221014130200-remove-customize-is-saved-states-of-tab-changes.js

@@ -1,5 +1,5 @@
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20221219011829-remove-basic-auth-related-config.js

@@ -1,5 +1,5 @@
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 1
apps/app/src/migrations/20230213090921-remove-presentation-configurations.js

@@ -1,5 +1,5 @@
 // eslint-disable-next-line import/no-named-as-default
-import Config from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 

+ 1 - 3
apps/app/src/migrations/20230731075753-add_installed_date_to_config.js

@@ -1,5 +1,5 @@
 // eslint-disable-next-line import/no-named-as-default
-import ConfigModel from '~/server/models/config';
+import { Config } from '~/server/models/config';
 import { getModelSafely, getMongoUri, mongoOptions } from '~/server/util/mongoose-utils';
 import loggerFactory from '~/utils/logger';
 
@@ -12,7 +12,6 @@ module.exports = {
   async up() {
     logger.info('Apply migration');
     mongoose.connect(getMongoUri(), mongoOptions);
-    const Config = getModelSafely('Config') || ConfigModel;
     const User = getModelSafely('User') || require('~/server/models/user')();
 
     const appInstalled = await Config.findOne({ key: 'app:installed' });
@@ -39,7 +38,6 @@ module.exports = {
   async down() {
     logger.info('Rollback migration');
     mongoose.connect(getMongoUri(), mongoOptions);
-    const Config = getModelSafely('Config') || ConfigModel;
 
     const appInstalled = await Config.findOne({ key: 'app:installed' });
     if (appInstalled != null) {

+ 3 - 3
apps/app/src/server/models/config.ts

@@ -7,7 +7,7 @@ import { RehypeSanitizeType } from '~/interfaces/services/rehype-sanitize';
 import { getOrCreateModel } from '../util/mongoose-utils';
 
 
-export interface Config {
+export interface IConfig {
   _id: Types.ObjectId;
   ns: string;
   key: string;
@@ -21,7 +21,7 @@ export interface Config {
 interface ModelMethods { any }
 
 
-const schema = new Schema<Config>({
+const schema = new Schema<IConfig>({
   ns: { type: String, required: true },
   key: { type: String, required: true },
   value: { type: String, required: true },
@@ -176,4 +176,4 @@ export const defaultNotificationConfigs: { [key: string]: any } = {
   'slack:token': undefined,
 };
 
-export default getOrCreateModel<Config, ModelMethods>('Config', schema);
+export const Config = getOrCreateModel<IConfig, ModelMethods>('Config', schema);

+ 12 - 7
apps/app/src/server/routes/apiv3/healthcheck.js → apps/app/src/server/routes/apiv3/healthcheck.ts

@@ -1,14 +1,17 @@
 import { ErrorV3 } from '@growi/core/dist/models';
+import express from 'express';
+import nocache from 'nocache';
 
 import loggerFactory from '~/utils/logger';
 
-const logger = loggerFactory('growi:routes:apiv3:healthcheck'); // eslint-disable-line no-unused-vars
+import { Config } from '../../models/config';
 
-const express = require('express');
+import type { ApiV3Response } from './interfaces/apiv3-response';
 
-const router = express.Router();
 
-const noCache = require('nocache');
+const logger = loggerFactory('growi:routes:apiv3:healthcheck');
+
+const router = express.Router();
 
 /**
  * @swagger
@@ -52,7 +55,6 @@ module.exports = (crowi) => {
 
   async function checkMongo(errors, info) {
     try {
-      const Config = crowi.models.Config;
       await Config.findOne({});
 
       info.mongo = 'OK';
@@ -123,8 +125,11 @@ module.exports = (crowi) => {
    *                  info:
    *                    $ref: '#/components/schemas/HealthcheckInfo'
    */
-  router.get('/', noCache(), async(req, res) => {
-    let checkServices = req.query.checkServices || [];
+  router.get('/', nocache(), async(req, res: ApiV3Response) => {
+    let checkServices = (() => {
+      if (req.query.checkServices == null) return [];
+      return Array.isArray(req.query.checkServices) ? req.query.checkServices : [req.query.checkServices];
+    })();
     let isStrictly = req.query.strictly != null;
 
     // for backward compatibility

+ 4 - 3
apps/app/src/server/service/config-loader.ts

@@ -4,8 +4,9 @@ import { parseISO } from 'date-fns/parseISO';
 import { GrowiServiceType } from '~/features/questionnaire/interfaces/growi-info';
 import loggerFactory from '~/utils/logger';
 
-import type { Config } from '../models/config';
-import ConfigModel, { defaultCrowiConfigs, defaultMarkdownConfigs, defaultNotificationConfigs } from '../models/config';
+import {
+  Config, defaultCrowiConfigs, defaultMarkdownConfigs, defaultNotificationConfigs,
+} from '../models/config';
 
 
 const logger = loggerFactory('growi:service:ConfigLoader');
@@ -790,7 +791,7 @@ export default class ConfigLoader {
 
   async loadFromDB(): Promise<any> {
     const config = {};
-    const docs: Config[] = await ConfigModel.find().exec();
+    const docs = await Config.find().exec();
 
     for (const doc of docs) {
       if (!config[doc.ns]) {

+ 5 - 5
apps/app/src/server/service/config-manager.spec.ts

@@ -1,6 +1,6 @@
 import { mock } from 'vitest-mock-extended';
 
-import ConfigModel from '../models/config';
+import { Config } from '../models/config';
 
 import { configManager } from './config-manager';
 import type { S2sMessagingService } from './s2s-messaging/base';
@@ -19,7 +19,7 @@ describe('ConfigManager test', () => {
 
     test('invoke publishUpdateMessage()', async() => {
       // setup
-      ConfigModel.bulkWrite = vi.fn();
+      Config.bulkWrite = vi.fn();
       configManager.loadConfigs = vi.fn();
       configManager.publishUpdateMessage = vi.fn();
 
@@ -28,14 +28,14 @@ describe('ConfigManager test', () => {
       await configManager.updateConfigsInTheSameNamespace('dummyNs', dummyConfig);
 
       // then
-      expect(ConfigModel.bulkWrite).toHaveBeenCalledTimes(1);
+      expect(Config.bulkWrite).toHaveBeenCalledTimes(1);
       expect(configManager.loadConfigs).toHaveBeenCalledTimes(1);
       expect(configManager.publishUpdateMessage).toHaveBeenCalledTimes(1);
     });
 
     test('does not invoke publishUpdateMessage()', async() => {
       // setup
-      ConfigModel.bulkWrite = vi.fn();
+      Config.bulkWrite = vi.fn();
       configManager.loadConfigs = vi.fn();
       configManager.publishUpdateMessage = vi.fn();
 
@@ -44,7 +44,7 @@ describe('ConfigManager test', () => {
       await configManager.updateConfigsInTheSameNamespace('dummyNs', dummyConfig, true);
 
       // then
-      expect(ConfigModel.bulkWrite).toHaveBeenCalledTimes(1);
+      expect(Config.bulkWrite).toHaveBeenCalledTimes(1);
       expect(configManager.loadConfigs).toHaveBeenCalledTimes(1);
       expect(configManager.publishUpdateMessage).not.toHaveBeenCalled();
     });

+ 3 - 3
apps/app/src/server/service/config-manager.ts

@@ -2,7 +2,7 @@ import { parseISO } from 'date-fns/parseISO';
 
 import loggerFactory from '~/utils/logger';
 
-import ConfigModel from '../models/config';
+import { Config } from '../models/config';
 import S2sMessage from '../models/vo/s2s-message';
 
 import type { ConfigObject } from './config-loader';
@@ -204,7 +204,7 @@ class ConfigManagerImpl implements ConfigManager, S2sMessageHandlable {
         },
       });
     }
-    await ConfigModel.bulkWrite(queries);
+    await Config.bulkWrite(queries);
 
     await this.loadConfigs();
 
@@ -223,7 +223,7 @@ class ConfigManagerImpl implements ConfigManager, S2sMessageHandlable {
         },
       });
     }
-    await ConfigModel.bulkWrite(queries);
+    await Config.bulkWrite(queries);
 
     await this.loadConfigs();
 

+ 26 - 41
yarn.lock

@@ -2148,6 +2148,7 @@
 "@growi/editor@link:packages/editor":
   version "1.0.0"
   dependencies:
+    lib0 "^0.2.94"
     markdown-table "^3.0.3"
     react "^18.2.0"
     react-dom "^18.2.0"
@@ -4322,22 +4323,23 @@
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
   integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==
 
-"@types/express-serve-static-core@^4.17.18":
-  version "4.17.19"
-  resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d"
-  integrity sha512-DJOSHzX7pCiSElWaGR8kCprwibCB/3yW6vcT8VG3P0SJjnv19gnWG/AZMfM60Xj/YJIp/YCaDHyvzsFVeniARA==
+"@types/express-serve-static-core@^4.17.18", "@types/express-serve-static-core@^4.17.33":
+  version "4.19.5"
+  resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.5.tgz#218064e321126fcf9048d1ca25dd2465da55d9c6"
+  integrity sha512-y6W03tvrACO72aijJ5uF02FRq5cgDR9lUxddQ8vyF+GvmjJQqbzDcJngEjURc+ZsG31VI3hODNZJ2URj86pzmg==
   dependencies:
     "@types/node" "*"
     "@types/qs" "*"
     "@types/range-parser" "*"
+    "@types/send" "*"
 
-"@types/express@*", "@types/express@^4.17.11":
-  version "4.17.11"
-  resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.11.tgz#debe3caa6f8e5fcda96b47bd54e2f40c4ee59545"
-  integrity sha512-no+R6rW60JEc59977wIxreQVsIEOAYwgCqldrA/vkpCnbD7MqTefO97lmoBe4WE0F156bC4uLSP1XHDOySnChg==
+"@types/express@*", "@types/express@^4.17.11", "@types/express@^4.17.21":
+  version "4.17.21"
+  resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d"
+  integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==
   dependencies:
     "@types/body-parser" "*"
-    "@types/express-serve-static-core" "^4.17.18"
+    "@types/express-serve-static-core" "^4.17.33"
     "@types/qs" "*"
     "@types/serve-static" "*"
 
@@ -4656,6 +4658,14 @@
   resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e"
   integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==
 
+"@types/send@*":
+  version "0.17.4"
+  resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a"
+  integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==
+  dependencies:
+    "@types/mime" "^1"
+    "@types/node" "*"
+
 "@types/serve-static@*":
   version "1.13.9"
   resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.9.tgz#aacf28a85a05ee29a11fb7c3ead935ac56f33e4e"
@@ -13900,10 +13910,10 @@ no-case@^3.0.4:
     lower-case "^2.0.2"
     tslib "^2.0.3"
 
-nocache@^3.0.1:
-  version "3.0.1"
-  resolved "https://registry.yarnpkg.com/nocache/-/nocache-3.0.1.tgz#54d8b53a7e0a0aa1a288cfceab8a3cefbcde67d4"
-  integrity sha512-Gh39xwJwBKy0OvFmWfBs/vDO4Nl7JhnJtkqNP76OUinQz7BiMoszHYrIDHHAaqVl/QKVxCEy4ZxC/XZninu7nQ==
+nocache@^4.0.0:
+  version "4.0.0"
+  resolved "https://registry.yarnpkg.com/nocache/-/nocache-4.0.0.tgz#d6c6f34bee4600f63f852dccfeb29c9a96cf85c0"
+  integrity sha512-AntnTbmKZvNYIsTVPPwv7dfZdAfo/6H/2ZlZACK66NAOQtIApxkB/6pf/c+s+ACW8vemGJzUCyVTssrzNUK6yQ==
 
 node-cron@^3.0.2:
   version "3.0.2"
@@ -17240,7 +17250,7 @@ string-template@>=1.0.0:
   resolved "https://registry.yarnpkg.com/string-template/-/string-template-1.0.0.tgz#9e9f2233dc00f218718ec379a28a5673ecca8b96"
   integrity sha1-np8iM9wA8hhxjsN5oopWc+zKi5Y=
 
-"string-width-cjs@npm:string-width@^4.2.0":
+"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
   version "4.2.3"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
   integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -17258,15 +17268,6 @@ string-width@=4.2.2:
     is-fullwidth-code-point "^3.0.0"
     strip-ansi "^6.0.0"
 
-"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
-  version "4.2.3"
-  resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
-  integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
-  dependencies:
-    emoji-regex "^8.0.0"
-    is-fullwidth-code-point "^3.0.0"
-    strip-ansi "^6.0.1"
-
 string-width@^5.0.1, string-width@^5.1.2:
   version "5.1.2"
   resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
@@ -17350,7 +17351,7 @@ stringify-entities@^4.0.0:
     character-entities-html4 "^2.0.0"
     character-entities-legacy "^3.0.0"
 
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
   version "6.0.1"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
   integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -17364,13 +17365,6 @@ strip-ansi@^3.0.0:
   dependencies:
     ansi-regex "^2.0.0"
 
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
-  version "6.0.1"
-  resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
-  integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
-  dependencies:
-    ansi-regex "^5.0.1"
-
 strip-ansi@^7.0.1, strip-ansi@^7.1.0:
   version "7.1.0"
   resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -19192,7 +19186,7 @@ word-wrap@^1.2.3:
   resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c"
   integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==
 
-"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
+"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
   version "7.0.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
   integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -19210,15 +19204,6 @@ wrap-ansi@^6.2.0:
     string-width "^4.1.0"
     strip-ansi "^6.0.0"
 
-wrap-ansi@^7.0.0:
-  version "7.0.0"
-  resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
-  integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
-  dependencies:
-    ansi-styles "^4.0.0"
-    string-width "^4.1.0"
-    strip-ansi "^6.0.0"
-
 wrap-ansi@^8.1.0:
   version "8.1.0"
   resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"