Explorar el Código

typescriptize GlobalNotificationSetting

Yuki Takei hace 2 meses
padre
commit
b7d24cdf7d

+ 16 - 12
apps/app/src/server/models/GlobalNotificationSetting.ts

@@ -1,9 +1,14 @@
-const mongoose = require('mongoose');
+import type { Model } from 'mongoose';
+import mongoose from 'mongoose';
 
 
-const GlobalNotificationSetting = require('./GlobalNotificationSetting/index');
+import type Crowi from '~/server/crowi';
 
 
-const GlobalNotificationSettingClass = GlobalNotificationSetting.class;
-const GlobalNotificationSettingSchema = GlobalNotificationSetting.schema;
+import {
+  class as GlobalNotificationSettingClass,
+  type GlobalNotificationSettingModel,
+  schema as GlobalNotificationSettingSchema,
+  type IGlobalNotificationSetting,
+} from './GlobalNotificationSetting/index';
 
 
 /**
 /**
  * global notifcation event master
  * global notifcation event master
@@ -15,7 +20,7 @@ export const GlobalNotificationSettingEvent = {
   PAGE_MOVE: 'pageMove',
   PAGE_MOVE: 'pageMove',
   PAGE_LIKE: 'pageLike',
   PAGE_LIKE: 'pageLike',
   COMMENT: 'comment',
   COMMENT: 'comment',
-};
+} as const;
 
 
 /**
 /**
  * global notifcation type master
  * global notifcation type master
@@ -23,16 +28,15 @@ export const GlobalNotificationSettingEvent = {
 export const GlobalNotificationSettingType = {
 export const GlobalNotificationSettingType = {
   MAIL: 'mail',
   MAIL: 'mail',
   SLACK: 'slack',
   SLACK: 'slack',
-};
+} as const;
 
 
-/** @param {import('~/server/crowi').default} crowi Crowi instance */
-const factory = (crowi) => {
+const factory = (crowi: Crowi): GlobalNotificationSettingModel => {
   GlobalNotificationSettingClass.crowi = crowi;
   GlobalNotificationSettingClass.crowi = crowi;
   GlobalNotificationSettingSchema.loadClass(GlobalNotificationSettingClass);
   GlobalNotificationSettingSchema.loadClass(GlobalNotificationSettingClass);
-  return mongoose.model(
-    'GlobalNotificationSetting',
-    GlobalNotificationSettingSchema,
-  );
+  return mongoose.model<
+    IGlobalNotificationSetting,
+    GlobalNotificationSettingModel
+  >('GlobalNotificationSetting', GlobalNotificationSettingSchema);
 };
 };
 
 
 export default factory;
 export default factory;

+ 24 - 10
apps/app/src/server/models/GlobalNotificationSetting/GlobalNotificationMailSetting.ts

@@ -1,23 +1,37 @@
+import type { Model } from 'mongoose';
 import mongoose from 'mongoose';
 import mongoose from 'mongoose';
 
 
+import type Crowi from '~/server/crowi';
+
 import { GlobalNotificationSettingType } from '../GlobalNotificationSetting';
 import { GlobalNotificationSettingType } from '../GlobalNotificationSetting';
