Merge pull request #272 from Hexastack/fix/organize-type-declarations

Fix/organize type declarations
This commit is contained in:
Med Marrouchi 2024-10-27 22:08:52 +01:00 committed by GitHub
commit 0b4acd8c43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 126 additions and 85 deletions

View File

@ -5,6 +5,11 @@
"description": "Hexabot is a solution for creating and managing chatbots across multiple channels, leveraging AI for advanced conversational capabilities. It provides a user-friendly interface for building, training, and deploying chatbots with integrated support for various messaging platforms.", "description": "Hexabot is a solution for creating and managing chatbots across multiple channels, leveraging AI for advanced conversational capabilities. It provides a user-friendly interface for building, training, and deploying chatbots with integrated support for various messaging platforms.",
"author": "Hexastack", "author": "Hexastack",
"license": "AGPL-3.0-only", "license": "AGPL-3.0-only",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
],
"scripts": { "scripts": {
"postinstall": "patch-package", "postinstall": "patch-package",
"build:clean": "rm -rf src/.hexabot", "build:clean": "rm -rf src/.hexabot",
@ -13,7 +18,8 @@
"build:plugins": "mkdir -p src/.hexabot/extensions/plugins && find node_modules/ -name 'hexabot-plugin-*' -exec cp -R {} src/.hexabot/extensions/plugins/ \\;", "build:plugins": "mkdir -p src/.hexabot/extensions/plugins && find node_modules/ -name 'hexabot-plugin-*' -exec cp -R {} src/.hexabot/extensions/plugins/ \\;",
"build:extensions": "npm run build:channels && npm run build:helpers && npm run build:plugins", "build:extensions": "npm run build:channels && npm run build:helpers && npm run build:plugins",
"build:prepare": "npm run build:clean && npm run build:extensions", "build:prepare": "npm run build:clean && npm run build:extensions",
"build": "npm run build:prepare && nest build", "build": "npm run build:prepare && nest build && npm run copy-types",
"copy-types": "cp -R types dist/types",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"libs/**/*.ts\"", "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\" \"libs/**/*.ts\"",
"start": "nest start", "start": "nest start",
"doc": "npx @compodoc/compodoc --hideGenerator -p tsconfig.doc.json -s -r 9003 -w", "doc": "npx @compodoc/compodoc --hideGenerator -p tsconfig.doc.json -s -r 9003 -w",

View File

@ -136,4 +136,4 @@ const i18nOptions: I18nOptions = {
AppService, AppService,
], ],
}) })
export class AppModule {} export class HexabotModule {}

View File

