snapshot of https://github.com/RocketChat/Rocket.Chat.git (develop, 2026-09-16; blobs > 131072B omitted)
Some checks failed
Create issues from TODOs / todos (push) Failing after 3s
Close inactive issues / close-issues (push) Has been cancelled
Deploy GitHub Pages / deploy-preview (push) Has been cancelled
CI / ⚙️ Variables Setup (push) Has been cancelled
CI / ⚙️ Test Guard (push) Has been cancelled
CI / 🚀 Notify external services - draft (push) Has been cancelled
CI / 📦 Build Packages (push) Has been cancelled
CI / 📦 Meteor Build (coverage) (push) Has been cancelled
CI / 📦 Meteor Build (production) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [account-service presence-service omnichannel-transcript-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [authorization-service queue-worker-service ddp-streamer-service], fips) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Build Docker (amd64, [rocketchat], fips) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [account-service presence-service omnichannel-transcript-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [authorization-service queue-worker-service ddp-streamer-service], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], ${{ (github.event_name != 'release' && github.ref != 'refs/heads/develop') && 'coverage' || 'production' }}) (push) Has been cancelled
CI / 🚢 Build Docker (arm64, [rocketchat], coverage) (push) Has been cancelled
CI / 🚢 Publish Docker Images (ghcr.io) (push) Has been cancelled
CI / 📦 Track Image Sizes (push) Has been cancelled
CI / 🔎 Code Check - Action Lint (push) Has been cancelled
CI / 🔎 Code Check (push) Has been cancelled
CI / 🔨 Test Storybook (push) Has been cancelled
CI / 🔨 Test Unit (push) Has been cancelled
CI / 🔨 Test API (CE) (push) Has been cancelled
CI / 🔨 Test API Livechat (CE) (push) Has been cancelled
CI / 🔨 Test UI (CE) (push) Has been cancelled
CI / 🔨 Test API (EE) (push) Has been cancelled
CI / 🔨 Test API Livechat (EE) (push) Has been cancelled
CI / 🔨 Test API Apps (deno-runtime - EE) (push) Has been cancelled
CI / 🔨 Test UI (EE) (push) Has been cancelled
CI / 🔨 Test API (FIPS) (push) Has been cancelled
CI / 🔨 Test API Livechat (FIPS) (push) Has been cancelled
CI / 🔨 Test UI (FIPS) (push) Has been cancelled
CI / 🔨 Test Federation Matrix (push) Has been cancelled
CI / 📊 Report Coverage (push) Has been cancelled
CI / ✅ Tests Done (push) Has been cancelled
CI / 🚀 Publish build assets (push) Has been cancelled
CI / 🚀 Publish Docker Images (DockerHub) (push) Has been cancelled
CI / 🚀 Notify external services (push) Has been cancelled
CI / Update Version Durability (push) Has been cancelled
Release / Release (push) Has been cancelled
Auto-close duplicate issues / auto-close-duplicates (push) Failing after 1s
Code scanning - action / CodeQL-Build (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-16 01:21:02 +05:00
commit 30810eecd7
10161 changed files with 987110 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,28 @@
{
"name": "@rocket.chat/model-typings",
"version": "2.5.1",
"private": true,
"main": "./dist/index.js",
"typings": "./dist/index.d.ts",
"files": [
"/dist"
],
"scripts": {
"build": "rm -rf dist && tsc -p tsconfig.build.json",
"typecheck": "tsc --noEmit -p tsconfig.json",
"lint": "eslint .",
"lint:fix": "eslint --fix ."
},
"dependencies": {
"@rocket.chat/core-typings": "workspace:^"
},
"devDependencies": {
"@types/node-rsa": "^1.1.4",
"eslint": "~9.39.5",
"mongodb": "6.16.0",
"typescript": "~5.9.3"
},
"volta": {
"extends": "../../package.json"
}
}

View File

@@ -0,0 +1,85 @@
export type * from './models/IAnalyticsModel';
export type * from './models/IAvatarsModel';
export type * from './models/IBannersDismissModel';
export type * from './models/IBannersModel';
export type * from './models/IBaseModel';
export type * from './models/IBaseUploadsModel';
export type * from './models/ICannedResponseModel';
export type * from './models/ICredentialTokensModel';
export type * from './models/ILoginCodesModel';
export type * from './models/ICustomSoundsModel';
export type * from './models/ICustomUserStatusModel';
export type * from './models/IEmailInboxModel';
export type * from './models/IEmailMessageHistoryModel';
export type * from './models/IEmojiCustomModel';
export type * from './models/IExportOperationsModel';
export type * from './models/IFederationKeysModel';
export type * from './models/IInstanceStatusModel';
export type * from './models/IIntegrationHistoryModel';
export type * from './models/IIntegrationsModel';
export type * from './models/IInvitesModel';
export type * from './models/IImportDataModel';
export type * from './models/ILivechatAgentActivityModel';
export type * from './models/ILivechatBusinessHoursModel';
export type * from './models/ILivechatContactsModel';
export type * from './models/ILivechatCustomFieldModel';
export type * from './models/ILivechatDepartmentAgentsModel';
export type * from './models/ILivechatDepartmentModel';
export type * from './models/ILivechatInquiryModel';
export type * from './models/ILivechatPriorityModel';
export type * from './models/ILivechatRoomsModel';
export type * from './models/ILivechatTagModel';
export type * from './models/ILivechatTriggerModel';
export type * from './models/ILivechatUnitModel';
export type * from './models/ILivechatUnitMonitorsModel';
export type * from './models/ILivechatVisitorsModel';
export type * from './models/ILoginServiceConfigurationModel';
export type * from './models/IMessagesModel';
export type * from './models/INotificationQueueModel';
export type * from './models/INpsModel';
export type * from './models/INpsVoteModel';
export type * from './models/IOAuthAppsModel';
export type * from './models/IOAuthAuthCodesModel';
export type * from './models/IOAuthAccessTokensModel';
export type * from './models/IOAuthRefreshTokensModel';
export type * from './models/IOEmbedCacheModel';
export type * from './models/IPushTokenModel';
export type * from './models/IPermissionsModel';
export type * from './models/IReadReceiptsModel';
export type * from './models/IMessageReadsModel';
export type * from './models/IReportsModel';
export type * from './models/IRolesModel';
export type * from './models/IRoomsModel';
export type * from './models/IServerEventsModel';
export type * from './models/ISessionsModel';
export type * from './models/ISettingsModel';
export type * from './models/ISmarshHistoryModel';
export type * from './models/IStatisticsModel';
export type * from './models/ISubscriptionsModel';
export type * from './models/ITeamMemberModel';
export type * from './models/ITeamModel';
export type * from './models/IUploadsModel';
export type * from './models/IUserDataFilesModel';
export type * from './models/IUsersModel';
export type * from './models/IUsersSessionsModel';
export type * from './models/IVideoConferenceModel';
export type * from './models/IWebdavAccountsModel';
export type * from './models/ICalendarEventModel';
export type * from './models/IOmnichannelServiceLevelAgreementsModel';
export type * from './models/IAppLogsModel';
export type * from './models/IAppsModel';
export type * from './models/IAppsPersistenceModel';
export type * from './models/IImportsModel';
export type * from './models/IAuditLogModel';
export type * from './models/ICronHistoryModel';
export type * from './models/IMigrationsModel';
export type * from './models/IModerationReportsModel';
export type * from './models/IMediaCallsModel';
export type * from './models/IMediaCallNegotiationsModel';
export type * from './types/DocumentWithProjection';
export type * from './updater';
export type * from './models/IWorkspaceCredentialsModel';
export type * from './models/ICallHistoryModel';
export type * from './models/IAbacAttributesModel';
export type * from './models/ITwoFactorChallengesModel';
export type * from './models/ISamlUsedAssertionsModel';

View File

@@ -0,0 +1,13 @@
import type { IAbacAttribute } from '@rocket.chat/core-typings';
import type { Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IAbacAttributesModel extends IBaseModel<IAbacAttribute> {
findOneByKey<T extends Document = IAbacAttribute, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
key: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
countTotalValues(): Promise<number>;
}

View File

@@ -0,0 +1,50 @@
import type { IAnalytics, IRoom } from '@rocket.chat/core-typings';
import type { AggregationCursor, FindOptions, UpdateResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { IChannelsWithNumberOfMessagesBetweenDate } from './IRoomsModel';
export interface IAnalyticsModel extends IBaseModel<IAnalytics> {
saveMessageSent({ room, date }: { room: IRoom; date: IAnalytics['date'] }): Promise<Document | UpdateResult>;
saveUserData({ date }: { date: IAnalytics['date'] }): Promise<Document | UpdateResult>;
saveMessageDeleted({ room, date }: { room: { _id: string }; date: IAnalytics['date'] }): Promise<Document | UpdateResult>;
getMessagesSentTotalByDate(params: {
start: IAnalytics['date'];
end: IAnalytics['date'];
options?: { sort?: FindOptions<IAnalytics>['sort']; count?: number };
}): AggregationCursor<{
_id: IAnalytics['date'];
messages: number;
}>;
getMessagesOrigin({ start, end }: { start: IAnalytics['date']; end: IAnalytics['date'] }): AggregationCursor<{
t: IRoom['t'];
messages: number;
}>;
getMostPopularChannelsByMessagesSentQuantity(params: {
start: IAnalytics['date'];
end: IAnalytics['date'];
options?: { sort?: FindOptions<IAnalytics>['sort']; count?: number };
}): AggregationCursor<{
t: IRoom['t'];
name: string;
messages: number;
usernames: string[];
}>;
getTotalOfRegisteredUsersByDate(params: {
start: IAnalytics['date'];
end: IAnalytics['date'];
options?: { sort?: FindOptions<IAnalytics>['sort']; count?: number };
}): AggregationCursor<{
_id: IAnalytics['date'];
users: number;
}>;
findOneByTypeBeforeDate({ type, date }: { type: IAnalytics['type']; date: IAnalytics['date'] }): Promise<IAnalytics | null>;
findRoomsByTypesWithNumberOfMessagesBetweenDate(params: {
types: Array<IRoom['t']>;
start: number;
end: number;
startOfLastWeek: number;
endOfLastWeek: number;
options?: any;
}): AggregationCursor<{ channels: IChannelsWithNumberOfMessagesBetweenDate[]; total: number }>;
}

View File

@@ -0,0 +1,6 @@
import type { IBaseModel } from './IBaseModel';
// TODO: type for AppLogs
export interface IAppLogsModel extends IBaseModel<any> {
getDistinctFieldsForFilters(appId: string): Promise<{ instanceIds: string[]; methods: string[] }>;
}

View File

@@ -0,0 +1,4 @@
import type { IBaseModel } from './IBaseModel';
// TODO: type for AppLogs
export type IAppsModel = IBaseModel<any>;

View File

@@ -0,0 +1,8 @@
import type { DeleteResult, Filter } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
// TODO: type for appspersistence
export interface IAppsPersistenceModel extends IBaseModel<any> {
remove(query: Filter<any>): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,5 @@
import type { IAuditLog } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export type IAuditLogModel = IBaseModel<IAuditLog>;

View File

@@ -0,0 +1,9 @@
import type { IAvatar, IUser } from '@rocket.chat/core-typings';
import type { FindOptions } from 'mongodb';
import type { IBaseUploadsModel } from './IBaseUploadsModel';
export interface IAvatarsModel extends IBaseUploadsModel<IAvatar> {
findOneByUserId(userId: IUser['_id'], options?: FindOptions<IAvatarsModel>): Promise<IAvatar | null>;
findOneByETag(eTag: string, options?: FindOptions<IAvatarsModel>): Promise<IAvatar | null>;
}

View File

@@ -0,0 +1,22 @@
import type { IBannerDismiss } from '@rocket.chat/core-typings';
import type { Document, FindCursor, FindOptions } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IBannersDismissModel extends IBaseModel<IBannerDismiss> {
findByUserIdAndBannerId(userId: string, bannerIds: string[]): FindCursor<IBannerDismiss>;
findByUserIdAndBannerId(userId: string, bannerIds: string[], options: FindOptions<IBannerDismiss>): FindCursor<IBannerDismiss>;
findByUserIdAndBannerId<P extends Document>(
userId: string,
bannerIds: string[],
options: FindOptions<P extends IBannerDismiss ? IBannerDismiss : P>,
): FindCursor<P>;
findByUserIdAndBannerId<P extends Document>(
userId: string,
bannerIds: string[],
options?: FindOptions<IBannerDismiss> | FindOptions<P extends IBannerDismiss ? IBannerDismiss : P>,
): FindCursor<P> | FindCursor<IBannerDismiss>;
}

View File

@@ -0,0 +1,22 @@
import type { BannerPlatform, IBanner, Optional } from '@rocket.chat/core-typings';
import type { Document, FindCursor, UpdateResult, InsertOneResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IBannersModel extends IBaseModel<IBanner> {
create(doc: Optional<IBanner, '_updatedAt'>): Promise<InsertOneResult<IBanner>>;
findActiveByRoleOrId<T extends Document = IBanner, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roles: string[],
platform: BannerPlatform,
bannerId?: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
disable(bannerId: string): Promise<UpdateResult | Document>;
createOrUpdate(banner: Optional<IBanner, '_updatedAt'>): Promise<UpdateResult>;
findByIds(bannerIds: string[]): FindCursor<IBanner>;
}

View File

@@ -0,0 +1,157 @@
import type { RocketChatRecordDeleted } from '@rocket.chat/core-typings';
import type {
BulkWriteOptions,
ChangeStream,
ClientSession,
Collection,
CountDocumentsOptions,
DeleteOptions,
DeleteResult,
Document,
EnhancedOmit,
Filter,
FindCursor,
FindOneAndDeleteOptions,
FindOptions,
InsertManyResult,
InsertOneOptions,
InsertOneResult,
OptionalId,
UpdateFilter,
UpdateOptions,
UpdateResult,
WithId,
} from 'mongodb';
import type {
ApplyProjection,
DocumentWithDriverProjection,
DocumentWithProjection,
FindOneAndUpdateOptionsWithProjection,
FindOptionsWithProjection,
ProjectionSpec,
} from '../types/DocumentWithProjection';
import type { Updater } from '../updater';
export type DefaultFields<Base> = Partial<Record<keyof Base, 1>> | Partial<Record<keyof Base, 0>> | void;
export type ResultFields<Base, Defaults> = Defaults extends void | undefined
? Base
: Defaults extends ProjectionSpec
? ApplyProjection<Base, Defaults>
: Base;
export type InsertionModel<T> = EnhancedOmit<OptionalId<T>, '_updatedAt'> & {
_updatedAt?: Date;
};
export type FindPaginated<C> = {
cursor: C;
totalCount: Promise<number>;
};
export interface IBaseModel<
T extends { _id: string },
C extends DefaultFields<T> = undefined,
TDeleted extends RocketChatRecordDeleted<T> = RocketChatRecordDeleted<T>,
> {
col: Collection<T>;
createIndexes(): Promise<string[] | void>;
getCollectionName(): string;
getUpdater(): Updater<T>;
updateFromUpdater(query: Filter<T>, updater: Updater<T>, options?: UpdateOptions): Promise<UpdateResult>;
/**
* No projection narrowing: whether the model archives to a trash collection is a runtime detail
* (a constructor argument), and the trash path has to read the whole document to archive it, so
* it returns every field regardless of the projection. Narrowing here would claim a filtering
* that only happens for models without a trash collection.
*/
findOneAndDelete(filter: Filter<T>, options?: FindOneAndDeleteOptions): Promise<WithId<T> | null>;
findOneAndDeleteById(_id: T['_id'], options?: FindOneAndDeleteOptions): Promise<WithId<T> | null>;
findOneAndUpdate<P extends Document = T, O extends FindOneAndUpdateOptionsWithProjection = FindOneAndUpdateOptionsWithProjection>(
query: Filter<T>,
update: UpdateFilter<T> | T,
options?: O,
): Promise<DocumentWithDriverProjection<P, O> | null>;
findOneById(_id: T['_id'], options?: undefined): Promise<ResultFields<T, C> | null>;
findOneById<P extends Document = T, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
_id: T['_id'],
options?: O,
): Promise<DocumentWithProjection<P, O> | null>;
findOne(query?: Filter<T> | T['_id'], options?: undefined): Promise<ResultFields<T, C> | null>;
findOne<P extends Document = T, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
query: Filter<T> | T['_id'],
options?: O,
): Promise<DocumentWithProjection<P, O> | null>;
find(query?: Filter<T>): FindCursor<ResultFields<T, C>>;
find<P extends Document = T, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
query: Filter<T> | undefined,
options?: O,
): FindCursor<DocumentWithProjection<P, O>>;
findPaginated(query?: Filter<T>): FindPaginated<FindCursor<ResultFields<T, C>>>;
findPaginated<P extends Document = T, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
query: Filter<T> | undefined,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<P, O>>>;
update(
filter: Filter<T>,
update: UpdateFilter<T> | Partial<T>,
options?: UpdateOptions & { multi?: true },
): Promise<UpdateResult | Document>;
updateOne(filter: Filter<T>, update: UpdateFilter<T> | Partial<T>, options?: UpdateOptions): Promise<UpdateResult>;
updateMany(filter: Filter<T>, update: UpdateFilter<T> | Partial<T>, options?: UpdateOptions): Promise<Document | UpdateResult>;
insertMany(docs: InsertionModel<T>[], options?: BulkWriteOptions): Promise<InsertManyResult<T>>;
insertOne(doc: InsertionModel<T>, options?: InsertOneOptions): Promise<InsertOneResult<T>>;
removeById(_id: T['_id'], options?: { session?: ClientSession }): Promise<DeleteResult>;
removeByIds(ids: T['_id'][]): Promise<DeleteResult>;
deleteOne(filter: Filter<T>, options?: DeleteOptions & { bypassDocumentValidation?: boolean }): Promise<DeleteResult>;
deleteMany(filter: Filter<T>, options?: DeleteOptions & { onTrash?: (record: ResultFields<T, C>) => void }): Promise<DeleteResult>;
// Trash
trashFind<P extends TDeleted>(
query: Filter<TDeleted>,
options?: FindOptions<P extends TDeleted ? TDeleted : P>,
): FindCursor<WithId<TDeleted>> | undefined;
trashFindOneById(_id: TDeleted['_id']): Promise<TDeleted | null>;
trashFindOneById<P extends Document>(_id: TDeleted['_id'], options: FindOptions<P extends TDeleted ? TDeleted : P>): Promise<P | null>;
trashFindOneById<P extends TDeleted>(
_id: TDeleted['_id'],
options?: FindOptions<P extends TDeleted ? TDeleted : P>,
): Promise<WithId<RocketChatRecordDeleted<P> | TDeleted> | null>;
trashFindDeletedAfter(deletedAt: Date): FindCursor<WithId<TDeleted>>;
trashFindDeletedAfter<P extends Document = TDeleted>(
deletedAt: Date,
query?: Filter<TDeleted>,
options?: FindOptions<P extends TDeleted ? TDeleted : P>,
): FindCursor<WithId<TDeleted>>;
trashFindPaginatedDeletedAfter<P extends Document = TDeleted>(
deletedAt: Date,
query?: Filter<TDeleted>,
options?: FindOptions<P extends TDeleted ? TDeleted : P>,
): FindPaginated<FindCursor<WithId<TDeleted>>>;
watch(pipeline?: object[]): ChangeStream<T>;
countDocuments(query: Filter<T>, options?: CountDocumentsOptions): Promise<number>;
estimatedDocumentCount(): Promise<number>;
}

View File

@@ -0,0 +1,43 @@
import type { EncryptedContent, IUpload } from '@rocket.chat/core-typings';
import type { DeleteResult, UpdateResult, ClientSession, Document, InsertOneResult, WithId, FindCursor } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IBaseUploadsModel<T extends IUpload> extends IBaseModel<T> {
insertFileInit(userId: string, store: string, file: { name: string }, extra: object): Promise<InsertOneResult<WithId<IUpload>>>;
updateFileComplete(fileId: string, userId: string, file: object): Promise<Document | UpdateResult> | undefined;
confirmTemporaryFile(fileId: string, userId: string): Promise<Document | UpdateResult> | undefined;
findByIds<T_ extends Document = T, O extends FindOptionsWithProjection<T_> = FindOptionsWithProjection<T_>>(
_ids: string[],
options?: O,
): FindCursor<DocumentWithProjection<T_, O>>;
findOneByName(name: string, options?: { session?: ClientSession }): Promise<T | null>;
findOneByRoomId(rid: string): Promise<T | null>;
findExpiredTemporaryFiles<T_ extends Document = T, O extends FindOptionsWithProjection<T_> = FindOptionsWithProjection<T_>>(
options?: O,
): FindCursor<DocumentWithProjection<T_, O>>;
updateFileNameById(fileId: string, name: string): Promise<Document | UpdateResult>;
deleteFile(fileId: string, options?: { session?: ClientSession }): Promise<DeleteResult>;
findOneByIdAndUserIdAndRoomId<T_ extends Document = T, O extends FindOptionsWithProjection<T_> = FindOptionsWithProjection<T_>>(
fileId: string,
userId: string,
rid: string,
options?: O,
): Promise<DocumentWithProjection<T_, O> | null>;
updateFileMetadata(
fileId: string,
userId: string,
metadata: { name?: string; description?: string; typeGroup?: string; content?: EncryptedContent },
): Promise<UpdateResult | null>;
}

View File

@@ -0,0 +1,25 @@
import type { ICalendarEvent, IUser } from '@rocket.chat/core-typings';
import type { FindCursor, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface ICalendarEventModel extends IBaseModel<ICalendarEvent> {
findByUserIdAndDate(uid: IUser['_id'], date: Date): FindCursor<ICalendarEvent>;
updateEvent(eventId: ICalendarEvent['_id'], eventData: Partial<ICalendarEvent>): Promise<UpdateResult>;
findNextNotificationDate(): Promise<Date | null>;
findEventsToNotify(notificationTime: Date, minutes: number): FindCursor<ICalendarEvent>;
flagNotificationSent(eventId: ICalendarEvent['_id']): Promise<UpdateResult>;
findOneByExternalIdAndUserId(
externalId: Required<ICalendarEvent>['externalId'],
uid: ICalendarEvent['uid'],
): Promise<ICalendarEvent | null>;
findOverlappingEvents(eventId: ICalendarEvent['_id'], uid: IUser['_id'], startTime: Date, endTime: Date): FindCursor<ICalendarEvent>;
findNextFutureEvent(startTime: Date): Promise<Pick<ICalendarEvent, '_id' | 'startTime'> | null>;
findEventsStartingNow({
now,
offset,
}: {
now: Date;
offset?: number;
}): FindCursor<Pick<ICalendarEvent, '_id' | 'uid' | 'startTime' | 'endTime'>>;
}

View File

@@ -0,0 +1,35 @@
import type { CallHistoryItem, IRegisterUser, IUser } from '@rocket.chat/core-typings';
import type { FindCursor, Document } from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ICallHistoryModel extends IBaseModel<CallHistoryItem> {
findOneByIdAndUid<T extends Document = CallHistoryItem, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id: CallHistoryItem['_id'],
uid: CallHistoryItem['uid'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByCallIdAndUid<T extends Document = CallHistoryItem, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
callId: CallHistoryItem['callId'],
uid: CallHistoryItem['uid'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findAllByUserIdAndSearchFilters<
T extends Document = CallHistoryItem,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
uid: IUser['_id'],
filters: {
type?: CallHistoryItem['type'];
searchTerm?: string;
direction?: CallHistoryItem['direction'];
inStates?: CallHistoryItem['state'][];
},
options: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
updateUserReferences(userId: IRegisterUser['_id'], username: IRegisterUser['username'], name?: IRegisterUser['name']): Promise<void>;
}

View File

@@ -0,0 +1,35 @@
import type { IOmnichannelCannedResponse } from '@rocket.chat/core-typings';
import type { FindCursor, DeleteResult, UpdateResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ICannedResponseModel extends IBaseModel<IOmnichannelCannedResponse> {
findOneByShortcut<T extends Document = IOmnichannelCannedResponse, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
shortcut: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByDepartmentId<
T extends Document = IOmnichannelCannedResponse,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
departmentId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
removeById(_id: string): Promise<DeleteResult>;
createCannedResponse({
shortcut,
text,
tags,
scope,
userId,
departmentId,
createdBy,
_createdAt,
}: Omit<IOmnichannelCannedResponse, '_id' | '_updatedAt'>): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt'>>;
updateCannedResponse(
_id: string,
{ shortcut, text, tags, scope, userId, departmentId, createdBy }: Omit<IOmnichannelCannedResponse, '_id' | '_updatedAt' | '_createdAt'>,
): Promise<Omit<IOmnichannelCannedResponse, '_updatedAt' | '_createdAt'>>;
removeTagFromCannedResponses(tagId: string): Promise<UpdateResult | Document>;
}

View File

@@ -0,0 +1,9 @@
import type { ICredentialToken } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface ICredentialTokensModel extends IBaseModel<ICredentialToken> {
create(_id: string, userInfo: ICredentialToken['userInfo']): Promise<void>;
findOneNotExpiredById(_id: string): Promise<ICredentialToken | null>;
removeNotExpiredById(_id: string): Promise<ICredentialToken | null>;
}

View File

@@ -0,0 +1,5 @@
import type { ICronHistoryItem } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export type ICronHistoryModel = IBaseModel<ICronHistoryItem>;

View File

@@ -0,0 +1,20 @@
import type { ICustomSound } from '@rocket.chat/core-typings';
import type { FindCursor, InsertOneResult, UpdateResult, WithId, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ICustomSoundsModel extends IBaseModel<ICustomSound> {
findByName<T extends Document = ICustomSound, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
exceptId?: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findOneByName<T extends Document = ICustomSound, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
exceptId?: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
create(data: Omit<ICustomSound, '_id' | '_updatedAt'>): Promise<InsertOneResult<WithId<ICustomSound>>>;
updateById(_id: string, data: Partial<Omit<ICustomSound, '_id'>>): Promise<UpdateResult>;
}

View File

@@ -0,0 +1,29 @@
import type { ICustomUserStatus } from '@rocket.chat/core-typings';
import type { FindCursor, InsertOneResult, UpdateResult, WithId, Document } from 'mongodb';
import type { IBaseModel, InsertionModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ICustomUserStatusModel extends IBaseModel<ICustomUserStatus> {
findOneByName<T extends Document = ICustomUserStatus, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByNameExceptId<T extends Document = ICustomUserStatus, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
except: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByName<T extends Document = ICustomUserStatus, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByNameExceptId<T extends Document = ICustomUserStatus, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
except: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
setName(_id: string, name: string): Promise<UpdateResult>;
setStatusType(_id: string, statusType: string): Promise<UpdateResult>;
create(data: InsertionModel<ICustomUserStatus>): Promise<InsertOneResult<WithId<ICustomUserStatus>>>;
}

View File

@@ -0,0 +1,12 @@
import type { IEmailInbox } from '@rocket.chat/core-typings';
import type { FindCursor, InsertOneResult, WithId, UpdateFilter } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IEmailInboxModel extends IBaseModel<IEmailInbox> {
setDisabledById(id: IEmailInbox['_id']): Promise<null | WithId<IEmailInbox>>;
create(emailInbox: Omit<IEmailInbox, '_id'>): Promise<InsertOneResult<IEmailInbox>>;
updateById(id: IEmailInbox['_id'], data: UpdateFilter<IEmailInbox>): Promise<null | WithId<Pick<IEmailInbox, '_id'>>>;
findActive(): FindCursor<IEmailInbox>;
findByEmail(email: IEmailInbox['email']): Promise<IEmailInbox | null>;
}

View File

@@ -0,0 +1,8 @@
import type { IEmailMessageHistory } from '@rocket.chat/core-typings';
import type { InsertOneResult, WithId } from 'mongodb';
import type { IBaseModel, InsertionModel } from './IBaseModel';
export interface IEmailMessageHistoryModel extends IBaseModel<IEmailMessageHistory> {
create({ _id, email }: InsertionModel<IEmailMessageHistory>): Promise<InsertOneResult<WithId<IEmailMessageHistory>>>;
}

View File

@@ -0,0 +1,32 @@
import type { IEmojiCustom } from '@rocket.chat/core-typings';
import type { FindCursor, InsertOneResult, UpdateResult, WithId, Document } from 'mongodb';
import type { IBaseModel, InsertionModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IEmojiCustomModel extends IBaseModel<IEmojiCustom> {
findByNameOrAlias<T extends Document = IEmojiCustom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
emojiName: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findOneByNamesOrAliases<T extends Document = IEmojiCustom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
names: string[],
exceptId?: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByNameOrAliasExceptID<T extends Document = IEmojiCustom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
except: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
setName(_id: string, name: string): Promise<UpdateResult>;
setAliases(_id: string, aliases: string[]): Promise<UpdateResult>;
setExtension(_id: string, extension: string): Promise<UpdateResult>;
setETagByName(name: string, etag: string): Promise<UpdateResult>;
create(data: InsertionModel<IEmojiCustom>): Promise<InsertOneResult<WithId<IEmojiCustom>>>;
countByNameOrAlias(name: string): Promise<number>;
findOneByName<T extends Document = IEmojiCustom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
}

View File

@@ -0,0 +1,12 @@
import type { IExportOperation } from '@rocket.chat/core-typings';
import type { UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IExportOperationsModel extends IBaseModel<IExportOperation> {
findOnePending(): Promise<IExportOperation | null>;
create(data: IExportOperation): Promise<string>;
findLastOperationByUser(userId: string, fullExport: boolean): Promise<IExportOperation | null>;
updateOperation(data: IExportOperation): Promise<UpdateResult>;
countAllPendingBeforeMyRequest(requestDay: Date): Promise<number>;
}

View File

@@ -0,0 +1,21 @@
import type { FederationKey } from '@rocket.chat/core-typings';
import type NodeRSA from 'node-rsa';
import type { IBaseModel } from './IBaseModel';
export interface IFederationKeysModel extends IBaseModel<FederationKey> {
getKey(type: FederationKey['type']): Promise<string | null>;
loadKey(keyData: NodeRSA.Key, type: FederationKey['type']): NodeRSA;
generateKeys(): Promise<{
privateKey: '' | NodeRSA | null;
publicKey: '' | NodeRSA | null;
}>;
getPrivateKey(): Promise<'' | NodeRSA | null>;
getPublicKey(): Promise<'' | NodeRSA | null>;
getPublicKeyString(): Promise<string | null>;
}

View File

@@ -0,0 +1,12 @@
import type { IImportRecord, IImportUserRecord, IImportContactRecord, IImportChannelRecord } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface IImportDataModel extends IBaseModel<IImportRecord> {
getAllUsersForSelection(): Promise<Array<IImportUserRecord>>;
getAllChannelsForSelection(): Promise<Array<IImportChannelRecord>>;
getAllContactsForSelection(): Promise<IImportContactRecord[]>;
checkIfDirectMessagesExists(): Promise<boolean>;
countMessages(): Promise<number>;
findChannelImportIdByNameOrImportId(channelIdentifier: string): Promise<string | undefined>;
}

View File

@@ -0,0 +1,12 @@
import type { IImport } from '@rocket.chat/core-typings';
import type { UpdateResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IImportsModel extends IBaseModel<IImport> {
findLastImport(): Promise<IImport | undefined>;
invalidateAllOperations(): Promise<UpdateResult | Document>;
invalidateOperationsExceptId(id: string): Promise<UpdateResult | Document>;
increaseTotalCount(id: string, recordType: 'users' | 'channels' | 'messages', increaseBy?: number): Promise<UpdateResult>;
setOperationStatus(id: string, status: IImport['status']): Promise<UpdateResult>;
}

View File

@@ -0,0 +1,12 @@
import type { IInstanceStatus } from '@rocket.chat/core-typings';
import type { ChangeStream, DeleteResult, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IInstanceStatusModel extends IBaseModel<IInstanceStatus> {
watchActiveInstances(): ChangeStream<IInstanceStatus>;
removeInstanceById(_id: IInstanceStatus['_id']): Promise<DeleteResult>;
setDocumentHeartbeat(documentId: string): Promise<UpdateResult>;
upsertInstance(instance: Partial<IInstanceStatus>): Promise<IInstanceStatus | null>;
updateConnections(_id: IInstanceStatus['_id'], conns: number): Promise<UpdateResult>;
}

View File

@@ -0,0 +1,15 @@
import type { IIntegrationHistory } from '@rocket.chat/core-typings';
import type { FindOneAndUpdateOptions, InsertOneResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IIntegrationHistoryModel extends IBaseModel<IIntegrationHistory> {
removeByIntegrationId(integrationId: string): ReturnType<IBaseModel<IIntegrationHistory>['deleteMany']>;
findOneByIntegrationIdAndHistoryId(integrationId: string, historyId: string): Promise<IIntegrationHistory | null>;
create(integrationHistory: IIntegrationHistory): Promise<InsertOneResult<IIntegrationHistory>>;
updateById(
_id: IIntegrationHistory['_id'],
data: Partial<IIntegrationHistory>,
options?: FindOneAndUpdateOptions,
): Promise<IIntegrationHistory | null>;
}

View File

@@ -0,0 +1,30 @@
import type { IIntegration, IUser } from '@rocket.chat/core-typings';
import type { AggregateOptions, FindCursor, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export type IntegrationsStatistics = {
totalIntegrations: number;
totalIncoming: number;
totalIncomingActive: number;
totalOutgoing: number;
totalOutgoingActive: number;
totalWithScriptEnabled: number;
};
export interface IIntegrationsModel extends IBaseModel<IIntegration> {
disableByUserId(userId: IIntegration['userId']): ReturnType<IBaseModel<IIntegration>['updateMany']>;
findByChannels(channels: IIntegration['channel']): FindCursor<IIntegration>;
findByUserId(userId: IIntegration['userId']): FindCursor<Pick<IIntegration, '_id'>>;
findOneByIdAndCreatedByIfExists(params: { _id: IIntegration['_id']; createdBy?: IUser['_id'] }): Promise<IIntegration | null>;
removeByIdAndCreatedByIfExists(params: { _id: IIntegration['_id']; createdBy?: IUser['_id'] }): Promise<IIntegration | null>;
findOneByUrl(url: string): Promise<IIntegration | null>;
updateRoomName(oldRoomName: string, newRoomName: string): ReturnType<IBaseModel<IIntegration>['updateMany']>;
findOneByIdAndToken<P extends Document = IIntegration, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
id: IIntegration['_id'],
token: string,
options?: O,
): Promise<DocumentWithProjection<P, O> | null>;
getStatistics(options?: AggregateOptions): Promise<IntegrationsStatistics>;
}

View File

@@ -0,0 +1,10 @@
import type { IInvite } from '@rocket.chat/core-typings';
import type { UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IInvitesModel extends IBaseModel<IInvite> {
findOneByUserRoomMaxUsesAndExpiration(userId: string, rid: string, maxUses: number, daysToExpire: number): Promise<IInvite | null>;
increaseUsageById(_id: string, uses: number): Promise<UpdateResult>;
countUses(): Promise<number>;
}

View File

@@ -0,0 +1,44 @@
import type { ILivechatAgentActivity, IServiceHistory } from '@rocket.chat/core-typings';
import type { AggregationCursor, FindCursor, Document, WithId, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface ILivechatAgentActivityModel extends IBaseModel<ILivechatAgentActivity> {
findOneByAgendIdAndDate(agentId: string, date: ILivechatAgentActivity['date']): Promise<ILivechatAgentActivity | null>;
createOrUpdate(
data: Partial<Pick<ILivechatAgentActivity, 'date' | 'agentId' | 'lastStartedAt'>>,
): Promise<null | WithId<ILivechatAgentActivity> | undefined>;
updateLastStoppedAt(
params: Pick<ILivechatAgentActivity, 'date' | 'agentId' | 'lastStoppedAt' | 'availableTime'>,
): Promise<UpdateResult | Document>;
updateServiceHistory(
params: Pick<ILivechatAgentActivity, 'date' | 'agentId'> & { serviceHistory: IServiceHistory },
): Promise<UpdateResult | Document>;
findOpenSessions(): FindCursor<ILivechatAgentActivity>;
findAllAverageAvailableServiceTime(params: { date: Date; departmentId?: string }): Promise<
{
averageAvailableServiceTimeInSeconds: number;
}[]
>;
findAvailableServiceTimeHistory(p: {
start: string;
end: string;
fullReport: boolean;
onlyCount: true;
options?: { sort?: Record<string, number>; offset?: number; count?: number };
}): AggregationCursor<{ total: number }>;
findAvailableServiceTimeHistory(p: {
start: string;
end: string;
fullReport: boolean;
onlyCount?: false;
options?: { sort?: Record<string, number>; offset?: number; count?: number };
}): AggregationCursor<ILivechatAgentActivity>;
}

View File

@@ -0,0 +1,56 @@
import type { ILivechatBusinessHour, LivechatBusinessHourTypes } from '@rocket.chat/core-typings';
import type { Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IWorkHoursCronJobsItem {
day: string;
times: string[];
}
export interface IWorkHoursCronJobsWrapper {
start: IWorkHoursCronJobsItem[];
finish: IWorkHoursCronJobsItem[];
}
export interface ILivechatBusinessHoursModel extends IBaseModel<ILivechatBusinessHour> {
findActiveBusinessHours<
T extends Document = ILivechatBusinessHour,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
options?: O,
): Promise<DocumentWithProjection<T, O>[]>;
findOneDefaultBusinessHour<
P extends Document = ILivechatBusinessHour,
O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>,
>(
options?: O,
): Promise<DocumentWithProjection<P, O> | null>;
findActiveAndOpenBusinessHoursByDay<
T extends Document = ILivechatBusinessHour,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
day: string,
options?: O,
): Promise<DocumentWithProjection<T, O>[]>;
findDefaultActiveAndOpenBusinessHoursByDay(day: string, options?: any): Promise<ILivechatBusinessHour[]>;
insertOne(data: Omit<ILivechatBusinessHour, '_id' | '_updatedAt'>): Promise<any>;
findHoursToScheduleJobs(): Promise<IWorkHoursCronJobsWrapper[]>;
findActiveBusinessHoursToOpen(
day: string,
start: string,
type?: LivechatBusinessHourTypes,
options?: any,
): Promise<ILivechatBusinessHour[]>;
findActiveBusinessHoursToClose(
day: string,
finish: string,
type?: LivechatBusinessHourTypes,
options?: any,
): Promise<ILivechatBusinessHour[]>;
disableBusinessHour(businessHourId: string): Promise<any>;
}

View File

@@ -0,0 +1,76 @@
import type {
AtLeast,
ILivechatContact,
ILivechatContactChannel,
ILivechatContactVisitorAssociation,
ILivechatVisitor,
} from '@rocket.chat/core-typings';
import type { AggregationCursor, Document, FindCursor, FindOneAndUpdateOptions, UpdateFilter, UpdateOptions, UpdateResult } from 'mongodb';
import type { Updater } from '../updater';
import type { FindPaginated, IBaseModel, InsertionModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILivechatContactsModel extends IBaseModel<ILivechatContact> {
insertContact(
data: InsertionModel<Omit<ILivechatContact, 'createdAt'>> & { createdAt?: ILivechatContact['createdAt'] },
): Promise<ILivechatContact['_id']>;
patchContact(
contactId: string,
data: {
set?: Partial<ILivechatContact>;
unset?: Partial<Record<keyof ILivechatContact, '' | 1>>;
},
options?: FindOneAndUpdateOptions,
): Promise<ILivechatContact | null>;
updateById(contactId: string, update: UpdateFilter<ILivechatContact>, options?: UpdateOptions): Promise<Document | UpdateResult>;
addChannel(contactId: string, channel: ILivechatContactChannel): Promise<void>;
findPaginatedContacts<T extends Document = ILivechatContact, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
search: { searchText?: string; unknown?: boolean },
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
updateLastChatById(
contactId: string,
visitor: ILivechatContactVisitorAssociation,
lastChat: ILivechatContact['lastChat'],
): Promise<UpdateResult>;
findContactMatchingVisitor(visitor: AtLeast<ILivechatVisitor, 'visitorEmails' | 'phone'>): Promise<ILivechatContact | null>;
findContactByEmailAndContactManager(email: string): Promise<Pick<ILivechatContact, 'contactManager'> | null>;
findOneByVisitor<T extends Document = ILivechatContact, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
visitor: ILivechatContactVisitorAssociation,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
isChannelBlocked(visitor: ILivechatContactVisitorAssociation): Promise<boolean>;
updateFromUpdaterByAssociation(
visitor: ILivechatContactVisitorAssociation,
contactUpdater: Updater<ILivechatContact>,
options?: UpdateOptions,
): Promise<UpdateResult>;
findSimilarVerifiedContacts<T extends Document = ILivechatContact, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
channel: Pick<ILivechatContactChannel, 'field' | 'value'>,
originalContactId: string,
options?: O,
): Promise<DocumentWithProjection<T, O>[]>;
findAllByVisitorId(visitorId: string): FindCursor<ILivechatContact>;
addEmail(contactId: string, email: string): Promise<ILivechatContact | null>;
isContactActiveOnPeriod(visitor: ILivechatContactVisitorAssociation, period: string): Promise<number>;
markContactActiveForPeriod(visitor: ILivechatContactVisitorAssociation, period: string): Promise<UpdateResult>;
countContactsOnPeriod(period: string): Promise<number>;
setChannelBlockStatus(visitor: ILivechatContactVisitorAssociation, blocked: boolean): Promise<UpdateResult>;
setChannelVerifiedStatus(visitor: ILivechatContactVisitorAssociation, verified: boolean): Promise<UpdateResult>;
setVerifiedUpdateQuery(verified: boolean, contactUpdater: Updater<ILivechatContact>): Updater<ILivechatContact>;
setFieldAndValueUpdateQuery(field: string, value: string, contactUpdater: Updater<ILivechatContact>): Updater<ILivechatContact>;
countByContactInfo({ contactId, email, phone }: { contactId?: string; email?: string; phone?: string }): Promise<number>;
countUnknown(): Promise<number>;
countBlocked(): Promise<number>;
countFullyBlocked(): Promise<number>;
countVerified(): Promise<number>;
countContactsWithoutChannels(): Promise<number>;
getStatistics(): AggregationCursor<{ totalConflicts: number; avgChannelsPerContact: number }>;
disableByVisitorId(visitorId: string): Promise<UpdateResult | Document>;
disableByContactId(contactId: string): Promise<UpdateResult>;
findOneEnabledById<P extends Document = ILivechatContact, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
_id: ILivechatContact['_id'],
options?: O,
): Promise<DocumentWithProjection<P, O> | null>;
}

View File

@@ -0,0 +1,38 @@
import type { ILivechatCustomField } from '@rocket.chat/core-typings';
import type { FindCursor, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILivechatCustomFieldModel extends IBaseModel<ILivechatCustomField> {
findByScope<T extends Document = ILivechatCustomField, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
scope: ILivechatCustomField['scope'],
options?: O,
includeHidden?: boolean,
): FindCursor<DocumentWithProjection<T, O>>;
findMatchingCustomFields<
T extends Document = ILivechatCustomField,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
scope: ILivechatCustomField['scope'],
searchable: boolean,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findMatchingCustomFieldsByIds<
T extends Document = ILivechatCustomField,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
ids: ILivechatCustomField['_id'][],
scope: ILivechatCustomField['scope'],
searchable: boolean,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
createOrUpdateCustomField(
_id: string | null,
field: string,
label: ILivechatCustomField['label'],
scope: ILivechatCustomField['scope'],
visibility: ILivechatCustomField['visibility'],
extraData: any,
): Promise<ILivechatCustomField>;
}

View File

@@ -0,0 +1,68 @@
import type { AvailableAgentsAggregation, ILivechatDepartmentAgents } from '@rocket.chat/core-typings';
import type { DeleteResult, FindCursor, Document, UpdateResult, Filter, AggregationCursor } from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILivechatDepartmentAgentsModel extends IBaseModel<ILivechatDepartmentAgents> {
findByAgentId<T extends Document = ILivechatDepartmentAgents, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
agentId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findAgentsByDepartmentId<
P extends Document = ILivechatDepartmentAgents,
O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>,
>(
departmentId: string,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<P, O>>>;
findByDepartmentIds(departmentIds: string[], options?: Record<string, any>): FindCursor<ILivechatDepartmentAgents>;
setDepartmentEnabledByDepartmentId(departmentId: string, departmentEnabled: boolean): Promise<Document | UpdateResult>;
removeByDepartmentId(departmentId: string): Promise<DeleteResult>;
findByDepartmentId<T extends Document = ILivechatDepartmentAgents, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
departmentId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findOneByAgentIdAndDepartmentId<
T extends Document = ILivechatDepartmentAgents,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
agentId: string,
departmentId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
saveAgent(agent: Omit<ILivechatDepartmentAgents, '_id' | '_updatedAt'>): Promise<UpdateResult>;
removeByAgentId(agentId: string): Promise<DeleteResult>;
getNextAgentForDepartment(
departmentId: ILivechatDepartmentAgents['departmentId'],
isLivechatEnabledWhenAgentIdle?: boolean,
ignoreAgentId?: ILivechatDepartmentAgents['agentId'],
extraQuery?: Filter<AvailableAgentsAggregation>,
acceptChatsWithNoAgents?: boolean,
): Promise<Pick<ILivechatDepartmentAgents, '_id' | 'agentId' | 'departmentId' | 'username'> | null | undefined>;
countBotsForDepartment(departmentId: string): Promise<number>;
getNextBotForDepartment(
departmentId: ILivechatDepartmentAgents['departmentId'],
ignoreAgentId?: ILivechatDepartmentAgents['agentId'],
): Promise<Pick<ILivechatDepartmentAgents, '_id' | 'agentId' | 'departmentId' | 'username'> | null | undefined>;
replaceUsernameOfAgentByUserId(userId: string, username: string): Promise<UpdateResult | Document>;
countByDepartmentId(departmentId: string): Promise<number>;
disableAgentsByDepartmentId(departmentId: string): Promise<UpdateResult | Document>;
enableAgentsByDepartmentId(departmentId: string): Promise<UpdateResult | Document>;
findAllAgentsConnectedToListOfDepartments(departmentIds: string[]): Promise<string[]>;
findByAgentIds<T extends Document = ILivechatDepartmentAgents, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
agentIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByAgentsAndDepartmentId<
T extends Document = ILivechatDepartmentAgents,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
agentsIds: ILivechatDepartmentAgents['agentId'][],
departmentId: ILivechatDepartmentAgents['departmentId'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findDepartmentsOfAgent(agentId: string, enabled?: boolean): AggregationCursor<ILivechatDepartmentAgents & { departmentName: string }>;
}

View File

@@ -0,0 +1,100 @@
import type { ILivechatDepartment, LivechatDepartmentDTO } from '@rocket.chat/core-typings';
import type { FindOptions, FindCursor, Filter, UpdateResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILivechatDepartmentModel extends IBaseModel<ILivechatDepartment> {
countTotal(): Promise<number>;
findInIds<T extends Document = ILivechatDepartment, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
departmentsIds: string[],
options: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByNameRegexWithExceptionsAndConditions<
T extends Document = ILivechatDepartment,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
searchTerm: string,
exceptions: string[],
conditions: Filter<ILivechatDepartment>,
options: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByBusinessHourId<T extends Document = ILivechatDepartment, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
businessHourId: string,
options: O,
): FindCursor<DocumentWithProjection<T, O>>;
countByBusinessHourIdExcludingDepartmentId(businessHourId: string, departmentId: string): Promise<number>;
findEnabledByBusinessHourId<
T extends Document = ILivechatDepartment,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
businessHourId: string,
options: O,
): FindCursor<DocumentWithProjection<T, O>>;
findActiveDepartmentsWithoutBusinessHour<
T extends Document = ILivechatDepartment,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
options: O,
): FindCursor<DocumentWithProjection<T, O>>;
addBusinessHourToDepartmentsByIds(ids: string[], businessHourId: string): Promise<Document | UpdateResult>;
removeBusinessHourFromDepartmentsByIdsAndBusinessHourId(ids: string[], businessHourId: string): Promise<Document | UpdateResult>;
removeBusinessHourFromDepartmentsByBusinessHourId(businessHourId: string): Promise<Document | UpdateResult>;
createOrUpdateDepartment(_id: string | null, data: LivechatDepartmentDTO & { type?: string }): Promise<ILivechatDepartment>;
unsetFallbackDepartmentByDepartmentId(departmentId: string): Promise<Document | UpdateResult>;
removeDepartmentFromForwardListById(_departmentId: string): Promise<void>;
updateById(_id: string, update: Partial<ILivechatDepartment>): Promise<Document | UpdateResult>;
updateNumAgentsById(_id: string, numAgents: number): Promise<Document | UpdateResult>;
decreaseNumberOfAgentsByIds(_ids: string[]): Promise<Document | UpdateResult>;
findEnabledWithAgents<T extends Document = ILivechatDepartment>(
projection?: FindOptions<ILivechatDepartment>['projection'],
): FindCursor<T>;
findEnabledWithAgentsAndBusinessUnit<T extends Document = ILivechatDepartment>(
_: any,
projection: FindOptions<T>['projection'],
): FindCursor<T>;
findOneByIdOrName<T extends Document = ILivechatDepartment, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_idOrName: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByUnitIds<T extends Document = ILivechatDepartment, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
unitIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countDepartmentsInUnit(unitId: string): Promise<number>;
findActiveByUnitIds<T extends Document = ILivechatDepartment, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
unitIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findNotArchived<T extends Document = ILivechatDepartment, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
getBusinessHoursWithDepartmentStatuses(): Promise<
{
_id: string;
validDepartments: string[];
invalidDepartments: string[];
}[]
>;
checkIfMonitorIsMonitoringDepartmentById(monitorId: string, departmentId: string): Promise<boolean>;
countArchived(): Promise<number>;
findEnabledInIds<T extends Document = ILivechatDepartment, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
departmentsIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
archiveDepartment(_id: string): Promise<UpdateResult>;
unarchiveDepartment(_id: string): Promise<UpdateResult>;
addDepartmentToUnit(_id: string, unitId: string, ancestors: string[]): Promise<Document | UpdateResult>;
removeDepartmentFromUnit(_id: string): Promise<Document | UpdateResult>;
findEnabledWithAgentsAndRegistration<T extends Document = ILivechatDepartment>(projection?: FindOptions<T>['projection']): FindCursor<T>;
findOneEnabledWithAgentsAndRegistration<T extends Document = ILivechatDepartment>(
projection?: FindOptions<T>['projection'],
): Promise<T | null>;
}

View File

@@ -0,0 +1,49 @@
import type { IMessage, ILivechatInquiryRecord, LivechatInquiryStatus, SelectedAgent } from '@rocket.chat/core-typings';
import type { FindOptions, Document, UpdateResult, DeleteResult, FindCursor, DeleteOptions, AggregateOptions } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILivechatInquiryModel extends IBaseModel<ILivechatInquiryRecord> {
findOneByRoomId<T extends Document = ILivechatInquiryRecord, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
getDistinctQueuedDepartments(options: AggregateOptions): Promise<{ _id: string | null }[]>;
setDepartmentByInquiryId(inquiryId: string, department: string): Promise<ILivechatInquiryRecord | null>;
setLastMessageByRoomId(rid: ILivechatInquiryRecord['rid'], message: IMessage): Promise<ILivechatInquiryRecord | null>;
setLastMessageById(inquiryId: string, lastMessage: IMessage): Promise<UpdateResult>;
findNextAndLock(
queueSortBy: FindOptions<ILivechatInquiryRecord>['sort'],
department: string | null,
): Promise<ILivechatInquiryRecord | null>;
unlock(inquiryId: string): Promise<UpdateResult>;
unlockAll(): Promise<UpdateResult | Document>;
getCurrentSortedQueueAsync(props: {
inquiryId?: string;
department?: string;
queueSortBy: FindOptions<ILivechatInquiryRecord>['sort'];
}): Promise<(Pick<ILivechatInquiryRecord, '_id' | 'rid' | 'name' | 'ts' | 'status' | 'department'> & { position: number })[]>;
removeByRoomId(rid: string, options?: DeleteOptions): Promise<DeleteResult>;
getQueuedInquiries<T extends Document = ILivechatInquiryRecord, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
takeInquiry(inquiryId: string, lockedAt?: Date): Promise<UpdateResult>;
queueInquiry(inquiryId: string, lastMessage?: IMessage, defaultAgent?: SelectedAgent | null): Promise<ILivechatInquiryRecord | null>;
queueInquiryAndRemoveDefaultAgent(inquiryId: string): Promise<UpdateResult>;
readyInquiry(inquiryId: string): Promise<UpdateResult>;
changeDepartmentIdByRoomId(rid: string, department: string): Promise<UpdateResult>;
getStatus(inquiryId: string): Promise<ILivechatInquiryRecord['status'] | undefined>;
updateVisitorStatus(token: string, status: ILivechatInquiryRecord['v']['status']): Promise<UpdateResult>;
setDefaultAgentById(inquiryId: string, defaultAgent: ILivechatInquiryRecord['defaultAgent']): Promise<UpdateResult>;
setNameByRoomId(rid: string, name: string): Promise<UpdateResult>;
findOneByToken(token: string): Promise<ILivechatInquiryRecord | null>;
removeDefaultAgentById(inquiryId: string): Promise<UpdateResult | Document>;
markInquiryActiveForPeriod(rid: ILivechatInquiryRecord['rid'], period: string): Promise<ILivechatInquiryRecord | null>;
setStatusById(inquiryId: string, status: LivechatInquiryStatus): Promise<ILivechatInquiryRecord>;
updateNameByVisitorIds(visitorIds: string[], name: string): Promise<UpdateResult | Document>;
findByVisitorIds<T extends Document = ILivechatInquiryRecord, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
visitorIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
}

View File

@@ -0,0 +1,13 @@
import type { ILivechatPriority } from '@rocket.chat/core-typings';
import type { FindCursor, WithId } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface ILivechatPriorityModel extends IBaseModel<ILivechatPriority> {
findOneByIdOrName(_idOrName: string, options?: any): Promise<ILivechatPriority | null>;
findOneNameUsingRegex(_idOrName: string, options?: any): Promise<ILivechatPriority | null>;
findByDirty(): FindCursor<Pick<ILivechatPriority, '_id'>>;
canResetPriorities(): Promise<boolean>;
resetPriorities(ids: ILivechatPriority['_id'][]): Promise<void>;
updatePriority(_id: string, reset: boolean, name?: string): Promise<null | WithId<ILivechatPriority>>;
}

View File

@@ -0,0 +1,316 @@
import type {
IMessage,
IOmnichannelRoom,
IOmnichannelRoomClosingInfo,
ILivechatVisitor,
MACStats,
ILivechatContactVisitorAssociation,
AtLeast,
ILivechatContact,
} from '@rocket.chat/core-typings';
import type { FindCursor, UpdateResult, AggregationCursor, Document, FindOptions, DeleteResult, Filter, UpdateOptions } from 'mongodb';
import type { FindPaginated } from '..';
import type { Updater } from '../updater';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
type Period = {
start: any;
end: any;
};
type WithDepartment = {
departmentId: any;
};
type WithOnlyCount = {
onlyCount?: boolean;
};
type WithOptions = {
options?: any;
};
// TODO: Fix types of model
export interface ILivechatRoomsModel extends IBaseModel<IOmnichannelRoom> {
getUpdater(): Updater<IOmnichannelRoom>;
getQueueMetrics(params: { departmentId: any; agentId: any; includeOfflineAgents: any; options?: any }): any;
findAllNumberOfAbandonedRooms(
params: Period & WithDepartment & WithOnlyCount & WithOptions & { inactivityTimeout: number },
): Promise<any>;
findPercentageOfAbandonedRooms(
params: Period & WithDepartment & WithOnlyCount & WithOptions & { inactivityTimeout: number },
): Promise<any>;
findAllAverageOfChatDurationTime(params: Period & WithDepartment & WithOnlyCount & WithOptions): any;
findAllAverageWaitingTime(params: Period & WithDepartment & WithOnlyCount & WithOptions): any;
findAllRooms(params: Period & WithDepartment & WithOnlyCount & WithOptions & { answered: any }): any;
findAllServiceTime(params: Period & WithDepartment & WithOnlyCount & WithOptions): any;
findAllNumberOfTransferredRooms(params: Period & WithDepartment & WithOptions): any;
countAllOpenChatsBetweenDate(params: Period & WithDepartment): any;
countAllClosedChatsBetweenDate(params: Period & WithDepartment): any;
countAllQueuedChatsBetweenDate(params: Period & WithDepartment): any;
countAllOpenChatsByAgentBetweenDate(params: Period & WithDepartment): any;
countAllOnHoldChatsByAgentBetweenDate(params: Period & WithDepartment): any;
countAllClosedChatsByAgentBetweenDate(params: Period & WithDepartment): any;
countAllOpenChatsByDepartmentBetweenDate(params: Period & WithDepartment): any;
countAllClosedChatsByDepartmentBetweenDate(params: Period & WithDepartment): any;
calculateResponseTimingsBetweenDates(params: Period & WithDepartment): any;
calculateReactionTimingsBetweenDates(params: Period & WithDepartment): any;
calculateDurationTimingsBetweenDates(params: Period & WithDepartment): any;
findAllAverageOfServiceTime(params: Period & WithDepartment & WithOnlyCount & WithOptions): any;
findByVisitorId(visitorId: any, options: any, extraQuery?: any): any;
findPaginatedByVisitorId(visitorId: any, options: any, extraQuery?: any): any;
findRoomsByVisitorIdAndMessageWithCriteria(params: {
visitorId: any;
searchText: any;
open: any;
served: any;
onlyCount?: boolean;
options?: any;
source?: string;
}): any;
findRoomsWithCriteria(params: {
agents: any;
roomName: any;
departmentId: any;
open: any;
served?: any;
createdAt: any;
closedAt: any;
tags: any;
customFields: any;
visitorId?: any;
roomIds?: any;
onhold: any;
queued: any;
options?: any;
extraQuery?: any;
}): FindPaginated<FindCursor<IOmnichannelRoom>>;
getOnHoldConversationsBetweenDate(from: any, to: any, departmentId: any): any;
findAllServiceTimeByAgent(params: Period & WithOptions & WithOnlyCount): any;
findAllAverageServiceTimeByAgents(params: Period & WithOptions & WithOnlyCount): any;
setDepartmentByRoomId(roomId: any, departmentId: any): any;
findOpen(extraQuery?: Filter<IOmnichannelRoom>): FindCursor<IOmnichannelRoom>;
setAutoTransferOngoingById(roomId: string): Promise<UpdateResult>;
unsetAutoTransferOngoingById(roomId: string): Promise<UpdateResult>;
setAutoTransferredAtById(roomId: string): Promise<UpdateResult>;
findAvailableSources(): AggregationCursor<Document>;
setPdfTranscriptFileIdById(rid: string, fileId: string): Promise<UpdateResult>;
setEmailTranscriptRequestedByRoomId(
rid: string,
transcriptInfo: NonNullable<IOmnichannelRoom['transcriptRequest']>,
): Promise<UpdateResult>;
unsetEmailTranscriptRequestedByRoomId(rid: string): Promise<UpdateResult>;
closeRoomById(roomId: string, closeInfo: IOmnichannelRoomClosingInfo, options?: UpdateOptions): Promise<UpdateResult>;
bulkRemoveDepartmentAndUnitsFromRooms(departmentId: string): Promise<Document | UpdateResult>;
findOneByIdOrName<T extends Document = IOmnichannelRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_idOrName: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
updateSurveyFeedbackById(_id: string, surveyFeedback: unknown): Promise<UpdateResult>;
updateDataByToken(token: string, key: string, value: string, overwrite?: boolean): Promise<UpdateResult | Document | boolean>;
saveRoomById(
data: { _id: string; topic?: string; tags?: string[]; livechatData?: Record<string, any> } & Record<string, unknown>,
): Promise<UpdateResult | undefined>;
findByIds(
ids: string[],
fields?: FindOptions<IOmnichannelRoom>['projection'],
extraQuery?: Filter<IOmnichannelRoom>,
): FindCursor<IOmnichannelRoom>;
findOneByIdAndVisitorToken(
_id: string,
visitorToken: string,
fields?: FindOptions<IOmnichannelRoom>['projection'],
): Promise<IOmnichannelRoom | null>;
findOneByVisitorTokenAndEmailThreadAndDepartment<
T extends Document = IOmnichannelRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
visitorToken: string,
emailThread: string[],
departmentId?: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
updateEmailThreadByRoomId(roomId: string, threadIds: string[] | string): Promise<UpdateResult>;
findOneLastServedAndClosedByVisitorToken<
T extends Document = IOmnichannelRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
visitorToken: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByVisitorToken(visitorToken: string, fields?: FindOptions<IOmnichannelRoom>['projection']): Promise<IOmnichannelRoom | null>;
findOpenByVisitorToken<T extends Document = IOmnichannelRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
visitorToken: string,
options?: O,
extraQuery?: Filter<IOmnichannelRoom>,
): FindCursor<DocumentWithProjection<T, O>>;
findOneOpenByContactChannelVisitor<
T extends Document = IOmnichannelRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
association: ILivechatContactVisitorAssociation,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneOpenByVisitorToken<T extends Document = IOmnichannelRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
visitorToken: string,
options?: O,
extraQuery?: Filter<IOmnichannelRoom>,
): Promise<DocumentWithProjection<T, O> | null>;
findOneOpenByVisitorTokenAndDepartmentIdAndSource<
T extends Document = IOmnichannelRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
visitorToken: string,
departmentId?: string,
source?: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOpenByVisitorTokenAndDepartmentId<
T extends Document = IOmnichannelRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
visitorToken: string,
departmentId: string,
options?: O,
extraQuery?: Filter<IOmnichannelRoom>,
): FindCursor<DocumentWithProjection<T, O>>;
findByVisitorIdAndAgentId<T extends Document = IOmnichannelRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
visitorId?: string,
agentId?: string,
options?: O,
extraQuery?: Filter<IOmnichannelRoom>,
): FindCursor<DocumentWithProjection<T, O>>;
findOneOpenByRoomIdAndVisitorToken<
T extends Document = IOmnichannelRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
roomId: string,
visitorToken: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findClosedRooms<T extends Document = IOmnichannelRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
departmentIds?: string[],
options?: O,
extraQuery?: Filter<IOmnichannelRoom>,
): FindCursor<DocumentWithProjection<T, O>>;
getResponseByRoomIdUpdateQuery(
responseBy: IOmnichannelRoom['responseBy'],
updater?: Updater<IOmnichannelRoom>,
): Updater<IOmnichannelRoom>;
getNotResponseByRoomIdUpdateQuery(updater: Updater<IOmnichannelRoom>): Updater<IOmnichannelRoom>;
getAgentLastMessageTsUpdateQuery(updater?: Updater<IOmnichannelRoom>): Updater<IOmnichannelRoom>;
getAnalyticsUpdateQueryBySentByAgent(
room: IOmnichannelRoom,
message: IMessage,
analyticsData: Record<string, string | number | Date> | undefined,
updater?: Updater<IOmnichannelRoom>,
): Updater<IOmnichannelRoom>;
getAnalyticsUpdateQueryBySentByVisitor(
room: IOmnichannelRoom,
message: IMessage,
updater?: Updater<IOmnichannelRoom>,
): Updater<IOmnichannelRoom>;
getTotalConversationsBetweenDate(t: 'l', date: { gte: Date; lte: Date }, data?: { departmentId: string }): Promise<number>;
getAnalyticsMetricsBetweenDate(
t: 'l',
date: { gte: Date; lte: Date },
data?: { departmentId?: string },
extraQuery?: Filter<IOmnichannelRoom>,
): FindCursor<Pick<IOmnichannelRoom, 'ts' | 'departmentId' | 'open' | 'servedBy' | 'responseBy' | 'metrics' | 'msgs'>>;
getAnalyticsMetricsBetweenDateWithMessages(
t: string,
date: { gte: Date; lte: Date },
data?: { departmentId?: string },
extraQuery?: Document,
extraMatchers?: Document,
): AggregationCursor<Pick<IOmnichannelRoom, '_id' | 'ts' | 'departmentId' | 'open' | 'servedBy' | 'metrics' | 'msgs'>>;
getAnalyticsBetweenDate(
date: { gte: Date; lte: Date },
data?: { departmentId: string },
): AggregationCursor<Pick<IOmnichannelRoom, 'ts' | 'departmentId' | 'open' | 'servedBy' | 'metrics' | 'msgs' | 'onHold'>>;
findOpenByAgent<T extends Document = IOmnichannelRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
extraQuery?: Filter<IOmnichannelRoom>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countOpenByAgent(userId: string, extraQuery?: Filter<IOmnichannelRoom>): Promise<number>;
changeAgentByRoomId(roomId: string, newAgent: { agentId: string; username: string }): Promise<UpdateResult>;
changeDepartmentIdByRoomId(roomId: string, departmentId: string): Promise<UpdateResult>;
saveCRMDataByRoomId(roomId: string, crmData: unknown): Promise<UpdateResult>;
updateVisitorStatus(token: string, status: ILivechatVisitor['status']): Promise<UpdateResult | Document>;
removeAgentByRoomId(roomId: string): Promise<UpdateResult>;
removeByVisitorId(_id: string): Promise<DeleteResult>;
removeById(_id: string): Promise<DeleteResult>;
getVisitorLastMessageTsUpdateQueryByRoomId(lastMessageTs: Date, updater?: Updater<IOmnichannelRoom>): Updater<IOmnichannelRoom>;
setVisitorInactivityInSecondsById(roomId: string, visitorInactivity: any): Promise<UpdateResult>;
unarchiveOneById(roomId: string): Promise<UpdateResult>;
getVisitorActiveForPeriodUpdateQuery(
period: string,
updater?: Updater<IOmnichannelRoom>,
currentActivity?: string[] | null,
): Updater<IOmnichannelRoom>;
getMACStatisticsForPeriod(period: string): Promise<MACStats[]>;
getMACStatisticsBetweenDates(start: Date, end: Date): Promise<MACStats[]>;
findNewestByContactVisitorAssociation<T extends Document = IOmnichannelRoom>(
association: ILivechatContactVisitorAssociation,
options?: Omit<FindOptions<IOmnichannelRoom>, 'sort' | 'limit'>,
): Promise<T | null>;
setContactByVisitorAssociation(
association: ILivechatContactVisitorAssociation,
contact: Pick<AtLeast<ILivechatContact, '_id'>, '_id' | 'name'>,
): Promise<UpdateResult | Document>;
findClosedRoomsByContactPaginated(params: { contactId: string; options?: FindOptions }): FindPaginated<FindCursor<IOmnichannelRoom>>;
findClosedRoomsByContactAndSourcePaginated(params: {
contactId: string;
source?: string;
options?: FindOptions;
}): FindPaginated<FindCursor<IOmnichannelRoom>>;
countLivechatRoomsWithDepartment(): Promise<number>;
updateContactDataByContactId(
oldContactId: ILivechatContact['_id'],
contact: Partial<Pick<ILivechatContact, '_id' | 'name'>>,
): Promise<UpdateResult | Document>;
findOpenByContactId<T extends Document = IOmnichannelRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
contactId: ILivechatContact['_id'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
checkContactOpenRooms(contactId: ILivechatContact['_id']): Promise<Pick<IOmnichannelRoom, '_id'> | null>;
}

View File

@@ -0,0 +1,13 @@
import type { ILivechatTag } from '@rocket.chat/core-typings';
import type { DeleteResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface ILivechatTagModel extends IBaseModel<ILivechatTag> {
createOrUpdateTag(
_id: string | undefined,
{ name, description }: { name: string; description?: string },
departments?: string[],
): Promise<Omit<ILivechatTag, '_updatedAt'>>;
removeById(_id: string): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,9 @@
import type { ILivechatTrigger } from '@rocket.chat/core-typings';
import type { FindCursor, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface ILivechatTriggerModel extends IBaseModel<ILivechatTrigger> {
findEnabled(): FindCursor<ILivechatTrigger>;
updateById(_id: string, data: Omit<ILivechatTrigger, '_id' | '_updatedAt'>): Promise<UpdateResult>;
}

View File

@@ -0,0 +1,44 @@
import type { ILivechatDepartment, IOmnichannelBusinessUnit } from '@rocket.chat/core-typings';
import type { Filter, FindCursor, DeleteResult, UpdateResult, Document } from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILivechatUnitModel extends IBaseModel<IOmnichannelBusinessUnit> {
//
findPaginatedUnits<T extends Document = IOmnichannelBusinessUnit, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
query: Filter<IOmnichannelBusinessUnit>,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
// `extra` carries the unit restrictions applied to the query before it reaches `BaseRaw.findOne`,
// so the projection is rewritten as usual and inference behaves like every other model
findOne<P extends Document = IOmnichannelBusinessUnit, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
originalQuery: Filter<IOmnichannelBusinessUnit>,
options?: O,
extra?: Record<string, any>,
): Promise<DocumentWithProjection<P, O> | null>;
findOneById<P extends Document = IOmnichannelBusinessUnit, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
_id: IOmnichannelBusinessUnit['_id'],
options?: O,
extra?: Record<string, any>,
): Promise<DocumentWithProjection<P, O> | null>;
createOrUpdateUnit(
_id: string | null,
{ name, visibility }: { name: string; visibility: IOmnichannelBusinessUnit['visibility'] },
ancestors: string[],
monitors: { monitorId: string; username: string }[],
departments: { departmentId: string }[],
): Promise<Omit<IOmnichannelBusinessUnit, '_updatedAt'>>;
removeParentAndAncestorById(parentId: string): Promise<UpdateResult | Document>;
incrementDepartmentsCount(_id: string): Promise<UpdateResult | Document>;
decrementDepartmentsCount(_id: string): Promise<UpdateResult | Document>;
removeById(_id: string): Promise<DeleteResult>;
removeByIdAndUnit(_id: string, unitsFromUser?: string[]): Promise<DeleteResult>;
findOneByIdOrName<T extends Document = IOmnichannelBusinessUnit, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_idOrName: string,
options: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByMonitorId(monitorId: string): Promise<string[]>;
findMonitoredDepartmentsByMonitorId(monitorId: string, includeDisabled: boolean): Promise<ILivechatDepartment[]>;
countUnits(): Promise<number>;
}

View File

@@ -0,0 +1,13 @@
import type { ILivechatUnitMonitor } from '@rocket.chat/core-typings';
import type { FindCursor, UpdateResult, DeleteResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface ILivechatUnitMonitorsModel extends IBaseModel<ILivechatUnitMonitor> {
findByUnitId(unitId: string): FindCursor<ILivechatUnitMonitor>;
findByMonitorId(monitorId: string): FindCursor<ILivechatUnitMonitor>;
saveMonitor(monitor: { monitorId: string; unitId: string; username: string }): Promise<UpdateResult>;
removeByUnitIdAndMonitorId(unitId: string, monitorId: string): Promise<DeleteResult>;
removeByUnitId(unitId: string): Promise<DeleteResult>;
removeByMonitorId(monitorId: string): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,108 @@
import type { IVisitorExternalIdentifier, ILivechatVisitor } from '@rocket.chat/core-typings';
import type {
AggregationCursor,
FindCursor,
Filter,
FindOptions,
UpdateResult,
Document,
UpdateFilter,
FindOneAndUpdateOptions,
WithId,
} from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILivechatVisitorsModel extends IBaseModel<ILivechatVisitor> {
findById<T extends Document = ILivechatVisitor, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByIds<T extends Document = ILivechatVisitor, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
ids: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
getVisitorByToken<T extends Document = ILivechatVisitor, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
token: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByNameRegexWithExceptionsAndConditions<P extends Document = ILivechatVisitor>(
searchTerm: string,
exceptions: string[],
conditions: Filter<ILivechatVisitor>,
options?: FindOptions<P extends ILivechatVisitor ? ILivechatVisitor : P>,
): AggregationCursor<
P & {
custom_name: string;
}
>;
findPaginatedVisitorsByEmailOrPhoneOrNameOrUsernameOrCustomField<
T extends Document = ILivechatVisitor,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
emailOrPhone?: string,
nameOrUsername?: RegExp,
allowedCustomFields?: string[],
options?: O,
): Promise<FindPaginated<FindCursor<DocumentWithProjection<T, O>>>>;
findOneByEmailAndPhoneAndCustomField(
email: string | null | undefined,
phone: string | null | undefined,
customFields?: { [key: string]: RegExp },
): Promise<ILivechatVisitor | null>;
removeContactManagerByUsername(manager: string): Promise<UpdateResult | Document>;
updateAllLivechatDataByToken(token: string, livechatDataToUpdate: Record<string, string>): Promise<UpdateResult>;
updateLivechatDataByToken(token: string, key: string, value: unknown, overwrite: boolean): Promise<UpdateResult | Document | boolean>;
findOneGuestByEmailAddress(emailAddress: string): Promise<ILivechatVisitor | null>;
findOneVisitorByPhone(phone: string): Promise<ILivechatVisitor | null>;
findOneVisitorByPhoneOrEmailAndAddExternalId(
contactData: { phone: string } | { email: string },
appId: string,
externalId: Omit<IVisitorExternalIdentifier, 'appId'>,
): Promise<ILivechatVisitor | null>;
findOneByExternalId(entityId: string): Promise<ILivechatVisitor | null>;
updateExternalIdById(_id: string, appId: string, externalId: Omit<IVisitorExternalIdentifier, 'appId'>): Promise<ILivechatVisitor | null>;
removeDepartmentById(_id: string): Promise<Document | UpdateResult>;
getNextVisitorUsername(): Promise<string>;
updateLastAgentByToken(token: string, lastAgent: ILivechatVisitor['lastAgent']): Promise<Document | UpdateResult>;
updateById(_id: string, update: UpdateFilter<ILivechatVisitor>): Promise<Document | UpdateResult>;
updateOneByIdOrToken(update: UpdateFilter<ILivechatVisitor>, options?: FindOneAndUpdateOptions): Promise<null | WithId<ILivechatVisitor>>;
saveGuestEmailPhoneById(_id: string, emails: string[], phones: string[]): Promise<UpdateResult | Document | void>;
findOneEnabledById<T extends Document = ILivechatVisitor, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
disableById(_id: string): Promise<UpdateResult>;
findEnabled<T extends Document = ILivechatVisitor, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
query: Filter<ILivechatVisitor>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
saveGuestById(
_id: string,
data: { name?: string; username?: string; email?: string; phone?: string; livechatData: { [k: string]: any } },
): Promise<UpdateResult | Document | boolean>;
setLastChatById(_id: string, lastChat: Required<ILivechatVisitor['lastChat']>): Promise<UpdateResult>;
countVisitorsBetweenDate({ start, end, department }: { start: Date; end: Date; department?: string }): Promise<number>;
updateDepartmentById(_id: string, department: string): Promise<null | WithId<ILivechatVisitor>>;
}

View File

@@ -0,0 +1,8 @@
import type { ILoginCode } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface ILoginCodesModel extends IBaseModel<ILoginCode> {
createCode(userId: string): Promise<string>;
findOneNotExpiredByCodeAndDelete(code: string): Promise<ILoginCode | null>;
}

View File

@@ -0,0 +1,17 @@
import type { LoginServiceConfiguration } from '@rocket.chat/core-typings';
import type { Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ILoginServiceConfigurationModel extends IBaseModel<LoginServiceConfiguration> {
createOrUpdateService(
serviceName: LoginServiceConfiguration['service'],
serviceData: Partial<LoginServiceConfiguration>,
): Promise<LoginServiceConfiguration['_id']>;
removeByService(serviceName: LoginServiceConfiguration['service']): Promise<Pick<LoginServiceConfiguration, '_id'> | null>;
findOneByService<P extends Document = LoginServiceConfiguration, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
serviceName: LoginServiceConfiguration['service'],
options?: O,
): Promise<DocumentWithProjection<P, O> | null>;
}

View File

@@ -0,0 +1,15 @@
import type { IMediaCallNegotiation, MediaCallNegotiationStream, RTCSessionDescriptionInit } from '@rocket.chat/core-typings';
import type { Document, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IMediaCallNegotiationsModel extends IBaseModel<IMediaCallNegotiation> {
findLatestByCallId<T extends Document = IMediaCallNegotiation, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
callId: IMediaCallNegotiation['callId'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
setOfferById(id: string, offer: RTCSessionDescriptionInit, offerStreams?: MediaCallNegotiationStream[]): Promise<UpdateResult>;
setAnswerById(id: string, answer: RTCSessionDescriptionInit, answerStreams?: MediaCallNegotiationStream[]): Promise<UpdateResult>;
setStableById(id: string): Promise<UpdateResult>;
}

View File

@@ -0,0 +1,44 @@
import type {
IMediaCall,
IUser,
MediaCallActor,
MediaCallActorType,
MediaCallContact,
MediaCallSignedContact,
} from '@rocket.chat/core-typings';
import type { Document, FindCursor, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IMediaCallsModel extends IBaseModel<IMediaCall> {
findOneByIdAndCallee<T extends Document = IMediaCall, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
id: IMediaCall['_id'],
callee: MediaCallActor,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByCallerRequestedId<T extends Document = IMediaCall, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
id: Required<IMediaCall>['callerRequestedId'],
caller: { type: MediaCallActorType; id: string },
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
startRingingById(callId: string, expiresAt: Date): Promise<UpdateResult>;
acceptCallById(
callId: string,
data: { calleeContractId: string; supportedFeatures: string[]; sipCallId?: string },
expiresAt: Date,
): Promise<UpdateResult>;
activateCallById(callId: string, expiresAt: Date): Promise<UpdateResult>;
setExpiresAtById(callId: string, expiresAt: Date): Promise<UpdateResult>;
hangupCallById(callId: string, params: { endedBy?: IMediaCall['endedBy']; reason?: string } | undefined): Promise<UpdateResult>;
transferCallById(callId: string, params: { by: MediaCallSignedContact; to: MediaCallContact }): Promise<UpdateResult>;
findAllExpiredCalls<T extends Document = IMediaCall, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findAllNotOverByUid<T extends Document = IMediaCall, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
uid: IUser['_id'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
hasUnfinishedCalls(): Promise<boolean>;
hasUnfinishedCallsByUid(uid: IUser['_id'], exceptCallId?: string): Promise<boolean>;
}

View File

@@ -0,0 +1,12 @@
import type { MessageReads, IUser, IMessage } from '@rocket.chat/core-typings';
import type { UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IMessageReadsModel extends IBaseModel<MessageReads> {
findOneByUserIdAndThreadId(userId: IUser['_id'], tmid: IMessage['_id']): Promise<MessageReads | null>;
getMinimumLastSeenByThreadId(tmid: string): Promise<MessageReads | null>;
updateReadTimestampByUserIdAndThreadId(userId: IUser['_id'], tmid: IMessage['_id']): Promise<UpdateResult>;
countByThreadAndUserIds(tmid: IMessage['_id'], userIds: IUser['_id'][]): Promise<number>;
countByThreadId(tmid: IMessage['_id']): Promise<number>;
}

View File

@@ -0,0 +1,369 @@
import type {
IMessage,
IRoom,
IUser,
ILivechatDepartment,
MessageTypesValues,
MessageAttachment,
IMessageWithPendingFileImport,
} from '@rocket.chat/core-typings';
import type {
AggregationCursor,
CountDocumentsOptions,
FindCursor,
FindOptions,
AggregateOptions,
InsertOneResult,
DeleteResult,
UpdateResult,
Document,
Filter,
WithId,
} from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
type PaginatedRequest<S extends string = string> = {
count?: number;
offset?: number;
sort?: `{ "${S}": ${1 | -1} }` | string;
/* deprecated */
query?: string;
};
export interface IMessagesModel extends IBaseModel<IMessage> {
findPaginatedVisibleByMentionAndRoomId<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
username: IUser['username'],
rid: IRoom['_id'],
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findVisibleByMentionAndRoomId<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
username: IUser['username'],
rid: IRoom['_id'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findStarredByUserAtRoom<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: IUser['_id'],
roomId: IRoom['_id'],
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findPaginatedByRoomIdAndType<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: IRoom['_id'],
type: IMessage['t'],
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findDiscussionsByRoomAndText<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: IRoom['_id'],
text: string,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findAllNumberOfTransferredRooms(p: {
start: Date;
end: Date;
departmentId?: ILivechatDepartment['_id'];
onlyCount: true;
options?: PaginatedRequest;
}): AggregationCursor<{ total: number }>;
findAllNumberOfTransferredRooms(p: {
start: Date;
end: Date;
departmentId?: ILivechatDepartment['_id'];
onlyCount?: false;
options?: PaginatedRequest;
}): AggregationCursor<{ _id: string | null; numberOfTransferredRooms: number }>;
getTotalOfMessagesSentByDate(params: { start: Date; end: Date; options?: any }): Promise<any[]>;
findLivechatClosedMessages<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: IRoom['_id'],
searchTerm?: string,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findLivechatMessagesWithoutTypes<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: IRoom['_id'],
ignoredTypes: IMessage['t'][],
showSystemMessages: boolean,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countRoomsWithStarredMessages(options: AggregateOptions): Promise<number>;
countRoomsWithPinnedMessages(options: AggregateOptions): Promise<number>;
setBlocksById(_id: string, blocks: Required<IMessage>['blocks']): Promise<void>;
countRoomsWithMessageType(type: IMessage['t'], options: AggregateOptions): Promise<number>;
countByType(type: IMessage['t'], options: CountDocumentsOptions): Promise<number>;
findPaginatedPinnedByRoom<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: IMessage['rid'],
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
setFederationReactionEventId(username: string, _id: string, reaction: string, federationEventId: string): Promise<void>;
unsetFederationReactionEventId(federationEventId: string, _id: string, reaction: string): Promise<void>;
findOneByFederationId(federationEventId: string): Promise<IMessage | null>;
findLatestFederationThreadMessageByTmid(tmid: string, messageId: IMessage['_id']): Promise<IMessage | null>;
setFederationEventIdById(_id: string, federationEventId: string): Promise<void>;
removeByRoomId(roomId: IRoom['_id']): Promise<DeleteResult>;
findVisibleByRoomIdNotContainingTypesBeforeTs<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
roomId: IRoom['_id'],
types: IMessage['t'][],
ts: Date,
showSystemMessages: boolean,
options?: O,
showThreadMessages?: boolean,
): FindCursor<DocumentWithProjection<T, O>>;
findLivechatClosingMessage<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: IRoom['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
setReactions(messageId: string, reactions: IMessage['reactions']): Promise<UpdateResult>;
setRoomIdByToken(token: string, rid: string): Promise<UpdateResult | Document>;
createWithTypeRoomIdMessageUserAndUnread(
type: MessageTypesValues,
rid: string,
message: string,
user: Pick<IMessage['u'], '_id' | 'username' | 'name'>,
unread?: boolean,
extraData?: Partial<IMessage>,
): Promise<InsertOneResult<IMessage>>;
unsetReactions(messageId: string): Promise<UpdateResult>;
addTranslations(messageId: string, translations: Record<string, string>, providerName: string): Promise<UpdateResult>;
addAttachmentTranslations(messageId: string, attachmentIndex: string, translations: Record<string, string>): Promise<UpdateResult>;
setImportFileRocketChatAttachment(
importFileId: string,
rocketChatUrl: string,
attachment: MessageAttachment,
): Promise<UpdateResult | Document>;
countVisibleByRoomIdBetweenTimestampsInclusive(roomId: string, afterTimestamp: Date, beforeTimestamp: Date): Promise<number>;
findByMention<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
username: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findVisibleThreadByThreadId<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
tmid: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findFilesByUserId(userId: string, options?: FindOptions<IMessage>): FindCursor<Pick<IMessage, 'file' | 'files'>>;
findVisibleByIds<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
ids: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findVisibleByRoomIdNotContainingTypes<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
roomId: string,
types: MessageTypesValues[],
options?: O,
showThreadMessages?: boolean,
): FindCursor<DocumentWithProjection<T, O>>;
countVisibleByRoomIdContainingTypes(roomId: string, types: MessageTypesValues[]): Promise<number>;
findFilesByRoomIdPinnedTimestampAndUsers<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
rid: string,
excludePinned: boolean,
ignoreDiscussion: boolean,
ts: Filter<IMessage>['ts'],
users: string[],
ignoreThreads: boolean,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findVisibleByRoomId<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findDiscussionByRoomIdPinnedTimestampAndUsers<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
rid: string,
excludePinned: boolean,
ts: Filter<IMessage>['ts'],
users: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findVisibleByRoomIdAfterTimestamp<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
timestamp: Date,
showThreadMessages?: boolean,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findVisibleByRoomIdBeforeTimestampNotContainingTypes<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
roomId: string,
timestamp: Date,
types: MessageTypesValues[],
options?: O,
showThreadMessages?: boolean,
inclusive?: boolean,
): FindCursor<DocumentWithProjection<T, O>>;
findVisibleByRoomIdBetweenTimestampsNotContainingTypes<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
roomId: string,
afterTimestamp: Date,
beforeTimestamp: Date,
types: MessageTypesValues[],
options?: O,
showThreadMessages?: boolean,
inclusive?: boolean,
): FindCursor<DocumentWithProjection<T, O>>;
countVisibleByRoomIdBetweenTimestampsNotContainingTypes(
roomId: string,
afterTimestamp: Date,
beforeTimestamp: Date,
types: MessageTypesValues[],
showThreadMessages?: boolean,
inclusive?: boolean,
): Promise<number>;
findVisibleByRoomIdBeforeTimestamp<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
timestamp: Date,
showThreadMessages?: boolean,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
getLastTimestamp(options?: FindOptions<IMessage>): Promise<Date | undefined>;
findOneBySlackBotIdAndSlackTs(slackBotId: string, slackTs: Date): Promise<IMessage | null>;
findByRoomIdAndMessageIds<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
messageIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findForUpdates<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: IMessage['rid'],
{ updatedAt, minTs }: { updatedAt: { $lt: Date } | { $gt: Date }; minTs?: Date },
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
updateUsernameOfEditByUserId(userId: string, username: string): Promise<UpdateResult | Document>;
updateAllUsernamesByUserId(userId: string, username: string): Promise<UpdateResult | Document>;
setUrlsById(_id: string, urls: NonNullable<IMessage['urls']>): Promise<UpdateResult>;
getLastVisibleUserMessageSentByRoomId(rid: string, messageId?: string): Promise<IMessage | null>;
findOneBySlackTs(slackTs: Date): Promise<IMessage | null>;
cloneAndSaveAsHistoryById(_id: string, user: IMessage['u']): Promise<InsertOneResult<IMessage>>;
cloneAndSaveAsHistoryByRecord(record: IMessage, user: IMessage['u']): Promise<InsertOneResult<IMessage>>;
setAsDeletedByIdAndUser(_id: string, user: IMessage['u']): Promise<UpdateResult>;
setAsDeletedByIdsAndUser(_ids: string[], user: IMessage['u']): Promise<Document | UpdateResult>;
setHiddenById(_id: string, hidden: boolean): Promise<UpdateResult>;
setHiddenByIds(_ids: string[], hidden: boolean): Promise<Document | UpdateResult>;
setPinnedByIdAndUserId(
_id: string,
pinnedBy: Pick<IUser, '_id' | 'username'> | undefined,
pinned?: boolean,
pinnedAt?: Date,
): Promise<UpdateResult>;
findOneByRoomIdAndMessageId<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
messageId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneVisibleByRoomIdAndMessageId<T extends Document = IMessage, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
messageId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
updateUserStarById(_id: string, userId: string, starred?: boolean): Promise<UpdateResult>;
updateUsernameAndMessageOfMentionByIdAndOldUsername(
_id: string,
oldUsername: string,
newUsername: string,
newMessage: string,
): Promise<UpdateResult>;
unlinkUserId(userId: string, newUserId: string, newUsername: string, newNameAlias: string): Promise<UpdateResult | Document>;
setReceiptsArchivedById(ids: string[], archived: boolean): Promise<UpdateResult | Document>;
setSlackBotIdAndSlackTs(_id: string, slackBotId: string, slackTs: Date): Promise<UpdateResult>;
setMessageAttachments(_id: string, attachments: IMessage['attachments']): Promise<UpdateResult>;
removeByRoomIds(rids: string[]): Promise<DeleteResult>;
findThreadsByRoomIdPinnedTimestampAndUsers<
T extends Document = IMessage,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
data: { rid: string; pinned: boolean; ignoreDiscussion?: boolean; ts: Filter<IMessage>['ts']; users: string[] },
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
removeByIdPinnedTimestampLimitAndUsers(
rid: string,
ignorePinned: boolean,
ignoreDiscussion: boolean,
ts: Filter<IMessage>['ts'],
limit: number,
users: string[],
ignoreThreads: boolean,
selectedMessageIds?: string[],
): Promise<number>;
findByIdPinnedTimestampLimitAndUsers(
rid: string,
ignorePinned: boolean,
ignoreDiscussion: boolean,
ts: Filter<IMessage>['ts'],
limit: number,
users: string[],
ignoreThreads: boolean,
): Promise<string[]>;
removeByUserId(userId: string): Promise<DeleteResult>;
getThreadFollowsByThreadId(tmid: string): Promise<string[] | undefined>;
setVisibleMessagesAsRead(rid: string, until: Date): Promise<UpdateResult | Document>;
getMessageByFileIdAndUsername(fileID: string, userId: string): Promise<IMessage | null>;
getMessageByFileId(fileID: string): Promise<IMessage | null>;
setThreadMessagesAsRead(rid: string, tmid: string, until: Date): Promise<UpdateResult | Document>;
updateRepliesByThreadId(tmid: string, replies: string[], ts: Date): Promise<UpdateResult>;
refreshDiscussionMetadata(room: Pick<IRoom, '_id' | 'msgs' | 'lm'>): Promise<null | WithId<IMessage>>;
findUnreadThreadMessagesByDate(
rid: string,
tmid: string,
userId: string,
after: Date,
): FindCursor<Pick<IMessage, '_id' | 't' | 'pinned' | 'drid' | 'tmid'>>;
findVisibleUnreadMessagesByRoomAndDate(rid: string, after: Date): FindCursor<Pick<IMessage, '_id' | 't' | 'pinned' | 'drid' | 'tmid'>>;
setAsReadById(_id: string): Promise<UpdateResult>;
countThreads(): Promise<number>;
addThreadFollowerByThreadId(tmid: string, userId: string): Promise<UpdateResult>;
findAllImportedMessagesWithFilesToDownload(): FindCursor<IMessageWithPendingFileImport>;
countAllImportedMessagesWithFilesToDownload(): Promise<number>;
findAgentLastMessageByVisitorLastMessageTs(roomId: string, visitorLastMessageTs: Date): Promise<IMessage | null>;
removeThreadFollowerByThreadId(tmid: string, userId: string): Promise<UpdateResult>;
findThreadsByRoomId(rid: string, skip: number, limit: number): FindCursor<IMessage>;
decreaseReplyCountById(_id: string, inc?: number): Promise<IMessage | null>;
countPinned(options?: CountDocumentsOptions): Promise<number>;
countStarred(options?: CountDocumentsOptions): Promise<number>;
removeFileAttachmentsByMessageIds(_ids: string[], replaceWith?: MessageAttachment): Promise<Document | UpdateResult>;
clearFilesByMessageIds(_ids: string[]): Promise<Document | UpdateResult>;
}

View File

@@ -0,0 +1,5 @@
import type { IControl } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export type IMigrationsModel = IBaseModel<IControl>;

View File

@@ -0,0 +1,75 @@
import type { IModerationReport, IMessage, IModerationAudit, MessageReport, UserReport } from '@rocket.chat/core-typings';
import type { AggregationCursor, Document, FindCursor, FindOptions, UpdateResult } from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
export type PaginationParams<T extends Document> = {
count: number;
offset: number;
sort: FindOptions<T>['sort'];
};
export interface IModerationReportsModel extends IBaseModel<IModerationReport> {
createWithMessageDescriptionAndUserId(
message: IMessage,
description: string,
room: IModerationReport['room'],
reportedBy: IModerationReport['reportedBy'],
): ReturnType<IBaseModel<IModerationReport>['insertOne']>;
createWithDescriptionAndUser(
reportedUser: Exclude<IModerationReport['reportedUser'], undefined>,
description: string,
reportedBy: IModerationReport['reportedBy'],
): ReturnType<IBaseModel<IModerationReport>['insertOne']>;
findMessageReportsGroupedByUser(
latest: Date,
oldest: Date,
selector: string,
pagination: PaginationParams<IModerationReport>,
): AggregationCursor<IModerationAudit>;
findUserReports(
latest: Date,
oldest: Date,
selector: string,
pagination: PaginationParams<IModerationReport>,
): AggregationCursor<Pick<UserReport, '_id' | 'reportedUser' | 'ts'> & { count: number }>;
getTotalUniqueReportedUsers(latest: Date, oldest: Date, selector: string, isMessageReports?: boolean): Promise<number>;
countMessageReportsInRange(latest: Date, oldest: Date, selector: string): Promise<number>;
findReportsByMessageId(
messageId: IMessage['_id'],
selector: string,
pagination: PaginationParams<IModerationReport>,
options?: FindOptions<IModerationReport>,
): FindPaginated<FindCursor<Pick<IModerationReport, '_id' | 'description' | 'reportedBy' | 'ts' | 'room'>>>;
findReportedMessagesByReportedUserId(
userId: string,
selector: string,
pagination: PaginationParams<IModerationReport>,
options?: FindOptions<IModerationReport>,
): FindPaginated<FindCursor<Pick<MessageReport, '_id' | 'message' | 'ts' | 'room'>>>;
findUserReportsByReportedUserId(
userId: string,
selector: string,
pagination: PaginationParams<IModerationReport>,
options?: FindOptions<IModerationReport>,
): FindPaginated<FindCursor<Omit<UserReport, 'moderationInfo'>>>;
hideMessageReportsByMessageId(
messageId: IMessage['_id'],
userId: string,
reason: string,
action: string,
): Promise<UpdateResult | Document>;
hideMessageReportsByUserId(userId: string, moderatorId: string, reason: string, action: string): Promise<UpdateResult | Document>;
hideUserReportsByUserId(userId: string, moderatorId: string, reason: string, action: string): Promise<UpdateResult | Document>;
}

View File

@@ -0,0 +1,12 @@
import type { INotification } from '@rocket.chat/core-typings';
import type { Document, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface INotificationQueueModel extends IBaseModel<INotification> {
unsetSendingById(_id: string): Promise<UpdateResult>;
setErrorById(_id: string, error: any): Promise<UpdateResult>;
clearScheduleByUserId(uid: string): Promise<UpdateResult | Document>;
clearQueueByUserId(uid: string): Promise<number | undefined>;
findNextInQueueOrExpired(expired: Date): Promise<INotification | null>;
}

View File

@@ -0,0 +1,19 @@
import type { INps, NPSStatus } from '@rocket.chat/core-typings';
import type { Document, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface INpsModel extends IBaseModel<INps> {
getOpenExpiredAndStartSending(): Promise<INps | null>;
getOpenExpiredAlreadySending(): Promise<INps | null>;
updateStatusById(_id: INps['_id'], status: INps['status']): Promise<UpdateResult>;
save({
_id,
startAt,
expireAt,
createdBy,
status,
}: Pick<INps, '_id' | 'startAt' | 'expireAt' | 'createdBy' | 'status'>): Promise<UpdateResult>;
closeAllByStatus(status: NPSStatus): Promise<UpdateResult | Document>;
}

View File

@@ -0,0 +1,28 @@
import type { INpsVote, INpsVoteStatus } from '@rocket.chat/core-typings';
import type { Document, FindCursor, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface INpsVoteModel extends IBaseModel<INpsVote> {
// `sort` and `limit` are branded away because the implementation overwrites both on the cursor;
// a caller passing them would have them silently dropped
findNotSentByNpsId<T extends Document = INpsVote, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
npsId: string,
options?: O & { sort?: never; limit?: never },
): FindCursor<DocumentWithProjection<T, O>>;
findByNpsIdAndStatus<T extends Document = INpsVote, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
npsId: string,
status: INpsVoteStatus,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByNpsId<T extends Document = INpsVote, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
npsId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
save(vote: Omit<INpsVote, '_id' | '_updatedAt'>): Promise<UpdateResult>;
updateVotesToSent(voteIds: string[]): Promise<UpdateResult | Document>;
updateOldSendingToNewByNpsId(npsId: string): Promise<UpdateResult | Document>;
countByNpsId(npsId: string): Promise<number>;
countByNpsIdAndStatus(npsId: string, status: INpsVoteStatus): Promise<number>;
}

View File

@@ -0,0 +1,18 @@
import type { IOAuthAccessToken } from '@rocket.chat/core-typings';
import type { DeleteResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IOAuthAccessTokensModel extends IBaseModel<IOAuthAccessToken> {
findOneByAccessToken<T extends Document = IOAuthAccessToken, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
accessToken: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByRefreshToken<T extends Document = IOAuthAccessToken, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
refreshToken: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
deleteByUserId(userId: string): Promise<DeleteResult>;
deleteByUserIds(userIds: string[]): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,36 @@
import type { IOAuthApps } from '@rocket.chat/core-typings';
import type { Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IOAuthAppsModel extends IBaseModel<IOAuthApps> {
findOneAuthAppByIdOrClientId<T extends Document = IOAuthApps, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
props:
| { clientId: string }
| { appId: string }
| {
_id: string;
},
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneActiveByClientId<T extends Document = IOAuthApps, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
clientId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
updateById(
_id: IOAuthApps['_id'],
data: Partial<Pick<IOAuthApps, 'name' | 'active' | 'redirectUri' | '_updatedBy'>>,
): Promise<IOAuthApps | null>;
findOneActiveByClientIdAndClientSecret<
T extends Document = IOAuthApps,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
clientId: string,
clientSecret: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
}

View File

@@ -0,0 +1,14 @@
import type { IOAuthAuthCode } from '@rocket.chat/core-typings';
import type { DeleteResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IOAuthAuthCodesModel extends IBaseModel<IOAuthAuthCode> {
findOneByAuthCode<T extends Document = IOAuthAuthCode, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
authCode: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
deleteByUserId(userId: string): Promise<DeleteResult>;
deleteByUserIds(userIds: string[]): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,14 @@
import type { IOAuthRefreshToken } from '@rocket.chat/core-typings';
import type { DeleteResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IOAuthRefreshTokensModel extends IBaseModel<IOAuthRefreshToken> {
findOneByRefreshToken<T extends Document = IOAuthRefreshToken, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
refreshToken: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
deleteByUserId(userId: string): Promise<DeleteResult>;
deleteByUserIds(userIds: string[]): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,10 @@
import type { IOEmbedCache } from '@rocket.chat/core-typings';
import type { DeleteResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IOEmbedCacheModel extends IBaseModel<IOEmbedCache> {
createWithIdAndData(_id: string, data: any): Promise<IOEmbedCache>;
removeBeforeDate(date: Date): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,16 @@
import type { IOmnichannelServiceLevelAgreements } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface IOmnichannelServiceLevelAgreementsModel extends IBaseModel<IOmnichannelServiceLevelAgreements> {
findOneByIdOrName(_idOrName: string, options?: any): Promise<IOmnichannelServiceLevelAgreements | null>;
createOrUpdatePriority(
{ name, description, dueTimeInMinutes }: Pick<IOmnichannelServiceLevelAgreements, 'name' | 'description' | 'dueTimeInMinutes'>,
_id: string | null,
): Promise<Omit<IOmnichannelServiceLevelAgreements, '_updatedAt'>>;
findDuplicate(
_id: string | null,
name: string,
dueTimeInMinutes: number,
): Promise<Pick<IOmnichannelServiceLevelAgreements, '_id'> | null>;
}

View File

@@ -0,0 +1,13 @@
import type { IPermission, IRole } from '@rocket.chat/core-typings';
import type { FindCursor } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IPermissionsModel extends IBaseModel<IPermission> {
createOrUpdate(name: string, roles: IRole['_id'][]): Promise<IPermission['_id']>;
create(id: string, roles: IRole['_id'][]): Promise<IPermission['_id']>;
addRole(permission: string, role: IRole['_id']): Promise<void>;
setRoles(permission: string, roles: IRole['_id'][]): Promise<void>;
removeRole(permission: string, role: IRole['_id']): Promise<void>;
findByLevel(level: 'settings', settingId?: string): FindCursor<IPermission>;
}

View File

@@ -0,0 +1,38 @@
import type { AtLeast, IPushToken, IUser } from '@rocket.chat/core-typings';
import type { DeleteResult, InsertOneResult, UpdateResult, FindCursor, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IPushTokenModel extends IBaseModel<IPushToken> {
countTokensByUserId(userId: IUser['_id']): Promise<number>;
countGcmTokens(): Promise<number>;
countApnTokens(): Promise<number>;
findOneByTokenAndAppName(token: IPushToken['token'], appName: IPushToken['appName']): Promise<IPushToken | null>;
findFirstByUserId<T extends Document = IPushToken, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: IUser['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findAllTokensByUserId<T extends Document = IPushToken, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: IUser['_id'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findTokensByUserIdExceptId<T extends Document = IPushToken, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: IUser['_id'],
idToIgnore: IPushToken['_id'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
insertToken(data: AtLeast<IPushToken, 'token' | 'authToken' | 'appName' | 'userId'>): Promise<InsertOneResult<IPushToken>>;
refreshTokenById(
id: IPushToken['_id'],
data: Pick<IPushToken, 'token' | 'appName' | 'authToken' | 'userId' | 'voipToken'>,
): Promise<UpdateResult<IPushToken>>;
removeByUserIdExceptTokens(userId: string, tokens: IPushToken['authToken'][]): Promise<DeleteResult>;
removeDuplicateTokens(tokenData: Pick<IPushToken, '_id' | 'token' | 'appName' | 'authToken'>): Promise<DeleteResult>;
removeAllByUserId(userId: string): Promise<DeleteResult>;
removeAllByTokenStringAndUserId(token: string, userId: string): Promise<DeleteResult>;
removeOrUnsetByTokenString(token: string): Promise<void>;
}

View File

@@ -0,0 +1,14 @@
import type { IReadReceipt } from '@rocket.chat/core-typings';
import type { FindCursor, DeleteResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IReadReceiptsModel extends IBaseModel<IReadReceipt> {
findByMessageId(messageId: string): FindCursor<IReadReceipt>;
removeByUserId(userId: string): Promise<DeleteResult>;
removeByRoomId(roomId: string): Promise<DeleteResult>;
removeByRoomIds(roomIds: string[]): Promise<DeleteResult>;
removeByMessageId(messageId: string): Promise<DeleteResult>;
removeByMessageIds(messageIds: string[]): Promise<DeleteResult>;
findOlderThan(date: Date): FindCursor<IReadReceipt>;
}

View File

@@ -0,0 +1,11 @@
import type { IReport, IMessage } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface IReportsModel extends IBaseModel<IReport> {
createWithMessageDescriptionAndUserId(
message: IMessage,
description: string,
userId: string,
): ReturnType<IBaseModel<IReport>['insertOne']>;
}

View File

@@ -0,0 +1,63 @@
import type { IRole, IUser, IRoom } from '@rocket.chat/core-typings';
import type { FindCursor, FindOptions, CountDocumentsOptions, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IRolesModel extends IBaseModel<IRole> {
findByUpdatedDate<T extends Document = IRole, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
updatedAfterDate: Date,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
isUserInRoles(userId: IUser['_id'], roles: IRole['_id'][], scope?: IRoom['_id']): Promise<boolean>;
findOneByIdOrName<P extends Document = IRole, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
_idOrName: IRole['_id'],
options?: O,
): Promise<DocumentWithProjection<P, O> | null>;
findOneByName<P = IRole>(name: IRole['name'], options?: any): Promise<IRole | P | null>;
findInIds<P>(ids: IRole['_id'][], options?: FindOptions<IRole>): P extends Pick<IRole, '_id'> ? FindCursor<P> : FindCursor<IRole>;
findInIdsOrNames<P>(
_idsOrNames: IRole['_id'][],
options?: FindOptions<IRole>,
): P extends Pick<IRole, '_id'> ? FindCursor<P> : FindCursor<IRole>;
findByScope<T extends Document = IRole, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
scope: IRole['scope'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
updateById(
_id: IRole['_id'],
name: IRole['name'],
scope: IRole['scope'],
description?: IRole['description'],
mandatory2fa?: IRole['mandatory2fa'],
): Promise<IRole>;
findUsersInRole(roleId: IRole['_id'], scope?: IRoom['_id']): Promise<FindCursor<IUser>>;
findUsersInRole(roleId: IRole['_id'], scope: IRoom['_id'] | undefined, options: FindOptions<IUser>): Promise<FindCursor<IUser>>;
findUsersInRole<P extends Document>(
roleId: IRole['_id'],
scope: IRoom['_id'] | undefined,
options: FindOptions<P extends IUser ? IUser : P>,
): Promise<FindCursor<P extends IUser ? IUser : P>>;
/** @deprecated function getUsersInRole should be used instead */
findUsersInRole<P>(roleId: IRole['_id'], scope: IRoom['_id'] | undefined, options?: any): Promise<FindCursor<IUser> | FindCursor<P>>;
findCustomRoles<T extends Document = IRole, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
createWithRandomId(
name: IRole['name'],
scope?: IRole['scope'],
description?: string,
protectedRole?: boolean,
mandatory2fa?: boolean,
): Promise<IRole>;
canAddUserToRole(uid: IUser['_id'], roleId: IRole['_id'], scope?: IRoom['_id']): Promise<boolean>;
countUsersInRole(roleId: IRole['_id'], scope?: IRoom['_id']): Promise<number>;
countByScope(scope: IRole['scope'], options?: CountDocumentsOptions): Promise<number>;
countCustomRoles(options?: CountDocumentsOptions): Promise<number>;
}

View File

@@ -0,0 +1,462 @@
import type {
IDirectMessageRoom,
IMessage,
IOmnichannelGenericRoom,
IRoom,
IRoomFederated,
IRoomNativeFederated,
ITeam,
IUser,
} from '@rocket.chat/core-typings';
import type {
AggregationCursor,
DeleteResult,
Document,
FindCursor,
FindOptions,
UpdateOptions,
UpdateResult,
CountDocumentsOptions,
WithId,
FindOneAndUpdateOptions,
} from 'mongodb';
import type { Updater } from '../updater';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IChannelsWithNumberOfMessagesBetweenDate {
room: {
_id: IRoom['_id'];
name: IRoom['name'];
ts: IRoom['ts'];
t: IRoom['t'];
_updatedAt: IRoom['_updatedAt'];
usernames?: IDirectMessageRoom['usernames'];
};
messages: number;
lastWeekMessages: number;
diffFromLastWeek: number;
}
export interface IRoomsModel extends IBaseModel<IRoom> {
findAllByTypesAndDiscussionAndTeam<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
filters?: {
types?: Array<IRoom['t']>;
discussions?: boolean;
teams?: boolean;
},
findOptions?: O,
): FindCursor<DocumentWithProjection<T, O>>;
isAbacAttributeInUse(key: string, values: string[]): Promise<boolean>;
findOneByRoomIdAndUserId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: IRoom['_id'],
uid: IUser['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findManyByRoomIds<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomIds: Array<IRoom['_id']>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findManyArchivedByRoomIds<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomIds: Array<IRoom['_id']>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findPaginatedByIds(
roomIds: Array<IRoom['_id']>,
options?: FindOptions<IRoom>,
): FindPaginated<FindCursor<IRoom & { isLastOwner?: boolean }>>;
getMostRecentAverageChatDurationTime(numberMostRecentChats: number, department?: string): Promise<Document>;
findByNameOrFnameContainingAndTypes<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: NonNullable<IRoom['name']>,
types: Array<IRoom['t']>,
discussion?: boolean,
teams?: boolean,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findPrivateRoomsAndTeamsPaginated<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: NonNullable<IRoom['name']>,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findByTeamId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
teamId: ITeam['_id'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countByTeamId(teamId: ITeam['_id']): Promise<number>;
findPaginatedByTeamIdContainingNameAndDefault<
T extends Document = IRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
teamId: ITeam['_id'],
name: IRoom['name'],
teamDefault: boolean,
ids: Array<IRoom['_id']> | undefined,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findByTeamIdAndRoomsId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
teamId: ITeam['_id'],
rids: Array<IRoom['_id']>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findRoomsByNameOrFnameStarting<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: NonNullable<IRoom['name']>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findRoomsWithoutDiscussionsByRoomIds<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: NonNullable<IRoom['name']>,
roomIds: Array<IRoom['_id']>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findPaginatedRoomsWithoutDiscussionsByRoomIds<
T extends Document = IRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
name: NonNullable<IRoom['name']>,
roomIds: Array<IRoom['_id']>,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findChannelAndGroupListWithoutTeamsByNameStartingByOwner<
T extends Document = IRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
name: IRoom['name'],
groupsToAccept: Array<IRoom['_id']>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
unsetTeamId(teamId: ITeam['_id'], options?: UpdateOptions): Promise<Document | UpdateResult>;
unsetTeamById(rid: IRoom['_id'], options?: UpdateOptions): Promise<UpdateResult>;
setTeamMainById(rid: IRoom['_id'], teamId: ITeam['_id'], options?: UpdateOptions): Promise<UpdateResult>;
setTeamByIds(rids: Array<IRoom['_id']>, teamId: ITeam['_id'], options?: UpdateOptions): Promise<Document | UpdateResult>;
setTeamDefaultById(rid: IRoom['_id'], teamDefault: NonNullable<IRoom['teamDefault']>, options?: UpdateOptions): Promise<UpdateResult>;
findOneByName(name: NonNullable<IRoom['name']>, options?: FindOptions<IRoom>): Promise<IRoom | null>;
findDefaultRoomsForTeam(teamId: any): FindCursor<IRoom>;
incUsersCountByIds(ids: Array<IRoom['_id']>, inc: number, options?: UpdateOptions): Promise<Document | UpdateResult>;
findOneByNameOrFname<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: NonNullable<IRoom['name']>,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByJoinCodeAndId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
joinCode: string,
rid: IRoom['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByNonValidatedName(name: NonNullable<IRoom['name']>, options?: FindOptions<IRoom>): Promise<IRoom | null>;
allRoomSourcesCount(): AggregationCursor<{ _id: Required<IOmnichannelGenericRoom['source']>; count: number }>;
countAbacEnabled(): Promise<number>;
setAsFederated(roomId: IRoom['_id'], { mrid, origin }: { mrid: string; origin: string }): Promise<UpdateResult>;
setFnameById(_id: IRoom['_id'], fname: IRoom['fname']): Promise<UpdateResult>;
findE2ERoomById<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: IRoom['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
countRoomsInsideTeams(autoJoin?: boolean): Promise<number>;
findOneDirectRoomContainingAllUserIDs<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
uid: IDirectMessageRoom['uids'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
countByType(t: IRoom['t']): Promise<number>;
findPaginatedByNameOrFNameAndRoomIdsIncludingTeamRooms<
T extends Document = IRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
searchTerm: RegExp | null,
teamIds: Array<ITeam['_id']>,
roomIds: Array<IRoom['_id']>,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findPaginatedContainingNameOrFNameInIdsAsTeamMain<
T extends Document = IRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
searchTerm: RegExp | null,
rids: Array<IRoom['_id']>,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findPaginatedByTypeAndIds<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
type: IRoom['t'],
ids: Array<IRoom['_id']>,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findOneFederatedByMrid<T extends Document = IRoomFederated, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
mrid: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findBiggestFederatedRoomInNumberOfUsers(options?: FindOptions<IRoom>): Promise<IRoom | undefined>;
findSmallestFederatedRoomInNumberOfUsers(options?: FindOptions<IRoom>): Promise<IRoom | undefined>;
countFederatedRooms(): Promise<number>;
incMsgCountById(rid: string, inc: number): Promise<UpdateResult>;
findOneAndIncMsgCountById(
rid: string,
inc: number,
options?: Omit<FindOneAndUpdateOptions, 'returnDocument' | 'includeResultMetadata' | 'upsert'>,
): Promise<IRoom | null>;
getIncMsgCountUpdateQuery(inc: number, roomUpdater: Updater<IRoom>): Updater<IRoom>;
decreaseMessageCountById(rid: string, dec: number): Promise<UpdateResult>;
findOneByIdOrName<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_idOrName: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
setReactionsInLastMessage(roomId: string, reactions: NonNullable<IRoom['lastMessage']>['reactions']): Promise<UpdateResult>;
unsetReactionsInLastMessage(roomId: string): Promise<UpdateResult>;
unsetAllImportIds(): Promise<Document | UpdateResult>;
updateLastMessageStar(roomId: string, userId: string, starred?: boolean): Promise<UpdateResult>;
// TODO check types
setLastMessagePinned(roomId: string, pinnedBy: unknown, pinned?: boolean, pinnedAt?: Date): Promise<UpdateResult>;
setLastMessageAsRead(roomId: string): Promise<UpdateResult>;
setDescriptionById(roomId: string, description: string): Promise<UpdateResult>;
setReadOnlyById(roomId: string, readOnly: NonNullable<IRoom['ro']>): Promise<UpdateResult>;
setDmReadOnlyByUserId(
roomId: string,
ids: string[] | undefined,
readOnly: NonNullable<IRoom['ro']>,
reactWhenReadOnly: NonNullable<IRoom['reactWhenReadOnly']>,
): Promise<UpdateResult | Document>;
getDirectConversationsByUserId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
setAllowReactingWhenReadOnlyById(
roomId: string,
allowReactingWhenReadOnly: NonNullable<IRoom['reactWhenReadOnly']>,
): Promise<UpdateResult>;
setAvatarData(roomId: string, origin: string, etag: string): Promise<UpdateResult>;
unsetAvatarData(roomId: string): Promise<UpdateResult>;
setSystemMessagesById(roomId: string, systemMessages: IRoom['sysMes']): Promise<UpdateResult>;
setE2eKeyId(
roomId: string,
e2eKeyId: string,
options?: Omit<FindOneAndUpdateOptions, 'returnDocument' | 'includeResultMetadata' | 'upsert'>,
): Promise<IRoom | null>;
findOneByImportId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
importId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByNameAndNotId(name: string, rid: string): Promise<IRoom | null>;
findOneByIdAndType<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: IRoom['_id'],
type: IRoom['t'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByDisplayName<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
displayName: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByNameAndType<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: string,
type: IRoom['t'],
options?: O,
includeFederatedRooms?: boolean,
): Promise<DocumentWithProjection<T, O> | null>;
findById<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByIds<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rids: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByType<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
type: IRoom['t'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByTypeInIds<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
type: IRoom['t'],
ids: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findPrivateRoomsByIdsWithAbacAttributes<
T extends Document = IRoom,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
ids: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findAllPrivateRoomsWithAbacAttributes<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findBySubscriptionUserId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): Promise<FindCursor<DocumentWithProjection<T, O>>>;
findBySubscriptionUserIdUpdatedAfter<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
updatedAfter: Date,
options?: O,
): Promise<FindCursor<DocumentWithProjection<T, O>>>;
findByNameAndTypeNotDefault<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: IRoom['name'] | RegExp,
type: IRoom['t'],
options?: O,
includeFederatedRooms?: boolean,
): FindCursor<DocumentWithProjection<T, O>>;
findByNameOrFNameAndTypesNotInIds<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
name: IRoom['name'] | RegExp,
types: IRoom['t'][],
ids: string[],
options?: O,
includeFederatedRooms?: boolean,
): FindCursor<DocumentWithProjection<T, O>>;
findByDefaultAndTypes<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
defaultValue: boolean,
types: IRoom['t'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findDirectRoomContainingAllUsernames<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
usernames: string[],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByTypeAndNameOrId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
type: IRoom['t'],
name: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByTypeAndNameContaining<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
type: IRoom['t'],
name: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByTypeInIdsAndNameContaining<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
type: IRoom['t'],
ids: string[],
name: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findGroupDMsByUids<T extends Document = IDirectMessageRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
uids: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
find1On1ByUserId<T extends Document = IRoom, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByUsernamesOrUids(uids: IRoom['u']['_id'][], usernames: IRoom['u']['username'][]): FindCursor<IRoom>;
findDMsByUids(uids: IRoom['u']['_id'][]): FindCursor<IRoom>;
addImportIds(rid: string, importIds: string[]): Promise<UpdateResult>;
archiveById(rid: string): Promise<UpdateResult>;
unarchiveById(rid: string): Promise<UpdateResult>;
setNameById(rid: string, name: string, fname: string): Promise<UpdateResult>;
setIncMsgCountAndSetLastMessageUpdateQuery(
inc: number,
lastMessage: IMessage,
shouldStoreLastMessage: boolean,
roomUpdater: Updater<IRoom>,
): Updater<IRoom>;
incUsersCountById(rid: string, inc: number): Promise<UpdateResult>;
incUsersCountNotDMsByIds(rids: string[], inc: number): Promise<Document | UpdateResult>;
getLastMessageUpdateQuery(lastMessage: IRoom['lastMessage'], roomUpdater: Updater<IRoom>): Updater<IRoom>;
resetLastMessageById(rid: string, lastMessage: IMessage | null, msgCountDelta?: number): Promise<UpdateResult>;
replaceUsername(username: string, newUsername: string): Promise<UpdateResult | Document>;
replaceMutedUsername(username: string, newUsername: string): Promise<UpdateResult | Document>;
replaceUsernameOfUserByUserId(userId: string, newUsername: string): Promise<UpdateResult | Document>;
setJoinCodeById(rid: string, joinCode: string): Promise<UpdateResult>;
setTypeById(rid: string, type: IRoom['t']): Promise<UpdateResult>;
setTopicById(rid: string, topic?: string): Promise<UpdateResult>;
setAnnouncementById(
rid: string,
announcement: IRoom['announcement'],
announcementDetails: IRoom['announcementDetails'],
): Promise<UpdateResult>;
setCustomFieldsById(rid: string, customFields: Record<string, any>): Promise<UpdateResult>;
muteUsernameByRoomId(rid: string, username: string): Promise<UpdateResult>;
muteReadOnlyUsernameByRoomId(rid: string, username: string): Promise<UpdateResult>;
unmuteMutedUsernameByRoomId(rid: string, username: string): Promise<UpdateResult>;
unmuteReadOnlyUsernameByRoomId(rid: string, username: string): Promise<UpdateResult>;
saveFeaturedById(rid: string, featured: boolean): Promise<UpdateResult>;
saveDefaultById(rid: string, defaultValue: boolean): Promise<UpdateResult>;
saveFavoriteById(rid: string, favorite: boolean, defaultValue: boolean): Promise<UpdateResult>;
saveRetentionEnabledById(rid: string, retentionEnabled: boolean): Promise<UpdateResult>;
saveRetentionMaxAgeById(rid: string, retentionMaxAge: number): Promise<UpdateResult>;
saveRetentionExcludePinnedById(rid: string, retentionExcludePinned: boolean): Promise<UpdateResult>;
saveRetentionIgnoreThreadsById(rid: string, retentionIgnoreThreads: boolean): Promise<UpdateResult>;
saveRetentionFilesOnlyById(rid: string, retentionFilesOnly: boolean): Promise<UpdateResult>;
saveRetentionOverrideGlobalById(rid: string, retentionOverrideGlobal: boolean): Promise<UpdateResult>;
saveEncryptedById(rid: string, encrypted: boolean): Promise<UpdateResult>;
updateGroupDMsRemovingUsernamesByUsername(username: string, userId: string): Promise<UpdateResult | Document>;
createWithIdTypeAndName(id: string, type: IRoom['t'], name: string, extraData?: Record<string, unknown>): Promise<IRoom>;
createWithFullRoomData(room: Omit<IRoom, '_id' | '_updatedAt'>): Promise<IRoom>;
removeById(rid: string): Promise<DeleteResult>;
removeByIds(rids: string[]): Promise<DeleteResult>;
removeDirectRoomContainingUsername(username: string): Promise<DeleteResult>;
countDiscussions(): Promise<number>;
addUserIdToE2EEQueueByRoomIds(roomIds: IRoom['_id'][], uid: IUser['_id']): Promise<Document | UpdateResult>;
getSubscribedRoomIdsWithoutE2EKeys(uid: IUser['_id']): Promise<IRoom['_id'][]>;
removeUsersFromE2EEQueueByRoomId(roomId: IRoom['_id'], uids: IUser['_id'][]): Promise<Document | UpdateResult>;
removeUserFromE2EEQueue(uid: IUser['_id']): Promise<Document | UpdateResult>;
findChildrenOfTeam(
teamId: string,
teamRoomId: string,
userId: string,
filter?: string,
type?: 'channels' | 'discussions',
options?: FindOptions<IRoom>,
): AggregationCursor<{ totalCount: { count: number }[]; paginatedResults: IRoom[] }>;
resetRoomKeyAndSetE2EEQueueByRoomId(
roomId: string,
e2eKeyId: string,
e2eQueue?: IRoom['usersWaitingForE2EKeys'],
): Promise<WithId<IRoom> | null>;
countGroupDMsByUids(uids: NonNullable<IRoom['uids']>): Promise<number>;
countByBroadcast(options?: CountDocumentsOptions): Promise<number>;
countByE2E(options?: CountDocumentsOptions): Promise<number>;
markRolePrioritesCreatedForRoom(rid: IRoom['_id'], version: number): Promise<UpdateResult>;
hasCreatedRolePrioritiesForRoom(rid: IRoom['_id'], syncVersion: number): Promise<number>;
countDistinctFederationRoomsExcluding(serverNames?: string[]): Promise<string[]>;
setAbacAttributesById(rid: IRoom['_id'], attributes: NonNullable<IRoom['abacAttributes']>): Promise<IRoom | null>;
unsetAbacAttributesById(rid: IRoom['_id']): Promise<UpdateResult>;
unsetAllAbacAttributes(): Promise<Document | UpdateResult>;
updateSingleAbacAttributeValuesById(rid: IRoom['_id'], key: string, values: string[]): Promise<UpdateResult>;
insertAbacAttributeIfNotExistsById(
rid: IRoom['_id'],
key: string,
values: string[],
): Promise<Pick<IRoom, '_id' | 'abacAttributes'> | null>;
updateAbacAttributeValuesArrayFilteredById(rid: IRoom['_id'], key: string, values: string[]): Promise<IRoom | null>;
removeAbacAttributeByRoomIdAndKey(rid: IRoom['_id'], key: string): Promise<UpdateResult>;
removeUserReferenceFromDMsById(roomId: string, username: string, userId: string): Promise<UpdateResult>;
findFederatedByIds<T extends Document = IRoomNativeFederated, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
ids: Array<IRoom['_id']>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
}

View File

@@ -0,0 +1,7 @@
import type { ISamlUsedAssertions } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface ISamlUsedAssertionsModel extends IBaseModel<ISamlUsedAssertions> {
markUsed(assertionId: string, issuer: string, expireAt: Date): Promise<boolean>;
}

View File

@@ -0,0 +1,17 @@
import type { ExtractDataToParams, IAuditServerActor, IServerEvent, IServerEvents } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface IServerEventsModel extends IBaseModel<IServerEvent> {
findLastFailedAttemptByIp(ip: string): Promise<IServerEvent | null>;
findLastFailedAttemptByUsername(username: string): Promise<IServerEvent | null>;
findLastSuccessfulAttemptByIp(ip: string): Promise<IServerEvent | null>;
findLastSuccessfulAttemptByUsername(username: string): Promise<IServerEvent | null>;
countFailedAttemptsByUsernameSince(username: string, since: Date): Promise<number>;
countFailedAttemptsByIpSince(ip: string, since: Date): Promise<number>;
createAuditServerEvent<K extends keyof IServerEvents, E extends IServerEvents[K]>(
key: K,
data: ExtractDataToParams<E>,
actor: IAuditServerActor,
): Promise<void>;
}

View File

@@ -0,0 +1,152 @@
import type {
ISession,
UserSessionAggregationResult,
DeviceSessionAggregationResult,
OSSessionAggregationResult,
IUser,
DeviceManagementPopulatedSession,
DeviceManagementSession,
} from '@rocket.chat/core-typings';
import type { BulkWriteResult, Document, UpdateResult, FindCursor, OptionalId } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export type DestructuredDate = { year: number; month: number; day: number };
export type DestructuredDateWithType = {
year: number;
month: number;
day: number;
type?: 'month' | 'week';
};
export type DestructuredRange = { start: DestructuredDate; end: DestructuredDate };
export type DateRange = { start: Date; end: Date };
type CustomSortOp = 'loginAt' | 'device.name' | 'device.os.name';
type CustomSortOpAdmin = CustomSortOp | '_user.username' | '_user.name';
export interface ISessionsModel extends IBaseModel<ISession> {
aggregateSessionsAndPopulate({
sort,
search,
offset,
count,
}: {
sort?: Record<CustomSortOpAdmin, 1 | -1>;
search?: string | null;
offset?: number;
count?: number;
}): Promise<{ sessions: Array<DeviceManagementPopulatedSession>; count: number; offset: number; total: number }>;
aggregateSessionsByUserId({
uid,
sort,
search,
offset,
count,
currentLoginToken,
}: {
uid: string;
sort?: Record<CustomSortOp, 1 | -1>;
search?: string | null;
offset?: number;
count?: number;
currentLoginToken?: string;
}): Promise<{ sessions: Array<DeviceManagementSession>; count: number; offset: number; total: number }>;
findOneBySessionId(sessionId: string): Promise<ISession | null>;
findOneBySessionIdAndUserId(sessionId: string, userId: string): Promise<ISession | null>;
findSessionsNotClosedByDateWithoutLastActivity({ year, month, day }: DestructuredDate): FindCursor<ISession>;
getActiveUsersOfPeriodByDayBetweenDates({ start, end }: DestructuredRange): Promise<
{
day: number;
month: number;
year: number;
usersList: IUser['_id'][];
users: number;
}[]
>;
getBusiestTimeWithinHoursPeriod({ start, end, groupSize }: DateRange & { groupSize: number }): Promise<
{
hour: number;
users: number;
}[]
>;
getTotalOfSessionsByDayBetweenDates({ start, end }: DestructuredRange): Promise<
{
day: number;
month: number;
year: number;
users: number;
}[]
>;
getTotalOfSessionByHourAndDayBetweenDates({ start, end }: DateRange): Promise<
{
hour: number;
day: number;
month: number;
year: number;
users: number;
}[]
>;
getUniqueUsersOfYesterday(): Promise<UserSessionAggregationResult>;
getUniqueUsersOfLastMonth(): Promise<UserSessionAggregationResult>;
getUniqueUsersOfLastWeek(): Promise<UserSessionAggregationResult>;
getUniqueDevicesOfYesterday(): Promise<DeviceSessionAggregationResult>;
getUniqueDevicesOfLastMonth(): Promise<DeviceSessionAggregationResult>;
getUniqueDevicesOfLastWeek(): Promise<DeviceSessionAggregationResult>;
getUniqueOSOfYesterday(): Promise<OSSessionAggregationResult>;
getUniqueOSOfLastMonth(): Promise<OSSessionAggregationResult>;
getUniqueOSOfLastWeek(): Promise<OSSessionAggregationResult>;
createOrUpdate(data: Omit<ISession, '_id' | 'createdAt' | '_updatedAt'>): Promise<UpdateResult | undefined>;
closeByInstanceIdAndSessionId(instanceId: string, sessionId: string): Promise<UpdateResult>;
updateActiveSessionsByDate({ year, month, day }: DestructuredDate, data: Record<string, any>): Promise<UpdateResult | Document>;
logoutBySessionIdAndUserId({
loginToken,
userId,
}: {
loginToken: ISession['loginToken'];
userId: IUser['_id'];
}): Promise<UpdateResult | Document>;
logoutByloginTokenAndUserId({
loginToken,
userId,
logoutBy,
}: {
loginToken: ISession['loginToken'];
userId: IUser['_id'];
logoutBy?: IUser['_id'];
}): Promise<UpdateResult | Document>;
logoutAllByUserId(userId: IUser['_id'], logoutBy: IUser['_id']): Promise<UpdateResult | Document>;
createBatch(sessions: OptionalId<ISession>[]): Promise<BulkWriteResult | undefined>;
updateDailySessionById(_id: ISession['_id'], record: Partial<ISession>): Promise<UpdateResult>;
updateAllSessionsByDateToComputed({ start, end }: DestructuredRange): Promise<UpdateResult | Document>;
getLoggedInByUserIdAndSessionId<T extends Document = ISession, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
sessionId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
}

View File

@@ -0,0 +1,63 @@
import type { ISetting, ISettingColor, ISettingSelectOption, SettingValue } from '@rocket.chat/core-typings';
import type { FindCursor, UpdateFilter, UpdateResult, Document, FindOneAndUpdateOptions, WithId, UpdateOptions } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ISettingsModel extends IBaseModel<ISetting> {
getValueById<T extends SettingValue = SettingValue>(_id: string): Promise<T | undefined>;
findNotHidden(params?: { updatedAfter?: Date }): FindCursor<ISetting>;
findOneNotHiddenById(_id: string): Promise<ISetting | null>;
findByIds<T extends Document = ISetting, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id?: string[] | string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
updateValueById(
_id: string,
value: (ISetting['value'] extends undefined ? never : ISetting['value']) | null,
options?: UpdateOptions,
): Promise<UpdateResult>;
resetValueById(
_id: string,
value?: (ISetting['value'] extends undefined ? never : ISetting['value']) | null,
): Promise<Document | UpdateResult | undefined>;
incrementValueById(_id: ISetting['_id'], value?: ISetting['value'], options?: FindOneAndUpdateOptions): Promise<null | WithId<ISetting>>;
updateOptionsById<T extends ISetting = ISetting>(
_id: ISetting['_id'],
options: UpdateFilter<T>['$set'],
): Promise<Document | UpdateResult>;
updateValueNotHiddenById<T extends ISetting['value'] = ISetting['value']>(
_id: ISetting['_id'],
value: T,
): Promise<Document | UpdateResult>;
updateValueAndEditorById<T extends ISetting['value'] = ISetting['value']>(
_id: ISetting['_id'],
value: T,
editor: ISettingColor['editor'],
): Promise<Document | UpdateResult>;
findNotHiddenPublic<T extends ISetting = ISetting>(
ids?: ISetting['_id'][],
): FindCursor<
T extends ISettingColor
? Pick<T, '_id' | 'value' | 'editor' | 'enterprise' | 'invalidValue' | 'modules' | 'requiredOnWizard'>
: Pick<T, '_id' | 'value' | 'enterprise' | 'invalidValue' | 'modules' | 'requiredOnWizard'>
>;
findSetupWizardSettings(): FindCursor<ISetting>;
findEnterpriseSettings(): FindCursor<ISetting>;
addOptionValueById(_id: ISetting['_id'], option: ISettingSelectOption): Promise<Document | UpdateResult>;
findNotHiddenPublicUpdatedAfter(updatedAt: Date): FindCursor<ISetting>;
}

View File

@@ -0,0 +1,6 @@
import type { ISmarshHistory } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ISmarshHistoryModel extends IBaseModel<ISmarshHistory> {}

View File

@@ -0,0 +1,10 @@
import type { IStats } from '@rocket.chat/core-typings';
import type { IBaseModel } from './IBaseModel';
export interface IStatisticsModel extends IBaseModel<IStats> {
findLast(): Promise<IStats>;
findMonthlyPeakConnections(): Promise<Pick<IStats, 'dailyPeakConnections' | 'createdAt'> | null>;
findLastStatsToken(): Promise<IStats['statsToken']>;
findInstallationDates(): Promise<Pick<IStats, 'version' | 'installedAt'>[]>;
}

View File

@@ -0,0 +1,388 @@
import type { ISubscription, IRole, IUser, IRoom, IMessage, SpotlightUser, AtLeast } from '@rocket.chat/core-typings';
import type {
FindOptions,
FindCursor,
UpdateResult,
DeleteResult,
Document,
AggregateOptions,
Filter,
InsertOneResult,
InsertManyResult,
AggregationCursor,
DeleteOptions,
CountDocumentsOptions,
WithId,
ClientSession,
} from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ISubscriptionsModel extends IBaseModel<ISubscription> {
getBadgeCount(uid: string): Promise<number>;
findOneByRoomIdAndUserId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
uid: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByUserIdAndRoomIds<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
roomIds: Array<string>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByRoomId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findUnarchivedByRoomId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByRoomIdAndNotUserId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
userId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countByRoomIdAndUserId(rid: string, uid: string | undefined, includeInvitations?: boolean): Promise<number>;
countUnarchivedByRoomId(rid: string): Promise<number>;
countUnarchivedByRoomIdAndNotUserId(rid: string, uid: string): Promise<number>;
isUserInRole(uid: IUser['_id'], roleId: IRole['_id'], rid?: IRoom['_id']): Promise<boolean>;
setAsReadByRoomIdAndUserId(
rid: string,
uid: string,
readThreads?: boolean,
alert?: boolean,
options?: FindOptions<ISubscription>,
): ReturnType<IBaseModel<ISubscription>['updateOne']>;
removeRolesByUserId(uid: IUser['_id'], roles: IRole['_id'][], rid: IRoom['_id']): Promise<UpdateResult>;
findUsersInRoles<P extends Document = IUser, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
roles: IRole['_id'][],
rid: string | undefined,
options?: O,
): Promise<FindCursor<DocumentWithProjection<P, O>>>;
addRolesByUserId(uid: IUser['_id'], roles: IRole['_id'][], rid?: IRoom['_id']): Promise<UpdateResult>;
isUserInRoleScope(uid: IUser['_id'], rid?: IRoom['_id']): Promise<boolean>;
findByRolesAndRoomId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
{ roles, rid }: { roles: string; rid?: string },
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByUserIdAndTypes<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
types: ISubscription['t'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findOpenByVisitorIds<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
visitorIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByRoomIdAndNotAlertOrOpenExcludingUserIds<
T extends Document = ISubscription,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
filter: {
roomId: ISubscription['rid'];
uidsExclude?: ISubscription['u']['_id'][];
uidsInclude?: ISubscription['u']['_id'][];
onlyRead: boolean;
},
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
removeByRoomId(roomId: ISubscription['rid'], options?: DeleteOptions & { onTrash: (doc: ISubscription) => void }): Promise<DeleteResult>;
findConnectedUsersExcept(
userId: string,
searchTerm: string,
exceptions: string[],
searchFields: string[],
extraConditions: Filter<IUser>,
limit: number,
roomType?: ISubscription['t'],
{ startsWith, endsWith }?: { startsWith?: string | false; endsWith?: string | false },
options?: AggregateOptions,
): Promise<SpotlightUser[]>;
incUnreadForRoomIdExcludingUserIds(roomId: IRoom['_id'], userIds: IUser['_id'][], inc: number): Promise<UpdateResult | Document>;
setAlertForRoomIdExcludingUserId(roomId: IRoom['_id'], userId: IUser['_id']): Promise<UpdateResult | Document>;
setOpenForRoomIdExcludingUserId(roomId: IRoom['_id'], userId: IUser['_id']): Promise<UpdateResult | Document>;
updateNameAndFnameByVisitorIds(visitorIds: string[], name: string): Promise<UpdateResult | Document>;
setGroupE2EKey(_id: string, key: string): Promise<UpdateResult>;
setGroupE2EKeyAndOldRoomKeys(_id: string, key: string, oldRoomKeys: ISubscription['oldRoomKeys']): Promise<UpdateResult>;
setGroupE2ESuggestedKey(uid: string, rid: string, key: string): Promise<null | WithId<ISubscription>>;
setGroupE2ESuggestedKeyAndOldRoomKeys(
uid: string,
rid: string,
key: string,
suggestedOldRoomKeys: ISubscription['suggestedOldRoomKeys'],
): Promise<null | WithId<ISubscription>>;
unsetGroupE2ESuggestedKeyAndOldRoomKeys(_id: string): Promise<UpdateResult | Document>;
setOnHoldByRoomId(roomId: string): Promise<UpdateResult>;
unsetOnHoldByRoomId(roomId: string): Promise<UpdateResult>;
updateUnreadAlertById(_id: string, unreadAlert: ISubscription['unreadAlert']): Promise<UpdateResult>;
updateNotificationsPrefById(
_id: string,
notificationPref: { value: number; origin: string } | null,
notificationField: keyof ISubscription,
notificationPrefOrigin: keyof ISubscription,
): Promise<UpdateResult>;
updateHideMentionStatusById(_id: string, hideMentionStatus: boolean): Promise<UpdateResult>;
updateDisableNotificationsById(_id: string, disableNotifications: boolean): Promise<UpdateResult>;
clearAudioNotificationValueById(_id: string): Promise<UpdateResult>;
updateHideUnreadStatusById(_id: string, hideUnreadStatus: boolean): Promise<UpdateResult>;
updateAudioNotificationValueById(_id: string, audioNotificationValue: string): Promise<UpdateResult>;
updateAutoTranslateLanguageById(_id: string, autoTranslateLanguage: string): Promise<UpdateResult>;
updateDraftByRoomIdAndUserId(
rid: IRoom['_id'],
uid: IUser['_id'],
draft: string | undefined,
tmid?: IMessage['_id'],
): Promise<null | WithId<ISubscription>>;
updateMuteGroupMentions(_id: string, muteGroupMentions: boolean): Promise<UpdateResult>;
changeDepartmentByRoomId(rid: string, department: string): Promise<UpdateResult>;
getAutoTranslateLanguagesByRoomAndNotUser(rid: string, userId: string): Promise<(string | undefined)[]>;
findByRidWithoutE2EKey<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
options: O,
): FindCursor<DocumentWithProjection<T, O>>;
findUsersWithPublicE2EKeyByRids(
rids: IRoom['_id'][],
excludeUserId: IUser['_id'],
usersLimit?: number,
): AggregationCursor<{ rid: IRoom['_id']; users: { _id: IUser['_id']; public_key: string }[] }>;
findByUserId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
updateAutoTranslateById(_id: string, autoTranslate: boolean): Promise<UpdateResult>;
setAutoTranslateByUserId(userId: IUser['_id'], language: string | null): Promise<UpdateResult | Document>;
findByAutoTranslateAndUserId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: ISubscription['u']['_id'],
autoTranslate?: ISubscription['autoTranslate'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByUserIdAndRoomType<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: ISubscription['u']['_id'],
type: ISubscription['t'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByNameAndRoomType<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
filter: Partial<Pick<ISubscription, 'name' | 't'>>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
disableAutoTranslateByRoomId(roomId: IRoom['_id']): Promise<UpdateResult | Document>;
findByUserIdWithoutE2E<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
resetUserE2EKey(userId: string): Promise<UpdateResult | Document>;
findOneByRoomIdAndUsername<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
username: string,
options: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByTypeAndUserId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
type: ISubscription['t'],
userId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByType<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
types: ISubscription['t'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByUserIdAndRoles<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
roles: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
getLastSeen(options?: FindOptions<ISubscription>): Promise<Date | undefined>;
findByRoomWithUserHighlights<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByUserIdAndType<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
type: ISubscription['t'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByUserIdExceptType<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
typeException: ISubscription['t'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByRoomIdAndRoles<P extends Document = ISubscription, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
roomId: string,
roles: string[],
options?: O,
): FindCursor<DocumentWithProjection<P, O>>;
findByRoomIdAndUserIds<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: ISubscription['rid'],
userIds: ISubscription['u']['_id'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
getMinimumLastSeenByRoomId(rid: string): Promise<Pick<ISubscription, '_id' | 'ls'> | null>;
setAsUnreadByRoomIdAndUserId(roomId: string, userId: string, firstMessageUnreadTimestamp: Date): Promise<UpdateResult>;
archiveByRoomId(roomId: string): Promise<UpdateResult | Document>;
findArchivedByRoomId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findArchivedByUserId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
unarchiveByIds(ids: string[]): Promise<UpdateResult | Document>;
updateNameAndAlertByRoomId(roomId: string, name: string, fname: string): Promise<UpdateResult | Document>;
findByRoomIdWhenUsernameExists<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
setCustomFieldsDirectMessagesByUserId(userId: string, fields: Record<string, any>): Promise<UpdateResult | Document>;
setFavoriteByRoomIdAndUserId(roomId: string, userId: string, favorite?: boolean): Promise<UpdateResult>;
setCategoryByRoomIdsAndUserId(roomIds: string[], userId: string, category: string | null): Promise<UpdateResult | Document>;
hideByRoomIdAndUserId(roomId: string, userId: string): Promise<UpdateResult>;
findByRoomIdWhenUserIdExists<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
updateNameAndFnameById(_id: string, name: string, fname: string, options?: { session?: ClientSession }): Promise<UpdateResult | Document>;
setUserUsernameByUserId(userId: string, username: string): Promise<UpdateResult | Document>;
updateFnameByRoomId(rid: string, fname: string): Promise<UpdateResult | Document>;
updateDisplayNameByRoomId(roomId: string, fname: string): Promise<UpdateResult | Document>;
updateDirectNameAndFnameByName(name: string, newName?: string, newFname?: string): Promise<UpdateResult | Document>;
incGroupMentionsAndUnreadForRoomIdExcludingUserId(
roomId: IRoom['_id'],
userId: IUser['_id'],
incGroup?: number,
incUnread?: number,
): Promise<UpdateResult | Document>;
unsetBlockedByRoomId(rid: string, blocked: string, blocker: string): Promise<UpdateResult[]>;
setLastReplyForRoomIdAndUserIds(roomId: IRoom['_id'], uids: IUser['_id'][], lr: Date): Promise<UpdateResult | Document>;
updateCustomFieldsByRoomId(rid: string, cfields: Record<string, any>): Promise<UpdateResult | Document>;
setOpenForRoomIdAndUserIds(roomId: string, uids: string[]): Promise<UpdateResult | Document>;
setAlertForRoomIdAndUserIds(roomId: ISubscription['rid'], uids: ISubscription['u']['_id'][]): Promise<UpdateResult | Document>;
updateTypeByRoomId(roomId: string, type: ISubscription['t']): Promise<UpdateResult | Document>;
setBlockedByRoomId(rid: string, blocked: string, blocker: string): Promise<UpdateResult[]>;
incUserMentionsAndUnreadForRoomIdAndUserIds(
roomId: IRoom['_id'],
userIds: IUser['_id'][],
incUser?: number,
incUnread?: number,
): Promise<UpdateResult | Document>;
ignoreUser(data: { _id: string; ignoredUser: string; ignore?: boolean }): Promise<UpdateResult>;
addRoleById(_id: string, role: string): Promise<UpdateResult>;
removeRoleById(_id: string, role: string): Promise<UpdateResult>;
setArchivedByUserId(userId: string, archived: boolean): Promise<UpdateResult | Document>;
setArchivedForDMsWithUsername(username: string, archived: boolean): Promise<UpdateResult | Document>;
updateUserHighlights(userId: string, userHighlights: any): Promise<UpdateResult | Document>;
updateNotificationUserPreferences(
userId: string,
userPref: string | number | boolean,
notificationField: keyof ISubscription,
notificationOriginField: keyof ISubscription,
): Promise<UpdateResult | Document>;
findByUserPreferences<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
notificationOriginField: keyof ISubscription,
originFieldNotEqualValue: 'user' | 'subscription',
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
clearNotificationUserPreferences(
userId: string,
notificationField: string,
notificationOriginField: string,
): Promise<UpdateResult | Document>;
removeByUserId(userId: string): Promise<number>;
createWithRoomAndUser(room: IRoom, user: IUser, extraData?: Partial<ISubscription>): Promise<InsertOneResult<ISubscription>>;
createWithRoomAndManyUsers(
room: IRoom,
users: { user: AtLeast<IUser, '_id' | 'username' | 'name' | 'settings'>; extraData: Record<string, any> }[],
): Promise<InsertManyResult<ISubscription>>;
removeByRoomIdAndUserId(roomId: string, userId: string): Promise<ISubscription | null>;
removeInvitedByRoomIdAndUserId(roomId: string, userId: string): Promise<ISubscription | null>;
removeByRoomIds(rids: string[], options?: { onTrash: (doc: ISubscription) => void }): Promise<DeleteResult>;
addUnreadThreadByRoomIdAndUserIds(
rid: string,
users: string[],
tmid: string,
data: { groupMention?: boolean; userMention?: boolean },
): Promise<UpdateResult | Document | void>;
removeUnreadThreadByRoomIdAndUserId(rid: string, userId: string, tmid: string, clearAlert?: boolean): Promise<UpdateResult>;
removeUnreadThreadsByRoomId(rid: string, tunread: string[]): Promise<UpdateResult | Document>;
findUnreadThreadsByRoomId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
rid: ISubscription['rid'],
tunread: ISubscription['tunread'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countByRoomIdAndRoles(roomId: string, roles: string[]): Promise<number>;
countByRoomId(roomId: string, options?: CountDocumentsOptions): Promise<number>;
countByUserIdExceptType(userId: string, typeException: ISubscription['t']): Promise<number>;
openByRoomIdAndUserId(roomId: string, userId: string): Promise<UpdateResult>;
countByRoomIdWhenUsernameExists(rid: string): Promise<number>;
setE2EKeyByUserIdAndRoomId(userId: string, rid: string, key: string): Promise<null | WithId<ISubscription>>;
countUsersInRoles(roles: IRole['_id'][], rid: IRoom['_id'] | undefined): Promise<number>;
findUserFederatedRoomIds(userId: IUser['_id']): AggregationCursor<{ _id: IRoom['_id']; externalRoomId: string }>;
findInvitedSubscription(roomId: ISubscription['rid'], userId: ISubscription['u']['_id']): Promise<ISubscription | null>;
acceptInvitationById(subscriptionId: ISubscription['_id']): Promise<UpdateResult>;
findOneBannedSubscription(roomId: ISubscription['rid'], userId: ISubscription['u']['_id']): Promise<ISubscription | null>;
banByRoomIdAndUserId(roomId: string, userId: string): Promise<UpdateResult>;
unbanToInvitedById(subId: string, inviter: Required<Pick<IUser, '_id' | 'username'>> & Pick<IUser, 'name'>): Promise<UpdateResult>;
setAbacLastTimeCheckedByUserIdAndRoomId(userId: string, roomId: string, time: Date): Promise<UpdateResult>;
findJoinedByUserId<T extends Document = ISubscription, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: ISubscription['u']['_id'],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
}

View File

@@ -0,0 +1,77 @@
import type { ITeamMember, IUser, IRole } from '@rocket.chat/core-typings';
import type { FindOptions, FindCursor, InsertOneResult, UpdateResult, DeleteResult, Filter, Document } from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
export interface ITeamMemberModel extends IBaseModel<ITeamMember> {
findByUserId(userId: string): FindCursor<ITeamMember>;
findByUserId(userId: string, options: FindOptions<ITeamMember>): FindCursor<ITeamMember>;
findByUserId<P extends Document>(userId: string, options: FindOptions<P>): FindCursor<P>;
findByUserId<P extends Document>(
userId: string,
options?: FindOptions<ITeamMember> | FindOptions<P extends ITeamMember ? ITeamMember : P>,
): FindCursor<P> | FindCursor<ITeamMember>;
findOneByUserIdAndTeamId(userId: string, teamId: string): Promise<ITeamMember | null>;
findOneByUserIdAndTeamId(userId: string, teamId: string, options: FindOptions<ITeamMember>): Promise<ITeamMember | null>;
findOneByUserIdAndTeamId<P extends Document>(userId: string, teamId: string, options: FindOptions<P>): Promise<P | null>;
findOneByUserIdAndTeamId<P extends Document>(
userId: string,
teamId: string,
options?: FindOptions<ITeamMember> | FindOptions<P extends ITeamMember ? ITeamMember : P>,
): Promise<P | null | ITeamMember>;
findByTeamId(teamId: string): FindCursor<ITeamMember>;
findByTeamId(teamId: string, options: FindOptions<ITeamMember>): FindCursor<ITeamMember>;
findByTeamId<P extends Document>(teamId: string, options: FindOptions<P>): FindCursor<P>;
findByTeamId<P extends Document>(
teamId: string,
options?: FindOptions<ITeamMember> | FindOptions<P extends ITeamMember ? ITeamMember : P>,
): FindCursor<P> | FindCursor<ITeamMember>;
countByTeamId(teamId: string): Promise<number>;
findByTeamIds(teamIds: Array<string>): FindCursor<ITeamMember>;
findByTeamIds(teamIds: Array<string>, options: FindOptions<ITeamMember>): FindCursor<ITeamMember>;
findByTeamIds<P extends Document>(teamIds: Array<string>, options: FindOptions<P>): FindCursor<P>;
findByTeamIds<P extends Document>(
teamIds: Array<string>,
options?: FindOptions<ITeamMember> | FindOptions<P extends ITeamMember ? ITeamMember : P>,
): FindCursor<P> | FindCursor<ITeamMember>;
countByTeamIdAndRole(teamId: string, role: IRole['_id']): Promise<number>;
findByUserIdAndTeamIds(userId: string, teamIds: Array<string>, options?: FindOptions<ITeamMember>): FindCursor<ITeamMember>;
findPaginatedMembersInfoByTeamId(
teamId: string,
limit: number,
skip: number,
query?: Filter<ITeamMember>,
): FindPaginated<FindCursor<Pick<ITeamMember, '_id' | 'userId' | 'roles' | 'createdBy' | 'createdAt'>>>;
updateOneByUserIdAndTeamId(userId: string, teamId: string, update: Partial<ITeamMember>): Promise<UpdateResult>;
createOneByTeamIdAndUserId(
teamId: string,
userId: string,
createdBy: Pick<IUser, '_id' | 'username'>,
): Promise<InsertOneResult<ITeamMember>>;
updateRolesByTeamIdAndUserId(teamId: string, userId: string, roles: Array<IRole['_id']>): Promise<UpdateResult>;
removeRolesByTeamIdAndUserId(teamId: string, userId: string, roles: Array<IRole['_id']>): Promise<UpdateResult>;
deleteByUserIdAndTeamId(userId: string, teamId: string): Promise<DeleteResult>;
deleteByTeamId(teamId: string): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,103 @@
import type { ITeam, TeamType } from '@rocket.chat/core-typings';
import type { FindCursor, UpdateResult, DeleteResult, Filter, Document, FindOptions } from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ITeamModel extends IBaseModel<ITeam> {
findByNames(names: Array<string>): FindCursor<ITeam>;
findByNames(names: Array<string>, options: FindOptions<ITeam>): FindCursor<ITeam>;
findByNames<P extends Document>(names: Array<string>, options: FindOptions<P extends ITeam ? ITeam : P>): FindCursor<P>;
findByNames<P extends Document>(
names: Array<string>,
options?: FindOptions<ITeam> | FindOptions<P extends ITeam ? ITeam : P>,
): FindCursor<P> | FindCursor<ITeam>;
findByIds<P extends Document = ITeam, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
ids: Array<string>,
options?: O,
query?: Filter<ITeam>,
): FindCursor<DocumentWithProjection<P, O>>;
findByIdsPaginated<T extends Document = ITeam, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
ids: Array<string>,
options?: O,
query?: Filter<ITeam>,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findByIdsAndType(ids: Array<string>, type: TeamType): FindCursor<ITeam>;
findByIdsAndType(ids: Array<string>, type: TeamType, options: FindOptions<ITeam>): FindCursor<ITeam>;
findByIdsAndType<P extends Document>(
ids: Array<string>,
type: TeamType,
options: FindOptions<P extends ITeam ? ITeam : P>,
): FindCursor<P>;
findByIdsAndType<P extends Document>(
ids: Array<string>,
type: TeamType,
options?: FindOptions<ITeam> | FindOptions<P extends ITeam ? ITeam : P>,
): FindCursor<P> | FindCursor<ITeam>;
findByType(type: number): FindCursor<ITeam>;
findByType(type: number, options: FindOptions<ITeam>): FindCursor<ITeam>;
findByType<P extends Document>(type: number, options: FindOptions<P extends ITeam ? ITeam : P>): FindCursor<P>;
findByType<P extends Document>(
type: number,
options?: FindOptions<ITeam> | FindOptions<P extends ITeam ? ITeam : P>,
): FindCursor<ITeam> | FindCursor<P>;
findByNameAndTeamIds(name: string | RegExp, teamIds: Array<string>): FindCursor<ITeam>;
findByNameAndTeamIds(name: string | RegExp, teamIds: Array<string>, options: FindOptions<ITeam>): FindCursor<ITeam>;
findByNameAndTeamIds<P extends Document>(
name: string | RegExp,
teamIds: Array<string>,
options: FindOptions<P extends ITeam ? ITeam : P>,
): FindCursor<P>;
findByNameAndTeamIds<P extends Document>(
name: string | RegExp,
teamIds: Array<string>,
options?: FindOptions<ITeam> | FindOptions<P extends ITeam ? ITeam : P>,
): FindCursor<P> | FindCursor<ITeam>;
findOneByName(name: string | RegExp): Promise<ITeam | null>;
findOneByName(name: string | RegExp, options: FindOptions<ITeam>): Promise<ITeam | null>;
findOneByName<P extends Document>(name: string | RegExp, options: FindOptions<P>): Promise<P | null>;
findOneByName<P extends Document>(
name: string | RegExp,
options?: FindOptions<ITeam> | FindOptions<P extends ITeam ? ITeam : P>,
): Promise<P | null> | Promise<ITeam | null>;
findOneByMainRoomId(roomId: string): Promise<ITeam | null>;
findOneByMainRoomId(roomId: string, options: FindOptions<ITeam>): Promise<ITeam | null>;
findOneByMainRoomId<P extends Document>(roomId: string, options: FindOptions<P>): Promise<P | null>;
findOneByMainRoomId<P extends Document>(
roomId: string,
options?: FindOptions<ITeam> | FindOptions<P extends ITeam ? ITeam : P>,
): Promise<P | null> | Promise<ITeam | null>;
updateMainRoomForTeam(id: string, roomId: string): Promise<UpdateResult>;
deleteOneById(id: string): Promise<DeleteResult>;
deleteOneByName(name: string): Promise<DeleteResult>;
updateNameAndType(teamId: string, nameAndType: { name?: string; type?: TeamType }): Promise<UpdateResult>;
}

View File

@@ -0,0 +1,17 @@
import type { ITwoFactorChallenge } from '@rocket.chat/core-typings';
import type { DeleteResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface ITwoFactorChallengesModel extends IBaseModel<ITwoFactorChallenge> {
findOneByPendingChallengeId<
T extends Document = ITwoFactorChallenge,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
id: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
removeByPendingChallengeId(id: string): Promise<DeleteResult>;
createTwoFactorChallenge(userId: string, method: ITwoFactorChallenge['method']): Promise<string>;
}

View File

@@ -0,0 +1,27 @@
import type { IRoom, IUpload } from '@rocket.chat/core-typings';
import type { FindCursor, WithId, Filter, FindOptions, UpdateResult, Document } from 'mongodb';
import type { FindPaginated } from './IBaseModel';
import type { IBaseUploadsModel } from './IBaseUploadsModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IUploadsModel extends IBaseUploadsModel<IUpload> {
findPaginatedWithoutThumbs(query: Filter<IUpload>, options?: any): FindPaginated<FindCursor<WithId<IUpload>>>;
findImagesByRoomId(
rid: IRoom['_id'],
uploadedAt?: Date,
options?: Omit<FindOptions<IUpload>, 'sort'>,
): FindPaginated<FindCursor<WithId<IUpload>>>;
findByFederationMediaIdAndServerName(mediaId: string, serverName: string): Promise<IUpload | null>;
setFederationInfo(fileId: IUpload['_id'], info: Required<IUpload>['federation']): Promise<UpdateResult>;
setFederationRoomInfo(fileId: IUpload['_id'], rid: IRoom['_id'], mrid: string): Promise<UpdateResult>;
findAllByOriginalFileId<T extends Document = IUpload, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
originalFileId: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
}

View File

@@ -0,0 +1,12 @@
import type { IUserDataFile } from '@rocket.chat/core-typings';
import type { Document } from 'mongodb';
import type { IBaseUploadsModel } from './IBaseUploadsModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IUserDataFilesModel extends IBaseUploadsModel<IUserDataFile> {
findLastFileByUser<T extends Document = IUserDataFile, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
}

View File

@@ -0,0 +1,603 @@
import type {
AvailableAgentsAggregation,
IUser,
IRole,
ILivechatAgent,
UserStatus,
ILoginToken,
IPersonalAccessToken,
AtLeast,
ILivechatAgentStatus,
IMeteorLoginToken,
IRoom,
} from '@rocket.chat/core-typings';
import type {
Document,
UpdateResult,
FindCursor,
FindOptions,
Filter,
InsertOneResult,
DeleteResult,
WithId,
UpdateOptions,
UpdateFilter,
BulkWriteResult,
} from 'mongodb';
import type { FindPaginated, IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IUsersModel extends IBaseModel<IUser> {
addRolesByUserId(uid: IUser['_id'], roles: IRole['_id'][]): Promise<UpdateResult>;
findUsersInRoles<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roles: IRole['_id'][] | IRole['_id'],
_scope?: null,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findPaginatedUsersInRoles<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roles: IRole['_id'][] | IRole['_id'],
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findOneByIdWithEmailAddress<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
uid: IUser['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByUsername<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
username: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneAgentById<T extends Document = ILivechatAgent, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id: IUser['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findUsersInRolesWithQuery<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roles: IRole['_id'][] | IRole['_id'],
query: Filter<IUser>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findPaginatedUsersInRolesWithQuery<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roles: IRole['_id'][] | IRole['_id'],
query: Filter<IUser>,
options?: O,
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findOneByUsernameAndRoomIgnoringCase<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
username: string | RegExp,
rid: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByIdAndLoginHashedToken<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id: IUser['_id'],
token: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findByActiveUsersExcept<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
searchTerm: string,
exceptions: string[],
options?: O,
searchFields?: string[],
extraQuery?: Filter<IUser>[],
extra?: { startsWith: boolean; endsWith: boolean },
): FindCursor<DocumentWithProjection<T, O>>;
findPaginatedByActiveUsersExcept<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
searchTerm: string,
exceptions?: string[],
options?: O,
searchFields?: string[],
extraQuery?: Filter<IUser>[],
extra?: { startsWith?: boolean; endsWith?: boolean },
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findPaginatedByActiveLocalUsersExcept<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
searchTerm: string,
exceptions?: string[],
options?: O,
forcedSearchFields?: string[],
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findPaginatedByActiveExternalUsersExcept<
T extends Document = IUser,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
searchTerm: string,
exceptions?: string[],
options?: O,
forcedSearchFields?: string[],
): FindPaginated<FindCursor<DocumentWithProjection<T, O>>>;
findActive<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
query: Filter<IUser>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findActiveByIds<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: IUser['_id'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByIds<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: IUser['_id'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findOneByUsernameIgnoringCase<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
username: IUser['username'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneWithoutLDAPByUsernameIgnoringCase<
T extends Document = IUser,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
username: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByLDAPId<T extends Document = IUser>(id: string, attribute?: string): Promise<T | null>;
findOneByAppId<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
appId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findUsersByIdentifiers<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
params: { usernames?: string[]; ids?: string[]; emails?: string[]; ldapIds?: string[] },
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findLDAPUsers<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findActiveLDAPUsersExceptIds<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: IUser['_id'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findConnectedLDAPUsers<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
isUserInRole(userId: IUser['_id'], roleId: IRole['_id']): Promise<Pick<IUser, 'roles' | '_id'> | null>;
getNextLeastBusyAgent(
department?: string,
ignoreAgentId?: string,
isEnabledWhenAgentIdle?: boolean,
ignoreUsernames?: string[],
acceptChatsWithNoAgents?: boolean,
): Promise<{ agentId: string; username?: string; lastRoutingTime?: Date; count: number }>;
getLastAvailableAgentRouted(
department?: string,
ignoreAgentId?: string,
isEnabledWhenAgentIdle?: boolean,
ignoreUsernames?: string[],
acceptChatsWithNoAgents?: boolean,
): Promise<{ agentId: string; username?: string; lastRoutingTime?: Date }>;
setLastRoutingTime(userId: IUser['_id']): Promise<WithId<IUser> | null>;
setLivechatStatusIf(
userId: IUser['_id'],
status: ILivechatAgentStatus,
conditions?: Filter<IUser>,
extraFields?: UpdateFilter<IUser>['$set'],
): Promise<UpdateResult>;
getAgentAndAmountOngoingChats(
userId: IUser['_id'],
departmentId?: string,
): Promise<{
agentId: string;
username?: string;
lastAssignTime?: Date;
lastRoutingTime?: Date;
queueInfo: { chats: number; chatsForDepartment?: number };
}>;
acquireAgentLock(agentId: IUser['_id'], lockTime: Date, lockTimeoutMs?: number): Promise<boolean>;
releaseAgentLock(agentId: IUser['_id'], lockTime: Date): Promise<boolean>;
findAllResumeTokensByUserId(userId: IUser['_id']): Promise<{ tokens: IMeteorLoginToken[] }[]>;
findActiveByUsernameOrNameRegexWithExceptionsAndConditions<
T extends Document = IUser,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
termRegex: { $regex: string; $options: string } | RegExp,
exceptions?: string[],
conditions?: Filter<IUser>,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countAllAgentsStatus({
departmentId,
}: {
departmentId?: string;
}): Promise<{ offline: number; away: number; busy: number; available: number }[]>;
getTotalOfRegisteredUsersByDate(params: {
start: Date;
end: Date;
options?: { count?: number; sort?: Record<string, 1 | -1> };
}): Promise<{ date: string; users: number; type: 'users' }[]>;
getUserLanguages(): Promise<{ _id: string; total: number }[]>;
setAbacAttributesById(userId: IUser['_id'], attributes: NonNullable<IUser['abacAttributes']>): Promise<IUser | null>;
unsetAbacAttributesById(userId: IUser['_id']): Promise<IUser | null>;
findActiveByRoomIds<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomIds: IRoom['_id'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
setCasExternalIdByUsername(username: string): Promise<IUser | null>;
updateStatusText(_id: IUser['_id'], statusText: string, options?: UpdateOptions): Promise<UpdateResult>;
findExpiredStatuses(): FindCursor<
Pick<
IUser,
| '_id'
| 'username'
| 'type'
| 'roles'
| 'status'
| 'statusDefault'
| 'statusSource'
| 'statusText'
| 'statusExpiresAt'
| 'statusConnection'
| 'statusId'
| 'previousState'
>
>;
findNextStatusExpiration(): Promise<Pick<IUser, '_id' | 'statusExpiresAt'> | null>;
updatePresenceAndStatus(
userId: IUser['_id'],
values: Record<string, unknown>,
clear?: string[],
extraFilter?: Filter<IUser>,
): Promise<IUser | null>;
updateStatusByAppId(appId: string, status: UserStatus): Promise<UpdateResult | Document>;
openAgentsBusinessHoursByBusinessHourId(businessHourIds: string[]): Promise<Document | UpdateResult>;
openAgentBusinessHoursByBusinessHourIdsAndAgentId(businessHourIds: string[], agentId: IUser['_id']): Promise<UpdateResult | Document>;
addBusinessHourByAgentIds(agentIds: string[], businessHourId: string): any;
removeBusinessHourByAgentIds(agentIds: any, businessHourId: any): any;
closeAgentsBusinessHoursByBusinessHourIds(businessHourIds: any): any;
setLivechatStatusActiveBasedOnBusinessHours(userId: any): any;
isAgentWithinBusinessHours(agentId: string): Promise<boolean>;
removeBusinessHoursFromAllUsers(): any;
resetTOTPById(userId: any): any;
unsetLoginTokens(userId: any): any;
unsetOneLoginToken(userId: IUser['_id'], token: string): Promise<UpdateResult>;
removeNonPATLoginTokensExcept(userId: any, authToken: any): any;
removeNonLoginTokensExcept(userId: any, authToken: any): any;
removeRoomsByRoomIdsAndUserId(rids: any, userId: any): any;
removeRolesByUserId(uid: IUser['_id'], roles: IRole['_id'][]): Promise<UpdateResult>;
isUserInRoleScope(uid: IUser['_id']): Promise<boolean>;
addBannerById(_id: IUser['_id'], banner: any): Promise<UpdateResult>;
countActiveUsersTOTPEnable(options: any): Promise<number>;
countActiveUsersEmail2faEnable(options: any): Promise<number>;
findActiveByIdsOrUsernames<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: IUser['_id'][],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
setAsFederated(userId: string): any;
removeRoomByRoomId(rid: any, options?: UpdateOptions): any;
updateStatusById(
userId: IUser['_id'],
{
statusDefault,
status,
statusConnection,
statusText,
}: { statusDefault?: UserStatus; status: UserStatus; statusConnection: UserStatus; statusText?: string },
): Promise<UpdateResult>;
countFederatedExternalUsers(): Promise<number>;
findOnlineUserFromList<T extends Document = ILivechatAgent>(
userList: string | string[],
isLivechatEnabledWhenAgentIdle?: boolean,
acceptChatsWithNoAgents?: boolean,
): FindCursor<T>;
getUnavailableAgents(
departmentId?: string,
extraQuery?: Filter<AvailableAgentsAggregation>,
isLivechatEnabledWhenIdle?: boolean,
acceptChatsWithNoAgents?: boolean,
): Promise<Pick<AvailableAgentsAggregation, 'username'>[]>;
findOneOnlineAgentByUserList<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userList: string[] | string,
options?: O,
isLivechatEnabledWhenAgentIdle?: boolean,
acceptChatsWithNoAgents?: boolean,
): Promise<DocumentWithProjection<T, O> | null>;
findBotAgents<T extends Document = ILivechatAgent>(usernameList?: string | string[]): FindCursor<T>;
countBotAgents(usernameList?: string | string[]): Promise<number>;
removeAllRoomsByUserId(userId: string): Promise<UpdateResult>;
removeRoomByUserId(userId: string, rid: string): Promise<UpdateResult>;
addRoomByUserId(userId: string, rid: string): Promise<UpdateResult>;
addRoomByUserIds(uids: string[], rid: string): Promise<UpdateResult | Document>;
removeRoomByRoomIds(rids: string[]): Promise<UpdateResult | Document>;
addRoomRolePriorityByUserId(userId: string, rid: string, rolePriority: number): Promise<UpdateResult>;
assignRoomRolePrioritiesByUserIdPriorityMap(rolePrioritiesMap: Record<string, number>, rid: string): Promise<number>;
getLoginTokensByUserId(userId: string): FindCursor<ILoginToken>;
addPersonalAccessTokenToUser(data: { userId: string; loginTokenObject: IPersonalAccessToken }): Promise<UpdateResult>;
removePersonalAccessTokenOfUser(data: {
userId: string;
loginTokenObject: AtLeast<IPersonalAccessToken, 'type' | 'name'>;
}): Promise<UpdateResult>;
findPersonalAccessTokenByTokenNameAndUserId({ userId, tokenName }: { userId: IUser['_id']; tokenName: string }): Promise<IUser | null>;
findPersonalAccessTokenByHashedTokenAndUserId({
userId,
hashedToken,
}: {
userId: IUser['_id'];
hashedToken: string;
}): Promise<Pick<IUser, '_id'> | null>;
checkOnlineAgents(agentId?: string, isLivechatEnabledWhenIdle?: boolean, acceptChatsWithNoAgents?: boolean): Promise<boolean>;
findOnlineAgents<T extends Document = ILivechatAgent>(
agentId?: IUser['_id'],
isLivechatEnabledWhenIdle?: boolean,
acceptChatsWithNoAgents?: boolean,
): FindCursor<T>;
findOneOnlineAgentById(
agentId: string,
isLivechatEnabledWhenAgentIdle?: boolean,
acceptChatsWithNoAgents?: boolean,
options?: FindOptions<IUser>,
): Promise<ILivechatAgent | null>;
countAgents(): Promise<number>;
getNextAgent(
ignoreAgentId?: string,
extraQuery?: Filter<AvailableAgentsAggregation>,
enabledWhenAgentIdle?: boolean,
acceptChatsWithNoAgents?: boolean,
): Promise<{ agentId: string; username?: string } | null>;
getNextBotAgent(ignoreAgentId?: string): Promise<{ agentId: string; username?: string } | null>;
setLivechatStatus(userId: string, status: ILivechatAgentStatus): Promise<UpdateResult>;
makeAgentUnavailable(userId: string): Promise<UpdateResult>;
setLivechatData(userId: string, data?: Record<string, any>): Promise<UpdateResult>;
getAgentInfo(
agentId: IUser['_id'],
showAgentEmail?: boolean,
): Promise<Pick<ILivechatAgent, '_id' | 'name' | 'username' | 'phone' | 'customFields' | 'status' | 'livechat' | 'emails'> | null>;
setE2EPublicAndPrivateKeysByUserId(userId: string, e2e: { public_key: string; private_key: string }): Promise<UpdateResult>;
rocketMailUnsubscribe(userId: string, createdAt: string): Promise<number>;
fetchKeysByUserId(userId: string): Promise<{ public_key: string; private_key: string } | object>;
disable2FAAndSetTempSecretByUserId(userId: string, tempSecret: string): Promise<UpdateResult>;
enable2FAAndSetSecretAndCodesByUserId(userId: string, secret: string, codes: string[]): Promise<UpdateResult>;
disable2FAByUserId(userId: string): Promise<UpdateResult>;
update2FABackupCodesByUserId(userId: string, codes: string[]): Promise<UpdateResult>;
enableEmail2FAByUserId(userId: string): Promise<UpdateResult>;
disableEmail2FAByUserId(userId: string): Promise<UpdateResult>;
findByIdsWithPublicE2EKey<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
resetE2EKey(userId: string): Promise<UpdateResult>;
removeExpiredEmailCodeOfUserId(userId: string): Promise<UpdateResult>;
maxInvalidEmailCodeAttemptsReached(userId: string, maxAttemtps: number): Promise<boolean>;
addEmailCodeByUserId(userId: string, code: string, expire: Date): Promise<UpdateResult>;
findActiveUsersInRoles<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roles: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countActiveUsersInRoles(roles: string[], options?: FindOptions<IUser>): Promise<number>;
findOneByUsernameAndServiceNameIgnoringCase<
T extends Document = IUser,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
username: string,
userId: string,
serviceName: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByEmailAddressAndServiceNameIgnoringCase<
T extends Document = IUser,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
emailAddress: string,
userId: string,
serviceName: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByEmailAddress<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
emailAddress: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneWithoutLDAPByEmailAddress<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
emailAddress: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneAdmin<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByIdAndLoginToken<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
loginToken: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneActiveById<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByIdOrUsername<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByRolesAndType<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roles: IRole['_id'][],
type: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
findWithStatusVisibilityConfig(
userIds?: string[],
): FindCursor<Pick<IUser, '_id' | 'username' | 'status' | 'statusText' | 'statusSource' | 'statusExpiresAt' | 'settings'>>;
findPresenceUsersByIds<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findUsersNotOffline<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countUsersNotOffline(options?: FindOptions<IUser>): Promise<number>;
findNotIdUpdatedFrom<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
updatedFrom: Date,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByRoomId<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
roomId: string,
options?: O,
): Promise<FindCursor<DocumentWithProjection<T, O>>>;
findByUsernames<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
usernames: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findByUsernamesIgnoringCase<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
usernames: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findActiveByUserIds<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
countActiveLocalGuests(idsExceptions: string[]): Promise<number>;
findCrowdUsers<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
getLastLogin(options?: FindOptions<IUser>): Promise<Date | undefined>;
findUsersByUsernames<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
usernames: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findUsersByIds<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
getOldest<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
getSAMLByIdAndSAMLProvider(userId: string, samlProvider: string): Promise<IUser | null>;
findBySAMLNameIdOrIdpSession<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
samlNameId: string,
idpSession: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
findBySAMLInResponseTo<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
inResponseTo: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
addImportIds(userId: string, importIds: string | string[]): Promise<UpdateResult>;
updateInviteToken(userId: string, token: string): Promise<UpdateResult>;
updateLastLoginById(userId: string): Promise<UpdateResult>;
addPasswordToHistory(userId: string, password: string, passwordHistoryAmount: number): Promise<UpdateResult>;
setServiceId(userId: string, serviceName: string, serviceId: string): Promise<UpdateResult>;
setUsername(userId: string, username: string, options?: UpdateOptions): Promise<UpdateResult>;
setEmail(userId: string, email: string, verified?: boolean, options?: UpdateOptions): Promise<UpdateResult>;
setEmailVerified(userId: string, email: string): Promise<UpdateResult>;
setName(userId: string, name: string, options?: UpdateOptions): Promise<UpdateResult>;
unsetName(userId: string, options?: UpdateOptions): Promise<UpdateResult>;
setCustomFields(userId: string, customFields: Record<string, unknown>): Promise<UpdateResult>;
setAvatarData(userId: string, origin: string, etag?: Date | null | string, options?: UpdateOptions): Promise<UpdateResult>;
unsetAvatarData(userId: string): Promise<UpdateResult>;
setUserActive(userId: string, active: boolean): Promise<UpdateResult>;
setActiveNotLoggedInAfterWithRole(latestLastLoginDate: Date, role?: string, active?: boolean): Promise<UpdateResult | Document>;
findActiveNotLoggedInAfterWithRole<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
latestLastLoginDate: Date,
role?: string,
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
unsetRequirePasswordChange(userId: string): Promise<UpdateResult>;
resetPasswordAndSetRequirePasswordChange(
userId: string,
requirePasswordChange: boolean,
requirePasswordChangeReason: string,
): Promise<UpdateResult>;
setLanguage(userId: string, language: string): Promise<UpdateResult>;
setProfile(userId: string, profile: Record<string, unknown>): Promise<UpdateResult>;
setBio(userId: string, bio?: string): Promise<UpdateResult>;
setNickname(userId: string, nickname?: string): Promise<UpdateResult>;
clearSettings(userId: string): Promise<UpdateResult>;
setPreferences(userId: string, preferences: Record<string, unknown>): Promise<UpdateResult>;
setTwoFactorAuthorizationHashAndUntilForUserIdAndToken(userId: string, token: string, hash: string, until: Date): Promise<UpdateResult>;
setUtcOffset(userId: string, utcOffset: number): Promise<UpdateResult>;
setReason(userId: string, reason: string): Promise<UpdateResult>;
unsetReason(userId: string): Promise<UpdateResult>;
bannerExistsById(userId: string, bannerId: string): Promise<boolean>;
setBannerReadById(userId: string, bannerId: string): Promise<UpdateResult>;
removeBannerById(userId: string, bannerId: string): Promise<UpdateResult>;
setBannersInBulk(updates: { userId: IUser['_id']; banners: NonNullable<IUser['banners']> }[]): Promise<BulkWriteResult>;
removeSamlServiceSession(userId: string): Promise<UpdateResult>;
setSamlInResponseTo(userId: string, inResponseTo: string): Promise<UpdateResult>;
create(data: Partial<IUser>): Promise<InsertOneResult<IUser>>;
removeById(userId: string): Promise<DeleteResult>;
countActiveUsersByService(service: string, options?: FindOptions<IUser>): Promise<number>;
getActiveLocalUserCount(): Promise<number>;
getActiveLocalGuestCount(exceptions?: IUser['_id'] | IUser['_id'][]): Promise<number>;
removeOlderResumeTokensByUserId(userId: string, fromDate: Date): Promise<UpdateResult>;
findAllUsersWithPendingAvatar(): FindCursor<IUser>;
updateCustomFieldsById(userId: string, customFields: Record<string, unknown>): Promise<UpdateResult>;
countRoomMembers(roomId: string): Promise<number>;
findOneByImportId<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id: IUser['_id'],
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
removeAgent(_id: string): Promise<UpdateResult>;
findAgentsWithDepartments<T extends Document = ILivechatAgent>(
role: IRole['_id'][] | IRole['_id'],
query: Filter<IUser>,
options?: FindOptions<IUser>,
): Promise<{ sortedResults: (T & { departments: string[] })[]; totalCount: { total: number }[] }[]>;
countByRole(roleName: string): Promise<number>;
removeEmailCodeOfUserId(userId: string): Promise<UpdateResult>;
incrementInvalidEmailCodeAttempt(userId: string): Promise<WithId<IUser> | null>;
findOnlineButNotAvailableAgents<T extends Document = ILivechatAgent>(userIds?: IUser['_id'][]): FindCursor<T>;
findAgentsAvailableWithoutBusinessHours(userIds?: IUser['_id'][]): FindCursor<Pick<ILivechatAgent, '_id' | 'openBusinessHours'>>;
updateLivechatStatusByAgentIds(userIds: string[], status: ILivechatAgentStatus): Promise<UpdateResult | Document>;
findOneByFreeSwitchExtension<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
freeSwitchExtension: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
countUsersInRoles(roles: IRole['_id'][]): Promise<number>;
countAllUsersWithPendingAvatar(): Promise<number>;
findOneByIdAndRole<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: IUser['_id'],
role: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
countActiveUsersInNonDMRoom(rid: string): Promise<number>;
countActiveUsersInDMRoom(rid: string): Promise<number>;
verifyEmailByAddress(_id: IUser['_id'], emailAddress: string): Promise<UpdateResult>;
findOneByEmailVerificationToken<T extends Document = IUser, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
token: string,
options?: O,
): Promise<DocumentWithProjection<T, O> | null>;
}

View File

@@ -0,0 +1,21 @@
import type { IUserSession, IUserSessionConnection } from '@rocket.chat/core-typings';
import type { FindCursor, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IUsersSessionsModel extends IBaseModel<IUserSession> {
updateConnectionStatusById(uid: string, connectionId: string, status: string): ReturnType<IBaseModel<IUserSession>['updateOne']>;
removeConnectionsFromInstanceId(instanceId: string): ReturnType<IBaseModel<IUserSession>['updateMany']>;
removeConnectionByConnectionId(connectionId: string): ReturnType<IBaseModel<IUserSession>['updateMany']>;
findByInstanceId(instanceId: string): FindCursor<IUserSession>;
addConnectionById(
userId: string,
{ id, instanceId, status }: Pick<IUserSessionConnection, 'id' | 'instanceId' | 'status'>,
): ReturnType<IBaseModel<IUserSession>['updateOne']>;
findByOtherInstanceIds<T extends Document = IUserSession, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
instanceIds: string[],
options?: O,
): FindCursor<DocumentWithProjection<T, O>>;
removeConnectionsFromOtherInstanceIds(instanceIds: string[]): ReturnType<IBaseModel<IUserSession>['updateMany']>;
}

View File

@@ -0,0 +1,73 @@
import type {
IGroupVideoConference,
ILivechatVideoConference,
IRoom,
IUser,
VideoConference,
VideoConferenceStatus,
IVoIPVideoConference,
} from '@rocket.chat/core-typings';
import type { FindCursor, UpdateOptions, UpdateFilter, UpdateResult, FindOptions } from 'mongodb';
import type { FindPaginated, IBaseModel, InsertionModel } from './IBaseModel';
export interface IVideoConferenceModel extends IBaseModel<VideoConference> {
findPaginatedByRoomId(
rid: IRoom['_id'],
{ offset, count }: { offset?: number; count?: number },
): FindPaginated<FindCursor<VideoConference>>;
findAllLongRunning(minDate: Date): Promise<FindCursor<Pick<VideoConference, '_id'>>>;
countByTypeAndStatus(
type: VideoConference['type'],
status: VideoConferenceStatus,
options: FindOptions<VideoConference>,
): Promise<number>;
createDirect({ providerName, ...callDetails }: Pick<VideoConference, 'rid' | 'createdBy' | 'providerName'>): Promise<string>;
createGroup({
providerName,
...callDetails
}: Required<Pick<IGroupVideoConference, 'rid' | 'title' | 'createdBy' | 'providerName'>>): Promise<string>;
createLivechat({
providerName,
...callDetails
}: Required<Pick<ILivechatVideoConference, 'rid' | 'createdBy' | 'providerName'>>): Promise<string>;
updateOneById(
_id: string,
update: UpdateFilter<VideoConference> | Partial<VideoConference>,
options?: UpdateOptions,
): Promise<UpdateResult>;
setDataById(callId: string, data: Partial<Omit<VideoConference, '_id'>>): Promise<void>;
setEndedById(callId: string, endedBy?: { _id: string; name: string; username: string }, endedAt?: Date): Promise<void>;
setRingingById(callId: string, ringing: boolean): Promise<void>;
setStatusById(callId: string, status: VideoConference['status']): Promise<void>;
setUrlById(callId: string, url: string): Promise<void>;
setProviderDataById(callId: string, providerData: Record<string, any> | undefined): Promise<void>;
addUserById(callId: string, user: Required<Pick<IUser, '_id' | 'name' | 'username' | 'avatarETag'>> & { ts?: Date }): Promise<void>;
setMessageById(callId: string, messageType: keyof VideoConference['messages'], messageId: string): Promise<void>;
updateUserReferences(userId: IUser['_id'], username: IUser['username'], name: IUser['name']): Promise<void>;
increaseAnonymousCount(callId: IGroupVideoConference['_id']): Promise<void>;
unsetDiscussionRidById(callId: string): Promise<void>;
setDiscussionRidById(callId: string, discussionRid: IRoom['_id']): Promise<void>;
unsetDiscussionRid(discussionRid: IRoom['_id']): Promise<void>;
createVoIP(call: InsertionModel<IVoIPVideoConference>): Promise<string | undefined>;
}

View File

@@ -0,0 +1,35 @@
import type { IWebdavAccount } from '@rocket.chat/core-typings';
import type { FindCursor, DeleteResult, Document } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
import type { DocumentWithProjection, FindOptionsWithProjection } from '../types/DocumentWithProjection';
export interface IWebdavAccountsModel extends IBaseModel<IWebdavAccount> {
findOneByIdAndUserId<T extends Document = IWebdavAccount, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
_id: string,
userId: string,
options: O,
): Promise<DocumentWithProjection<T, O> | null>;
findOneByUserIdServerUrlAndUsername<
T extends Document = IWebdavAccount,
O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>,
>(
{
userId,
serverURL,
username,
}: {
userId: string;
serverURL: string;
username: string;
},
options: O,
): Promise<DocumentWithProjection<T, O> | null>;
findWithUserId<T extends Document = IWebdavAccount, O extends FindOptionsWithProjection<T> = FindOptionsWithProjection<T>>(
userId: string,
options: O,
): FindCursor<DocumentWithProjection<T, O>>;
removeByUserAndId(_id: string, userId: string): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,10 @@
import type { IWorkspaceCredentials } from '@rocket.chat/core-typings';
import type { DeleteResult, UpdateResult } from 'mongodb';
import type { IBaseModel } from './IBaseModel';
export interface IWorkspaceCredentialsModel extends IBaseModel<IWorkspaceCredentials> {
getCredentialByScope(scope?: string): Promise<IWorkspaceCredentials | null>;
updateCredentialByScope(credentials: { scope: string; accessToken: string; expirationDate: Date }): Promise<UpdateResult>;
removeAllCredentials(): Promise<DeleteResult>;
}

View File

@@ -0,0 +1,94 @@
import type { Document, FindOneAndUpdateOptions, FindOptions } from 'mongodb';
type Prettify<T> = {
[K in keyof T]: T[K];
} & {};
export type ProjectionValue = 0 | 1 | boolean;
/** Projection operators (`$slice`, `$elemMatch`, `$meta`, positional `$`) hold plain documents. */
export type ProjectionSpec = Record<string, ProjectionValue | Document>;
/**
* `FindOptions` with a projection type that keeps `0`/`1` as literal types when the options object
* is inferred into a generic parameter. The driver's own `FindOptions['projection']` is `Document`
* (`{ [key: string]: any }`), which contains no literal types, so `0` and `1` widen to `number` and
* inclusion becomes indistinguishable from exclusion.
*
* `ProjectionSpec | Document` looks redundant, but both members are load-bearing:
* - `ProjectionSpec` supplies the literal contextual type that keeps `0`/`1` narrow;
* - `Document` keeps assignability identical to the driver's `FindOptions`, so interface-typed
* projections (which get no implicit index signature) keep compiling.
* Do not collapse the union.
*/
export type WithProjectionSpec<O> = Omit<O, 'projection'> & {
projection?: ProjectionSpec | Document;
};
export type FindOptionsWithProjection<T extends Document = Document> = WithProjectionSpec<FindOptions<T>>;
export type FindOneAndUpdateOptionsWithProjection = WithProjectionSpec<FindOneAndUpdateOptions>;
/**
* `Extract<keyof T, '_id'>` would miss documents with a string index signature (`keyof T` collapses
* to `string | number`, which `'_id'` is not a member of), so probe with `extends` instead.
*/
type IdKey<T> = '_id' extends keyof T ? '_id' : never;
type InclusionKeys<P> = { [K in keyof P]-?: P[K] extends 1 | true ? K : never }[keyof P];
type ExclusionKeys<P> = { [K in keyof P]-?: P[K] extends 0 | false ? K : never }[keyof P];
/**
* Applies a projection `P` to a document type `T`, mirroring what `BaseRaw` actually sends to the
* server — see `doNotMixInclusionAndExclusionFields`, which strips every exclusion key (`0` or
* `false`) as soon as one key is an inclusion, so a mixed projection behaves as inclusion-only and
* still returns `_id`.
*
* Bails out to `T` whenever the projection cannot be read statically: dotted paths, `$`-operators,
* computed keys, or values that are not `0`/`1`/`false`/`true` literals.
*/
export type ApplyProjection<T, P> = [keyof P] extends [keyof T]
? [keyof P] extends [InclusionKeys<P> | ExclusionKeys<P>]
? [InclusionKeys<P>] extends [never]
? Omit<T, ExclusionKeys<P> & keyof T>
: Prettify<Pick<T, (InclusionKeys<P> & keyof T) | IdKey<T>>>
: T
: T;
/**
* `NoInfer` blocks contextual inference through the return type: when a call sits in a typed
* position (argument, object literal property), the document type param would otherwise fall back
* to its `Document` constraint instead of its default, degenerating the result to `{ key: any }`.
* The bail-out branches must stay a bare `T` so the no-projection case reduces to exactly the
* document type — implementations that forward a legacy `<T>` generic rely on that identity.
*/
export type DocumentWithProjection<T extends Document, O> = O extends { projection: infer P }
? P extends ProjectionSpec
? ApplyProjection<NoInfer<T>, P>
: T
: T;
/**
* Applies a projection the way the **driver** sees it. `findOneAndUpdate` / `findOneAndDelete` go
* straight to the collection, so they get none of `BaseRaw`'s rewriting. Two consequences:
* - `_id` comes back unless the projection excludes it explicitly, so `{ a: 1, _id: 0 }` really does
* drop `_id` here, where the `find` path would have kept it;
* - mixing inclusion with any other exclusion is a server error, so there is nothing useful to
* describe and we fall back to `T`.
*/
type ApplyDriverProjection<T, P> = [keyof P] extends [keyof T]
? [keyof P] extends [InclusionKeys<P> | ExclusionKeys<P>]
? [InclusionKeys<P>] extends [never]
? Omit<T, ExclusionKeys<P> & keyof T>
: [Exclude<ExclusionKeys<P>, '_id'>] extends [never]
? Prettify<Pick<T, (InclusionKeys<P> & keyof T) | Exclude<IdKey<T>, ExclusionKeys<P>>>>
: T
: T
: T;
export type DocumentWithDriverProjection<T extends Document, O> = O extends { projection: infer P }
? P extends ProjectionSpec
? ApplyDriverProjection<NoInfer<T>, P>
: T
: T;

View File

@@ -0,0 +1,120 @@
/**
* Compile-time assertions for {@link DocumentWithProjection}. Nothing here is meant to run; it
* exists so that `tsc -p tsconfig.json` fails if the projection inference regresses.
*/
import type { Document } from 'mongodb';
import type { DocumentWithDriverProjection, DocumentWithProjection, FindOptionsWithProjection } from './DocumentWithProjection';
type Expect<T extends true> = T;
/** Strict type identity. */
type Equal<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2 ? true : false;
/** Mutual assignability — tolerant of `Prettify`/`Pick` representation differences. */
type Equivalent<A, B> = [A] extends [B] ? ([B] extends [A] ? true : false) : false;
type Doc = {
_id: string;
username?: string;
password: string;
name: string;
roles: string[];
};
type Project<P> = DocumentWithProjection<Doc, { projection: P }>;
/**
* The invariant the whole backward-compatibility story rests on: `projection` is optional in
* `FindOptionsWithProjection`, so the default `O` does not match `{ projection: infer P }` and the
* result collapses to the document type. Making `projection` required would silently change the
* meaning of every call site that passes an explicit generic.
*/
export type NoProjectionCollapsesToDocument = Expect<Equal<DocumentWithProjection<Doc, FindOptionsWithProjection<Doc>>, Doc>>;
export type UndefinedOptionsCollapsesToDocument = Expect<Equal<DocumentWithProjection<Doc, undefined>, Doc>>;
export type Inclusion = Expect<Equivalent<Project<{ username: 1 }>, Pick<Doc, '_id' | 'username'>>>;
export type InclusionKeepsIdImplicitly = Expect<Equivalent<Project<{ name: 1 }>, Pick<Doc, '_id' | 'name'>>>;
export type BooleanInclusion = Expect<Equivalent<Project<{ username: true }>, Pick<Doc, '_id' | 'username'>>>;
export type Exclusion = Expect<Equivalent<Project<{ password: 0 }>, Omit<Doc, 'password'>>>;
export type BooleanExclusion = Expect<Equivalent<Project<{ password: false; name: false }>, Omit<Doc, 'password' | 'name'>>>;
export type ExclusionCanDropId = Expect<Equivalent<Project<{ _id: 0 }>, Omit<Doc, '_id'>>>;
/** `doNotMixInclusionAndExclusionFields` drops the exclusion keys at runtime, so `_id` survives a mix. */
export type MixedBehavesAsInclusion = Expect<Equivalent<Project<{ name: 1; password: 0 }>, Pick<Doc, '_id' | 'name'>>>;
export type MixedBooleanBehavesAsInclusion = Expect<Equivalent<Project<{ name: true; password: false }>, Pick<Doc, '_id' | 'name'>>>;
export type MixedNotationBehavesAsInclusion = Expect<Equivalent<Project<{ name: 1; password: false }>, Pick<Doc, '_id' | 'name'>>>;
export type MixedNotationExclusionStaysExclusion = Expect<
Equivalent<Project<{ password: 0; name: false }>, Omit<Doc, 'password' | 'name'>>
>;
export type MixedKeepsIdEvenWhenExcluded = Expect<Equivalent<Project<{ _id: 0; name: 1 }>, Pick<Doc, '_id' | 'name'>>>;
export type MixedKeepsIdEvenWhenExcludedWithBoolean = Expect<Equivalent<Project<{ _id: false; name: 1 }>, Pick<Doc, '_id' | 'name'>>>;
// Everything below must bail out to the full document rather than guess.
export type DottedPathBailsOut = Expect<Equal<Project<{ 'roles.0': 1 }>, Doc>>;
export type OperatorBailsOut = Expect<Equal<Project<{ roles: { $slice: 5 } }>, Doc>>;
export type MetaBailsOut = Expect<Equal<Project<{ $meta: 'textScore' }>, Doc>>;
export type NonLiteralValueBailsOut = Expect<Equal<Project<{ name: number }>, Doc>>;
export type UnknownKeyBailsOut = Expect<Equal<Project<{ name: 1; notInDoc: 1 }>, Doc>>;
export type WideProjectionBailsOut = Expect<Equal<Project<Record<string, 0 | 1>>, Doc>>;
// Documents with a string index signature collapse `keyof T` to `string | number`, which used to
// make the implicit `_id` disappear from inclusion projections.
type IndexedDoc = {
_id: string;
name: string;
[k: string]: any;
};
export type IndexSignatureKeepsId = Expect<
Equivalent<DocumentWithProjection<IndexedDoc, { projection: { name: 1 } }>, { _id: string; name: string }>
>;
// When a call sits in a contextually typed position (argument, object literal property), inference
// through the return type would drive the document type param to its `Document` constraint instead
// of its default. The `NoInfer` inside `DocumentWithProjection` blocks that.
declare const contextualProbe: {
findOne<P extends Document = Doc, O extends FindOptionsWithProjection<P> = FindOptionsWithProjection<P>>(
options?: O,
): DocumentWithProjection<P, O> | null;
};
export const contextualInferenceKeepsDefault: Pick<Doc, '_id' | 'username'> | null = contextualProbe.findOne({
projection: { username: 1 },
});
// `findOneAndUpdate` / `findOneAndDelete` reach the driver directly, so they get none of BaseRaw's
// rewriting. The two rules below are where driver semantics diverge from the `find` path.
type DriverProject<P> = DocumentWithDriverProjection<Doc, { projection: P }>;
export type DriverInclusion = Expect<Equivalent<DriverProject<{ username: 1 }>, Pick<Doc, '_id' | 'username'>>>;
export type DriverExclusion = Expect<Equivalent<DriverProject<{ password: 0 }>, Omit<Doc, 'password'>>>;
/** `find` keeps `_id` here because BaseRaw strips the `0`; the driver really drops it. */
export type DriverExplicitIdExclusionDropsId = Expect<Equivalent<DriverProject<{ name: 1; _id: 0 }>, Pick<Doc, 'name'>>>;
/** Mixing inclusion with a non-`_id` exclusion is a server error, so there is nothing to describe. */
export type DriverGenuineMixBailsOut = Expect<Equal<DriverProject<{ name: 1; password: 0 }>, Doc>>;
export type DriverNoProjectionCollapses = Expect<Equal<DocumentWithDriverProjection<Doc, undefined>, Doc>>;

View File

@@ -0,0 +1,59 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { Join, NestedPaths, PropertyType, ArrayElement, KeysOfAType, UpdateFilter } from 'mongodb';
export interface Updater<T extends { _id: string }> {
set<K extends keyof SetProps<T>>(key: K, value: SetProps<T>[K]): Updater<T>;
unset<K extends keyof UnsetProps<T>>(key: K): Updater<T>;
inc<K extends keyof IncProps<T>>(key: K, value: number): Updater<T>;
addToSet<K extends keyof AddToSetProps<T>>(key: K, value: ArrayElementType<AddToSetProps<T>[K]>): Updater<T>;
hasChanges(): boolean;
getUpdateFilter(): UpdateFilter<T>;
getRawUpdateFilter(): UpdateFilter<T>;
}
type ArrayElementType<T> = T extends (infer E)[] ? E : T;
/**
* Depth limit for NestedPaths. Starting at [1,1,1,1,1] (length 5) allows
* 3 more levels of recursion (MongoDB's NestedPaths stops at length 8).
* This covers all real usage (e.g. 'metrics.response.avg') while avoiding
* the exponential type expansion that happens at deeper levels.
*/
type NestedPathsDepthLimit = [1, 1, 1, 1, 1];
/**
* Depth-limited version of MongoDB's NestedPathsOfType.
* The original uses NestedPaths<TSchema, []> (unlimited depth),
* which causes exponential type expansion on large schemas.
*/
type NestedPathsOfTypeLimited<TSchema, Type> = KeysOfAType<
{
[Property in Join<NestedPaths<TSchema, NestedPathsDepthLimit>, '.'>]: PropertyType<TSchema, Property>;
},
Type
>;
export type SetProps<TSchema extends { _id: string }> = Readonly<
{
[Property in Join<NestedPaths<TSchema, NestedPathsDepthLimit>, '.'>]: PropertyType<TSchema, Property>;
} & {
[Property in `${NestedPathsOfTypeLimited<TSchema, any[]>}.$${`[${string}]` | ''}`]: ArrayElement<
PropertyType<TSchema, Property extends `${infer Key}.$${string}` ? Key : never>
>;
} & {
[Property in `${NestedPathsOfTypeLimited<TSchema, Record<string, any>[]>}.$${`[${string}]` | ''}.${string}`]: any;
}
>;
type GetType<T, K> = {
[Key in keyof T]: K extends T[Key] ? T[Key] : never;
};
type OmitNever<T> = { [K in keyof T as T[K] extends never ? never : K]: T[K] };
// only allow optional properties
export type UnsetProps<TSchema extends { _id: string }> = OmitNever<GetType<SetProps<TSchema>, undefined>>;
export type IncProps<TSchema extends { _id: string }> = OmitNever<GetType<SetProps<TSchema>, number>>;
export type AddToSetProps<TSchema extends { _id: string }> = OmitNever<GetType<SetProps<TSchema>, any[]>>;

View File

@@ -0,0 +1,5 @@
{
"extends": "./tsconfig.json",
// `*.typetest.ts` holds compile-time assertions only — `yarn typecheck` covers them, the build must not emit them.
"exclude": ["node_modules", "${configDir}/**/*.spec.ts", "${configDir}/**/*.typetest.ts"]
}

View File

@@ -0,0 +1,12 @@
{
"extends": "@rocket.chat/tsconfig/server.json",
"compilerOptions": {
"declaration": true,
"rootDir": "./src",
"outDir": "./dist"
},
"include": ["./src/**/*"],
// restates the inherited exclusions: a child `exclude` replaces the parent's rather than adding to it.
// keeping only `node_modules` lets ESLint and `yarn typecheck` cover the type tests; the build config drops them.
"exclude": ["node_modules"]
}