+import {
+  class as GlobalNotificationSettingClass,
+  type GlobalNotificationSettingModel,
+  schema as GlobalNotificationSettingSchema,
+  type IGlobalNotificationSetting,
+} from './index';
 
 
-const GlobalNotificationSetting = require('./index');
+export interface IGlobalNotificationMailSetting
+  extends IGlobalNotificationSetting {
+  toEmail: string;
+}
 
 
-const GlobalNotificationSettingClass = GlobalNotificationSetting.class;
-const GlobalNotificationSettingSchema = GlobalNotificationSetting.schema;
+export type GlobalNotificationMailSettingModel =
+  Model<IGlobalNotificationMailSetting> & GlobalNotificationSettingModel;
 
 
-/** @param {import('~/server/crowi').default} crowi Crowi instance */
-const factory = (crowi) => {
+const factory = (crowi: Crowi): GlobalNotificationMailSettingModel => {
   GlobalNotificationSettingClass.crowi = crowi;
   GlobalNotificationSettingClass.crowi = crowi;
   GlobalNotificationSettingSchema.loadClass(GlobalNotificationSettingClass);
   GlobalNotificationSettingSchema.loadClass(GlobalNotificationSettingClass);
 
 
-  const GlobalNotificationSettingModel = mongoose.model(
-    'GlobalNotificationSetting',
-    GlobalNotificationSettingSchema,
-  );
+  const GlobalNotificationSettingModel = mongoose.model<
+    IGlobalNotificationSetting,
+    GlobalNotificationSettingModel
+  >('GlobalNotificationSetting', GlobalNotificationSettingSchema);
   const GlobalNotificationMailSettingModel =
   const GlobalNotificationMailSettingModel =
-    GlobalNotificationSettingModel.discriminator(
+    GlobalNotificationSettingModel.discriminator<
+      IGlobalNotificationMailSetting,
+      GlobalNotificationMailSettingModel
+    >(
       GlobalNotificationSettingType.MAIL,
       GlobalNotificationSettingType.MAIL,
       new mongoose.Schema(
       new mongoose.Schema(
         {
         {

+ 24 - 10
apps/app/src/server/models/GlobalNotificationSetting/GlobalNotificationSlackSetting.ts

@@ -1,23 +1,37 @@
+import type { Model } from 'mongoose';
 import mongoose from 'mongoose';
 import mongoose from 'mongoose';
 
 
+import type Crowi from '~/server/crowi';
+
 import { GlobalNotificationSettingType } from '../GlobalNotificationSetting';
 import { GlobalNotificationSettingType } from '../GlobalNotificationSetting';
+import {
+  class as GlobalNotificationSettingClass,
+  type GlobalNotificationSettingModel,
+  schema as GlobalNotificationSettingSchema,
+  type IGlobalNotificationSetting,
+} from './index';
 
 
-const GlobalNotificationSetting = require('./index');
+export interface IGlobalNotificationSlackSetting
+  extends IGlobalNotificationSetting {
+  slackChannels: string;
+}
 
 
-const GlobalNotificationSettingClass = GlobalNotificationSetting.class;
-const GlobalNotificationSettingSchema = GlobalNotificationSetting.schema;
+export type GlobalNotificationSlackSettingModel =
+  Model<IGlobalNotificationSlackSetting> & GlobalNotificationSettingModel;
 
 
-/** @param {import('~/server/crowi').default} crowi Crowi instance */
-const factory = (crowi) => {
+const factory = (crowi: Crowi): GlobalNotificationSlackSettingModel => {
   GlobalNotificationSettingClass.crowi = crowi;
   GlobalNotificationSettingClass.crowi = crowi;
   GlobalNotificationSettingSchema.loadClass(GlobalNotificationSettingClass);
   GlobalNotificationSettingSchema.loadClass(GlobalNotificationSettingClass);
 
 
-  const GlobalNotificationSettingModel = mongoose.model(
-    'GlobalNotificationSetting',
-    GlobalNotificationSettingSchema,
-  );
+  const GlobalNotificationSettingModel = mongoose.model<
+    IGlobalNotificationSetting,
+    GlobalNotificationSettingModel
+  >('GlobalNotificationSetting', GlobalNotificationSettingSchema);
   const GlobalNotificationSlackSettingModel =
   const GlobalNotificationSlackSettingModel =
-    GlobalNotificationSettingModel.discriminator(
+    GlobalNotificationSettingModel.discriminator<
+      IGlobalNotificationSlackSetting,
+      GlobalNotificationSlackSettingModel
+    >(
       GlobalNotificationSettingType.SLACK,
       GlobalNotificationSettingType.SLACK,
       new mongoose.Schema(
       new mongoose.Schema(
         {
         {

+ 66 - 23
apps/app/src/server/models/GlobalNotificationSetting/index.ts

@@ -1,12 +1,38 @@
-const nodePath = require('path');
+import nodePath from 'node:path';
+import { pathUtils } from '@growi/core/dist/utils';
+import type { HydratedDocument, Model } from 'mongoose';
+import mongoose from 'mongoose';
 
 
-const { pathUtils } = require('@growi/core/dist/utils');
-const mongoose = require('mongoose');
+import type Crowi from '~/server/crowi';
+
+export interface IGlobalNotificationSetting {
+  isEnabled: boolean;
+  triggerPath: string;
+  triggerEvents: string[];
+}
+
+export type GlobalNotificationSettingDocument =
+  HydratedDocument<IGlobalNotificationSetting>;
+
+export interface GlobalNotificationSettingModel
+  extends Model<IGlobalNotificationSetting> {
+  enable(id: string): Promise<GlobalNotificationSettingDocument>;
+  disable(id: string): Promise<GlobalNotificationSettingDocument>;
+  findAll(): Promise<GlobalNotificationSettingDocument[]>;
+  findSettingByPathAndEvent(
+    event: string,
+    path: string,
+    type: string,
+  ): Promise<GlobalNotificationSettingDocument[]>;
+}
 
 
 /**
 /**
  * parent schema for GlobalNotificationSetting model
  * parent schema for GlobalNotificationSetting model
  */
  */
-const globalNotificationSettingSchema = new mongoose.Schema({
+const globalNotificationSettingSchema = new mongoose.Schema<
+  IGlobalNotificationSetting,
+  GlobalNotificationSettingModel
+>({
   isEnabled: { type: Boolean, required: true, default: true },
   isEnabled: { type: Boolean, required: true, default: true },
   triggerPath: { type: String, required: true },
   triggerPath: { type: String, required: true },
   triggerEvents: { type: [String] },
   triggerEvents: { type: [String] },
@@ -15,7 +41,7 @@ const globalNotificationSettingSchema = new mongoose.Schema({
 /*
 /*
  * e.g. "/a/b/c" => ["/a/b/c", "/a/b", "/a", "/"]
  * e.g. "/a/b/c" => ["/a/b/c", "/a/b", "/a", "/"]
  */
  */
-const generatePathsOnTree = (path, pathList) => {
+const generatePathsOnTree = (path: string, pathList: string[]): string[] => {
   pathList.push(path);
   pathList.push(path);
 
 
   if (path === '/') {
   if (path === '/') {
@@ -30,7 +56,7 @@ const generatePathsOnTree = (path, pathList) => {
 /*
 /*
  * e.g. "/a/b/c" => ["/a/b/c", "/a/b", "/a", "/"]
  * e.g. "/a/b/c" => ["/a/b/c", "/a/b", "/a", "/"]
  */
  */
-const generatePathsToMatch = (originalPath) => {
+const generatePathsToMatch = (originalPath: string): string[] => {
   const pathList = generatePathsOnTree(originalPath, []);
   const pathList = generatePathsOnTree(originalPath, []);
   return pathList.map((path) => {
   return pathList.map((path) => {
     // except for the original trigger path ("/a/b/c"), append "*" to find all matches
     // except for the original trigger path ("/a/b/c"), append "*" to find all matches
@@ -48,38 +74,50 @@ const generatePathsToMatch = (originalPath) => {
  * @class GlobalNotificationSetting
  * @class GlobalNotificationSetting
  */
  */
 class GlobalNotificationSetting {
 class GlobalNotificationSetting {
-  /** @type {import('~/server/crowi').default} Crowi instance */
-  crowi;
+  static crowi: Crowi;
+
+  crowi: Crowi;
 
 
-  /** @param {import('~/server/crowi').default} crowi Crowi instance */
-  constructor(crowi) {
+  constructor(crowi: Crowi) {
     this.crowi = crowi;
     this.crowi = crowi;
   }
   }
 
 
   /**
   /**
    * enable notification setting
    * enable notification setting
-   * @param {string} id
    */
    */
-  static async enable(id) {
+  static async enable(
+    this: GlobalNotificationSettingModel,
+    id: string,
+  ): Promise<GlobalNotificationSettingDocument> {
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
     const setting = await this.findOne({ _id: id });
     const setting = await this.findOne({ _id: id });
 
 
+    if (setting == null) {
+      throw new Error(`GlobalNotificationSetting with id ${id} not found`);
+    }
+
     setting.isEnabled = true;
     setting.isEnabled = true;
-    setting.save();
+    await setting.save();
 
 
     return setting;
     return setting;
   }
   }
 
 
   /**
   /**
    * disable notification setting
    * disable notification setting
-   * @param {string} id
    */
    */
-  static async disable(id) {
+  static async disable(
+    this: GlobalNotificationSettingModel,
+    id: string,
+  ): Promise<GlobalNotificationSettingDocument> {
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
     const setting = await this.findOne({ _id: id });
     const setting = await this.findOne({ _id: id });
 
 
+    if (setting == null) {
+      throw new Error(`GlobalNotificationSetting with id ${id} not found`);
+    }
+
     setting.isEnabled = false;
     setting.isEnabled = false;
-    setting.save();
+    await setting.save();
 
 
     return setting;
     return setting;
   }
   }
@@ -87,7 +125,9 @@ class GlobalNotificationSetting {
   /**
   /**
    * find all notification settings
    * find all notification settings
    */
    */
-  static async findAll() {
+  static async findAll(
+    this: GlobalNotificationSettingModel,
+  ): Promise<GlobalNotificationSettingDocument[]> {
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
     const settings = await this.find().sort({
     const settings = await this.find().sort({
       triggerPath: 1,
       triggerPath: 1,
@@ -98,10 +138,13 @@ class GlobalNotificationSetting {
 
 
   /**
   /**
    * find a list of notification settings by path and a list of events
    * find a list of notification settings by path and a list of events
-   * @param {string} path
-   * @param {string} event
    */
    */
-  static async findSettingByPathAndEvent(event, path, type) {
+  static async findSettingByPathAndEvent(
+    this: GlobalNotificationSettingModel,
+    event: string,
+    path: string,
+    type: string,
+  ): Promise<GlobalNotificationSettingDocument[]> {
     const pathsToMatch = generatePathsToMatch(path);
     const pathsToMatch = generatePathsToMatch(path);
 
 
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
     // biome-ignore lint/complexity/noThisInStatic: 'this' refers to the mongoose model here, not the class defined in this file
@@ -116,7 +159,7 @@ class GlobalNotificationSetting {
   }
   }
 }
 }
 
 
-module.exports = {
-  class: GlobalNotificationSetting,
-  schema: globalNotificationSettingSchema,
+export {
+  GlobalNotificationSetting as class,
+  globalNotificationSettingSchema as schema,
 };
 };