@ -20,6 +20,7 @@ import {
import { LoggerService } from '@/logger/logger.service'; import { LoggerService } from '@/logger/logger.service';
import { SettingService } from '@/setting/services/setting.service'; import { SettingService } from '@/setting/services/setting.service';
import { Extension } from '@/utils/generics/extension'; import { Extension } from '@/utils/generics/extension';
import { HyphenToUnderscore } from '@/utils/types/extension';
import { SocketRequest } from '@/websocket/utils/socket-request'; import { SocketRequest } from '@/websocket/utils/socket-request';
import { SocketResponse } from '@/websocket/utils/socket-response'; import { SocketResponse } from '@/websocket/utils/socket-response';

View File

@ -7,6 +7,7 @@
*/ */
import { SettingCreateDto } from '@/setting/dto/setting.dto'; import { SettingCreateDto } from '@/setting/dto/setting.dto';
import { HyphenToUnderscore } from '@/utils/types/extension';
export type ChannelName = `${string}-channel`; export type ChannelName = `${string}-channel`;

View File

@ -134,12 +134,12 @@ export const config: Config = {
max: 100, // Maximum number of items in cache (defaults to 100) max: 100, // Maximum number of items in cache (defaults to 100)
}, },
mongo: { mongo: {
user: process.env.MONGO_USER, user: process.env.MONGO_USER || 'dev_only',
password: process.env.MONGO_PASSWORD, password: process.env.MONGO_PASSWORD || 'dev_only',
uri: process.env.MONGO_URI, uri: process.env.MONGO_URI || 'mongodb://dev_only:dev_only@mongo:27017/',
dbName: process.env.MONGO_DB, dbName: process.env.MONGO_DB || 'hexabot',
}, },
env: process.env.NODE_ENV, env: process.env.NODE_ENV || 'development',
authentication: { authentication: {
jwtOptions: { jwtOptions: {
salt: parseInt(process.env.SALT_LENGTH || '12'), salt: parseInt(process.env.SALT_LENGTH || '12'),

View File

@ -299,7 +299,7 @@ export default abstract class BaseWebChannelHandler<
*/ */
private async verifyToken(verificationToken: string) { private async verifyToken(verificationToken: string) {
const settings = const settings =
(await this.getSettings()) as Settings[typeof WEB_CHANNEL_NAMESPACE]; (await this.getSettings()) as unknown as Settings[typeof WEB_CHANNEL_NAMESPACE];
const verifyToken = settings.verification_token; const verifyToken = settings.verification_token;
if (!verifyToken) { if (!verifyToken) {

16
api/src/global.d.ts vendored Normal file
View File

@ -0,0 +1,16 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
declare global {
type HyphenToUnderscore<S extends string> = S extends `${infer P}-${infer Q}`
? `${P}_${HyphenToUnderscore<Q>}`
: S;
}
// eslint-disable-next-line prettier/prettier
export { };

View File

@ -12,6 +12,7 @@ import { LoggerService, OnModuleInit } from '@nestjs/common';
import { SettingService } from '@/setting/services/setting.service'; import { SettingService } from '@/setting/services/setting.service';
import { Extension } from '@/utils/generics/extension'; import { Extension } from '@/utils/generics/extension';
import { HyphenToUnderscore } from '@/utils/types/extension';
import { HelperService } from '../helper.service'; import { HelperService } from '../helper.service';
import { HelperName, HelperSetting, HelperType } from '../types'; import { HelperName, HelperSetting, HelperType } from '../types';

View File

@ -7,6 +7,7 @@
*/ */
import { SettingCreateDto } from '@/setting/dto/setting.dto'; import { SettingCreateDto } from '@/setting/dto/setting.dto';
import { HyphenToUnderscore } from '@/utils/types/extension';
import BaseHelper from './lib/base-helper'; import BaseHelper from './lib/base-helper';
import BaseLlmHelper from './lib/base-llm-helper'; import BaseLlmHelper from './lib/base-llm-helper';

9
api/src/index.ts Normal file
View File

@ -0,0 +1,9 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
export * from './app.module';

View File

@ -18,19 +18,19 @@ moduleAlias.addAliases({
'@': __dirname, '@': __dirname,
}); });
import { AppModule } from './app.module'; import { HexabotModule } from './app.module';
import { config } from './config'; import { config } from './config';
import { LoggerService } from './logger/logger.service'; import { LoggerService } from './logger/logger.service';
import { seedDatabase } from './seeder'; import { seedDatabase } from './seeder';
import { swagger } from './swagger'; import { swagger } from './swagger';
import { sessionStore } from './utils/constants/session-store'; import { getSessionStore } from './utils/constants/session-store';
import { ObjectIdPipe } from './utils/pipes/object-id.pipe'; import { ObjectIdPipe } from './utils/pipes/object-id.pipe';
async function bootstrap() { async function bootstrap() {
const isProduction = config.env.toLowerCase().includes('prod'); const isProduction = config.env.toLowerCase().includes('prod');
await resolveDynamicProviders(); await resolveDynamicProviders();
const app = await NestFactory.create(AppModule, { const app = await NestFactory.create(HexabotModule, {
bodyParser: false, bodyParser: false,
}); });
@ -63,7 +63,7 @@ async function bootstrap() {
proxy: config.security.trustProxy, proxy: config.security.trustProxy,
resave: true, resave: true,
saveUninitialized: false, saveUninitialized: false,
store: sessionStore, store: getSessionStore(),
cookie: { cookie: {
httpOnly: true, httpOnly: true,
secure: config.security.httpsEnabled, secure: config.security.httpsEnabled,

View File

@ -8,6 +8,7 @@
import { forwardRef, Inject, Injectable } from '@nestjs/common'; import { forwardRef, Inject, Injectable } from '@nestjs/common';
import { DeleteResult } from '@/utils/generics/base-repository';
import { BaseService } from '@/utils/generics/base-service'; import { BaseService } from '@/utils/generics/base-service';
import { NlpValueCreateDto, NlpValueUpdateDto } from '../dto/nlp-value.dto'; import { NlpValueCreateDto, NlpValueUpdateDto } from '../dto/nlp-value.dto';
@ -43,7 +44,7 @@ export class NlpValueService extends BaseService<
* *
* @returns A promise that resolves when the deletion is complete. * @returns A promise that resolves when the deletion is complete.
*/ */
async deleteCascadeOne(id: string) { async deleteCascadeOne(id: string): Promise<DeleteResult> {
return await this.repository.deleteOne(id); return await this.repository.deleteOne(id);
} }

View File

@ -11,7 +11,7 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
import { InjectModel } from '@nestjs/mongoose'; import { InjectModel } from '@nestjs/mongoose';
import { Model as MongooseModel } from 'mongoose'; import { Model as MongooseModel } from 'mongoose';
import { BaseRepository } from '@/utils/generics/base-repository'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
import { import {
Model, Model,
@ -43,7 +43,7 @@ export class ModelRepository extends BaseRepository<
* *
* @returns The result of the delete operation. * @returns The result of the delete operation.
*/ */
async deleteOne(id: string) { async deleteOne(id: string): Promise<DeleteResult> {
const result = await this.model.deleteOne({ _id: id }).exec(); const result = await this.model.deleteOne({ _id: id }).exec();
if (result.deletedCount > 0) { if (result.deletedCount > 0) {
await this.permissionModel.deleteMany({ model: id }); await this.permissionModel.deleteMany({ model: id });

View File

@ -11,7 +11,7 @@ import { EventEmitter2 } from '@nestjs/event-emitter';
import { InjectModel } from '@nestjs/mongoose'; import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose'; import { Model } from 'mongoose';
import { BaseRepository } from '@/utils/generics/base-repository'; import { BaseRepository, DeleteResult } from '@/utils/generics/base-repository';
import { Permission } from '../schemas/permission.schema'; import { Permission } from '../schemas/permission.schema';
import { import {
@ -43,7 +43,7 @@ export class RoleRepository extends BaseRepository<
* *
* @returns The result of the delete operation. * @returns The result of the delete operation.
*/ */
async deleteOne(id: string) { async deleteOne(id: string): Promise<DeleteResult> {
const result = await this.model.deleteOne({ _id: id }).exec(); const result = await this.model.deleteOne({ _id: id }).exec();
if (result.deletedCount > 0) { if (result.deletedCount > 0) {
await this.permissionModel.deleteMany({ role: id }); await this.permissionModel.deleteMany({ role: id });

View File

@ -18,15 +18,4 @@ export class ModelService extends BaseService<Model, ModelPopulate, ModelFull> {
constructor(readonly repository: ModelRepository) { constructor(readonly repository: ModelRepository) {
super(repository); super(repository);
} }
/**
* Deletes a Model entity by its unique identifier.
*
* @param id - The unique identifier of the Model entity to delete.
*
* @returns A promise that resolves to the result of the deletion operation.
*/
async deleteOne(id: string) {
return await this.repository.deleteOne(id);
}
} }

View File

@ -10,8 +10,15 @@ import MongoStore from 'connect-mongo';
import { config } from '@/config'; import { config } from '@/config';
export const sessionStore = MongoStore.create({ let sessionStore: MongoStore = null;
mongoUrl: config.mongo.uri,
dbName: config.mongo.dbName, export const getSessionStore = () => {
collectionName: 'sessions', if (!sessionStore) {
}); sessionStore = MongoStore.create({
mongoUrl: config.mongo.uri,
dbName: config.mongo.dbName,
collectionName: 'sessions',
});
}
return sessionStore;
};

View File

@ -340,13 +340,13 @@ export abstract class BaseRepository<
}); });
} }
async deleteOne(criteria: string | TFilterQuery<T>) { async deleteOne(criteria: string | TFilterQuery<T>): Promise<DeleteResult> {
return await this.model return await this.model
.deleteOne(typeof criteria === 'string' ? { _id: criteria } : criteria) .deleteOne(typeof criteria === 'string' ? { _id: criteria } : criteria)
.exec(); .exec();
} }
async deleteMany(criteria: TFilterQuery<T>) { async deleteMany(criteria: TFilterQuery<T>): Promise<DeleteResult> {
return await this.model.deleteMany(criteria); return await this.model.deleteMany(criteria);
} }

View File

@ -13,7 +13,7 @@ import { OnModuleInit } from '@nestjs/common';
import { I18nJsonLoader, I18nTranslation } from 'nestjs-i18n'; import { I18nJsonLoader, I18nTranslation } from 'nestjs-i18n';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { ExtensionName } from '../types/extension'; import { ExtensionName, HyphenToUnderscore } from '../types/extension';
export abstract class Extension implements OnModuleInit { export abstract class Extension implements OnModuleInit {
private translations: I18nTranslation | Observable<I18nTranslation>; private translations: I18nTranslation | Observable<I18nTranslation>;

View File

@ -11,3 +11,6 @@ import { HelperName } from '@/helper/types';
import { PluginName } from '@/plugins/types'; import { PluginName } from '@/plugins/types';
export type ExtensionName = ChannelName | HelperName | PluginName; export type ExtensionName = ChannelName | HelperName | PluginName;
export type HyphenToUnderscore<S extends string> =
S extends `${infer P}-${infer Q}` ? `${P}_${HyphenToUnderscore<Q>}` : S;

View File

@ -33,7 +33,7 @@ import {
import { OutgoingMessage, StdEventType } from '@/chat/schemas/types/message'; import { OutgoingMessage, StdEventType } from '@/chat/schemas/types/message';
import { config } from '@/config'; import { config } from '@/config';
import { LoggerService } from '@/logger/logger.service'; import { LoggerService } from '@/logger/logger.service';
import { sessionStore } from '@/utils/constants/session-store'; import { getSessionStore } from '@/utils/constants/session-store';
import { IOIncomingMessage, IOMessagePipe } from './pipes/io-message.pipe'; import { IOIncomingMessage, IOMessagePipe } from './pipes/io-message.pipe';
import { SocketEventDispatcherService } from './services/socket-event-dispatcher.service'; import { SocketEventDispatcherService } from './services/socket-event-dispatcher.service';
@ -134,7 +134,7 @@ export class WebsocketGateway
}, },
passport: { user: {} }, passport: { user: {} },
}; // Initialize your session object as needed }; // Initialize your session object as needed
sessionStore.set(sid, newSession, (err) => { getSessionStore().set(sid, newSession, (err) => {
if (err) { if (err) {
this.logger.error('Error saving session:', err); this.logger.error('Error saving session:', err);
return next(new Error('Unable to establish a new socket session')); return next(new Error('Unable to establish a new socket session'));
@ -179,7 +179,7 @@ export class WebsocketGateway
); );
return; return;
} }
sessionStore.set(sessionID, session, (err) => { getSessionStore().set(sessionID, session, (err) => {
if (err) { if (err) {
this.logger.error( this.logger.error(
'Error saving session in `config.sockets.afterDisconnect`:', 'Error saving session in `config.sockets.afterDisconnect`:',
@ -195,7 +195,7 @@ export class WebsocketGateway
sessionID: string, sessionID: string,
next: (err: Error, session: any) => void, next: (err: Error, session: any) => void,
): void { ): void {
sessionStore.get(sessionID, (err, session) => { getSessionStore().get(sessionID, (err, session) => {
this.logger.verbose('Retrieved socket session', err || session); this.logger.verbose('Retrieved socket session', err || session);
return next(err, session); return next(err, session);
}); });

View File

@ -10,14 +10,14 @@ import { INestApplication } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing'; import { Test, TestingModule } from '@nestjs/testing';
import request from 'supertest'; import request from 'supertest';
import { AppModule } from './../src/app.module'; import { HexabotModule } from './../src/app.module';
describe('AppController (e2e)', () => { describe('AppController (e2e)', () => {
let app: INestApplication; let app: INestApplication;
beforeEach(async () => { beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({ const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule], imports: [HexabotModule],
}).compile(); }).compile();
app = moduleFixture.createNestApplication(); app = moduleFixture.createNestApplication();

View File

@ -1,5 +1,6 @@
{ {
"compilerOptions": { "compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"],
"module": "commonjs", "module": "commonjs",
"declaration": true, "declaration": true,
"removeComments": true, "removeComments": true,
@ -24,6 +25,8 @@
} }
}, },
"include": [ "include": [
"types/**/*.d.ts",
"src/global.d.ts",
"src/**/*.ts", "src/**/*.ts",
"src/**/*.json", "src/**/*.json",
"test/**/*.ts", "test/**/*.ts",

View File

@ -19,6 +19,7 @@ import { type Socket } from 'socket.io';
import { type BotStats } from '@/analytics/schemas/bot-stats.schema'; import { type BotStats } from '@/analytics/schemas/bot-stats.schema';
import { type Attachment } from '@/attachment/schemas/attachment.schema'; import { type Attachment } from '@/attachment/schemas/attachment.schema';
import type EventWrapper from '@/channel/lib/EventWrapper'; import type EventWrapper from '@/channel/lib/EventWrapper';
import { type SubscriberUpdateDto } from '@/chat/dto/subscriber.dto';
import type { Block, BlockFull } from '@/chat/schemas/block.schema'; import type { Block, BlockFull } from '@/chat/schemas/block.schema';
import { type Category } from '@/chat/schemas/category.schema'; import { type Category } from '@/chat/schemas/category.schema';
import { type ContextVar } from '@/chat/schemas/context-var.schema'; import { type ContextVar } from '@/chat/schemas/context-var.schema';
@ -49,8 +50,6 @@ import { type Role } from '@/user/schemas/role.schema';
import { type User } from '@/user/schemas/user.schema'; import { type User } from '@/user/schemas/user.schema';
import { EHook, type DeleteResult } from '@/utils/generics/base-repository'; import { EHook, type DeleteResult } from '@/utils/generics/base-repository';
import { type SubscriberUpdateDto } from './chat/dto/subscriber.dto';
import '@nestjs/event-emitter'; import '@nestjs/event-emitter';
/** /**
* @description Module declaration that extends the NestJS EventEmitter with custom event types and methods. * @description Module declaration that extends the NestJS EventEmitter with custom event types and methods.
@ -87,15 +86,6 @@ declare module '@nestjs/event-emitter' {
company_country: Setting; company_country: Setting;
} }
>; >;
nlp_settings: TDefinition<
object,
{
provider: Setting;
endpoint: Setting;
token: Setting;
threshold: Setting;
}
>;
} }
/* custom hooks */ /* custom hooks */
@ -187,12 +177,16 @@ declare module '@nestjs/event-emitter' {
* @description A constrained string type that allows specific string values while preserving type safety. * @description A constrained string type that allows specific string values while preserving type safety.
*/ */
type ConstrainedString = string & Record<never, never>; type ConstrainedString = string & Record<never, never>;
type EventNamespaces = keyof IHookEntityOperationMap; type EventNamespaces = keyof IHookEntityOperationMap;
/* pre hooks */ /* pre hooks */
type TPreValidate<T> = THydratedDocument<T>; type TPreValidate<T> = THydratedDocument<T>;
type TPreCreate<T> = THydratedDocument<T>; type TPreCreate<T> = THydratedDocument<T>;
type TPreUpdate<T> = TFilterQuery<T> & object; type TPreUpdate<T> = TFilterQuery<T> & object;
type TPreDelete<T> = Query< type TPreDelete<T> = Query<
DeleteResult, DeleteResult,
Document<T>, Document<T>,
@ -201,6 +195,7 @@ declare module '@nestjs/event-emitter' {
'deleteOne', 'deleteOne',
Record<string, never> Record<string, never>
>; >;
type TPreUnion<T> = type TPreUnion<T> =
| TPreValidate<T> | TPreValidate<T>
| TPreCreate<T> | TPreCreate<T>
@ -209,9 +204,13 @@ declare module '@nestjs/event-emitter' {
/* post hooks */ /* post hooks */
type TPostValidate<T> = THydratedDocument<T>; type TPostValidate<T> = THydratedDocument<T>;
type TPostCreate<T> = THydratedDocument<T>; type TPostCreate<T> = THydratedDocument<T>;
type TPostUpdate<T> = THydratedDocument<T>; type TPostUpdate<T> = THydratedDocument<T>;
type TPostDelete = DeleteResult; type TPostDelete = DeleteResult;
type TPostUnion<T> = type TPostUnion<T> =
| TPostValidate<T> | TPostValidate<T>
| TPostCreate<T> | TPostCreate<T>
@ -240,6 +239,7 @@ declare module '@nestjs/event-emitter' {
> = T extends `${P}${infer I}` ? `${P}${I}` : never; > = T extends `${P}${infer I}` ? `${P}${I}` : never;
type TPreHook = TCompatibleHook<EHookPrefix.pre>; type TPreHook = TCompatibleHook<EHookPrefix.pre>;
type TPostHook = TCompatibleHook<EHookPrefix.post>; type TPostHook = TCompatibleHook<EHookPrefix.post>;
type TNormalizedEvents = '*' | TPreHook | TPostHook; type TNormalizedEvents = '*' | TPreHook | TPostHook;
@ -313,11 +313,11 @@ declare module '@nestjs/event-emitter' {
: `hook:${G}:${TNormalizedEvents | TCustomEvents<G>}` : `hook:${G}:${TNormalizedEvents | TCustomEvents<G>}`
: never; : never;
export interface ListenerFn<G extends EventNamespaces | ConstrainedString> { interface ListenerFn<G extends EventNamespaces | ConstrainedString> {
(value: EventValueOf<G>, ...values: any[]): void; (value: EventValueOf<G>, ...values: any[]): void;
} }
export class EventEmitter2 { class EventEmitter2 {
emit<G extends EventNamespaces | ConstrainedString, H extends G>( emit<G extends EventNamespaces | ConstrainedString, H extends G>(
customEvent: customEvent<G>, customEvent: customEvent<G>,
value: EventValueOf<H>, value: EventValueOf<H>,
@ -392,7 +392,7 @@ declare module '@nestjs/event-emitter' {
propertyKey: K, propertyKey: K,
) => void; ) => void;
export declare function OnEvent< declare function OnEvent<
G extends EventNamespaces | ConstrainedString, G extends EventNamespaces | ConstrainedString,
H extends G, H extends G,
>( >(

View File

@ -6,16 +6,8 @@
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file). * 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/ */
import 'mongoose';
import { SubscriberStub } from './chat/schemas/subscriber.schema'; import { SubscriberStub } from './chat/schemas/subscriber.schema';
import {
ObjectWithNestedKeys,
RecursivePartial,
WithoutGenericAny,
} from './utils/types/filter.types';
type TOmitId<T> = Omit<T, 'id'>;
type TReplaceId<T> = TOmitId<T> & { _id?: string };
declare module 'express-session' { declare module 'express-session' {
interface SessionUser { interface SessionUser {
id?: string; id?: string;
@ -48,24 +40,3 @@ declare module 'express-session' {
}; };
} }
} }
declare module 'mongoose' {
// Enforce the typing with an alternative type to FilterQuery compatible with mongoose: version 8.0.0
type TFilterQuery<T, S = TReplaceId<T>> = (
| RecursivePartial<{
[P in keyof S]?:
| (S[P] extends string ? S[P] | RegExp : S[P])
| QuerySelector<S[P]>;
}>
| Partial<ObjectWithNestedKeys<S>>
) &
WithoutGenericAny<RootQuerySelector<S>>;
type THydratedDocument<T> = TOmitId<HydratedDocument<T>>;
}
declare global {
type HyphenToUnderscore<S extends string> = S extends `${infer P}-${infer Q}`
? `${P}_${HyphenToUnderscore<Q>}`
: S;
}

32
api/types/mongoose.d.ts vendored Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright © 2024 Hexastack. All rights reserved.
*
* Licensed under the GNU Affero General Public License v3.0 (AGPLv3) with the following additional terms:
* 1. The name "Hexabot" is a trademark of Hexastack. You may not use this name in derivative works without express written permission.
* 2. All derivative works must include clear attribution to the original creator and software, Hexastack and Hexabot, in a prominent location (e.g., in the software's "About" section, documentation, and README file).
*/
import {
ObjectWithNestedKeys,
RecursivePartial,
WithoutGenericAny,
} from '@/utils/types/filter.types';
import 'mongoose';
declare module 'mongoose' {
type TOmitId<T> = Omit<T, 'id'>;
type TReplaceId<T> = TOmitId<T> & { _id?: string };
// Enforce the typing with an alternative type to FilterQuery compatible with mongoose: version 8.0.0
type TFilterQuery<T, S = TReplaceId<T>> = (
| RecursivePartial<{
[P in keyof S]?:
| (S[P] extends string ? S[P] | RegExp : S[P])
| QuerySelector<S[P]>;
}>
| Partial<ObjectWithNestedKeys<S>>
) &
WithoutGenericAny<RootQuerySelector<S>>;
type THydratedDocument<T> = TOmitId<HydratedDocument<T>>;
}