Skip to content

Commit

Permalink
chore: register a dummy Read Receipts model in CE (#32022)
Browse files Browse the repository at this point in the history
  • Loading branch information
pierre-lehnen-rc authored Mar 28, 2024
1 parent c9a92e6 commit c3fe007
Show file tree
Hide file tree
Showing 5 changed files with 269 additions and 1 deletion.
5 changes: 5 additions & 0 deletions apps/meteor/server/models/ReadReceipts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { registerModel } from '@rocket.chat/models';

import { ReadReceiptsDummy } from './dummy/ReadReceipts';

registerModel('IReadReceiptsModel', new ReadReceiptsDummy(), false);
196 changes: 196 additions & 0 deletions apps/meteor/server/models/dummy/BaseDummy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
import type { RocketChatRecordDeleted } from '@rocket.chat/core-typings';
import type { DefaultFields, FindPaginated, IBaseModel, InsertionModel, ResultFields } from '@rocket.chat/model-typings';
import { getCollectionName } from '@rocket.chat/models';
import type {
BulkWriteOptions,
ChangeStream,
Collection,
DeleteOptions,
DeleteResult,
Document,
Filter,
FindCursor,
FindOptions,
InsertManyResult,
InsertOneOptions,
InsertOneResult,
ModifyResult,
UpdateFilter,
UpdateOptions,
UpdateResult,
WithId,
} from 'mongodb';

export class BaseDummy<
T extends { _id: string },
C extends DefaultFields<T> = undefined,
TDeleted extends RocketChatRecordDeleted<T> = RocketChatRecordDeleted<T>,
> implements IBaseModel<T, C, TDeleted>
{
public readonly col: Collection<T>;

private collectionName: string;

constructor(protected name: string) {
this.collectionName = getCollectionName(name);
this.col = undefined as any;
}

public async createIndexes(): Promise<string[] | void> {
// nothing to do
}

getCollectionName(): string {
return this.collectionName;
}

async findOneAndUpdate(): Promise<ModifyResult<T>> {
return {
value: null,
ok: 1,
};
}

findOneById(_id: T['_id'], options?: FindOptions<T> | undefined): Promise<T | null>;

findOneById<P extends Document = T>(_id: T['_id'], options?: FindOptions<P>): Promise<P | null>;

async findOneById(_id: T['_id'], _options?: any): Promise<T | null> {
return null;
}

findOne(query?: Filter<T> | T['_id'], options?: undefined): Promise<T | null>;

findOne<P extends Document = T>(query: Filter<T> | T['_id'], options: FindOptions<P extends T ? T : P>): Promise<P | null>;

async findOne<P>(_query: Filter<T> | T['_id'], _options?: any): Promise<WithId<T> | WithId<P> | null> {
return null;
}

find(query?: Filter<T>): FindCursor<ResultFields<T, C>>;

find<P extends Document = T>(query: Filter<T>, options: FindOptions<P extends T ? T : P>): FindCursor<P>;

find<P extends Document>(
_query: Filter<T> | undefined,
_options?: FindOptions<P extends T ? T : P>,
): FindCursor<WithId<P>> | FindCursor<WithId<T>> {
return undefined as any;
}

findPaginated<P extends Document = T>(query: Filter<T>, options?: FindOptions<P extends T ? T : P>): FindPaginated<FindCursor<WithId<P>>>;

findPaginated(_query: Filter<T>, _options?: any): FindPaginated<FindCursor<WithId<T>>> {
return {
cursor: undefined as any,
totalCount: Promise.resolve(0),
};
}

async update(
filter: Filter<T>,
update: UpdateFilter<T> | Partial<T>,
options?: UpdateOptions & { multi?: true },
): Promise<UpdateResult | Document> {
return this.updateOne(filter, update, options);
}

async updateOne(_filter: Filter<T>, _update: UpdateFilter<T> | Partial<T>, _options?: UpdateOptions): Promise<UpdateResult> {
return {
acknowledged: true,
matchedCount: 0,
modifiedCount: 0,
upsertedCount: 0,
upsertedId: '' as any,
};
}

async updateMany(filter: Filter<T>, update: UpdateFilter<T> | Partial<T>, options?: UpdateOptions): Promise<Document | UpdateResult> {
return this.updateOne(filter, update, options);
}

async insertMany(_docs: InsertionModel<T>[], _options?: BulkWriteOptions): Promise<InsertManyResult<T>> {
return {
acknowledged: true,
insertedCount: 0,
insertedIds: {},
};
}

async insertOne(_doc: InsertionModel<T>, _options?: InsertOneOptions): Promise<InsertOneResult<T>> {
return {
acknowledged: true,
insertedId: '' as any,
};
}

async removeById(_id: T['_id']): Promise<DeleteResult> {
return {
acknowledged: true,
deletedCount: 0,
};
}

async deleteOne(filter: Filter<T>, options?: DeleteOptions & { bypassDocumentValidation?: boolean }): Promise<DeleteResult> {
return this.deleteMany(filter, options);
}

async deleteMany(_filter: Filter<T>, _options?: DeleteOptions): Promise<DeleteResult> {
return {
acknowledged: true,
deletedCount: 0,
};
}

// Trash
trashFind<P extends TDeleted>(
_query: Filter<TDeleted>,
_options?: FindOptions<P extends TDeleted ? TDeleted : P>,
): FindCursor<WithId<TDeleted>> | undefined {
return undefined as any;
}

trashFindOneById(_id: TDeleted['_id']): Promise<TDeleted | null>;

trashFindOneById<P extends Document>(_id: TDeleted['_id'], options: FindOptions<P extends TDeleted ? TDeleted : P>): Promise<P | null>;

async trashFindOneById<P extends TDeleted>(
_id: TDeleted['_id'],
_options?: FindOptions<P extends TDeleted ? TDeleted : P>,
): Promise<WithId<RocketChatRecordDeleted<P> | TDeleted> | null> {
return 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>> {
return undefined as any;
}

trashFindPaginatedDeletedAfter<P extends Document = TDeleted>(
_deletedAt: Date,
_query?: Filter<TDeleted>,
_options?: FindOptions<P extends TDeleted ? TDeleted : P>,
): FindPaginated<FindCursor<WithId<TDeleted>>> {
return {
cursor: undefined as any,
totalCount: Promise.resolve(0),
};
}

watch(_pipeline?: object[]): ChangeStream<T> {
return undefined as any;
}

async countDocuments(): Promise<number> {
return 0;
}

async estimatedDocumentCount(): Promise<number> {
return 0;
}
}
58 changes: 58 additions & 0 deletions apps/meteor/server/models/dummy/ReadReceipts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import type { IUser, IMessage, ReadReceipt } from '@rocket.chat/core-typings';
import type { IReadReceiptsModel } from '@rocket.chat/model-typings';
import type { FindCursor, DeleteResult, Filter, UpdateResult, Document } from 'mongodb';

import { BaseDummy } from './BaseDummy';

export class ReadReceiptsDummy extends BaseDummy<ReadReceipt> implements IReadReceiptsModel {
constructor() {
super('read_receipts');
}

findByMessageId(_messageId: string): FindCursor<ReadReceipt> {
return this.find({});
}

removeByUserId(_userId: string): Promise<DeleteResult> {
return this.deleteMany({});
}

removeByRoomId(_roomId: string): Promise<DeleteResult> {
return this.deleteMany({});
}

removeByRoomIds(_roomIds: string[]): Promise<DeleteResult> {
return this.deleteMany({});
}

removeByMessageId(_messageId: string): Promise<DeleteResult> {
return this.deleteMany({});
}

removeByMessageIds(_messageIds: string[]): Promise<DeleteResult> {
return this.deleteMany({});
}

removeOTRReceiptsUntilDate(_roomId: string, _until: Date): Promise<DeleteResult> {
return this.deleteMany({});
}

async removeByIdPinnedTimestampLimitAndUsers(
_roomId: string,
_ignorePinned: boolean,
_ignoreDiscussion: boolean,
_ts: Filter<IMessage>['ts'],
_users: IUser['_id'][],
_ignoreThreads: boolean,
): Promise<DeleteResult> {
return this.deleteMany({});
}

setPinnedByMessageId(_messageId: string, _pinned = true): Promise<Document | UpdateResult> {
return this.updateMany({}, {});
}

setAsThreadById(_messageId: string): Promise<Document | UpdateResult> {
return this.updateMany({}, {});
}
}
1 change: 1 addition & 0 deletions apps/meteor/server/models/startup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,4 @@ import './Imports';
import './AppsTokens';
import './CronHistory';
import './Migrations';
import './ReadReceipts';
10 changes: 9 additions & 1 deletion packages/models/src/proxify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,15 @@ function handler<T extends object>(namespace: string): ProxyHandler<T> {
};
}

export function registerModel<TModel extends IBaseModel<any, any, any>>(name: string, instance: TModel | (() => TModel)): void {
export function registerModel<TModel extends IBaseModel<any, any, any>>(
name: string,
instance: TModel | (() => TModel),
overwriteExisting = true,
): void {
if (!overwriteExisting && (lazyModels.has(name) || models.has(name))) {
return;
}

if (typeof instance === 'function') {
lazyModels.set(name, instance);
} else {
Expand Down

0 comments on commit c3fe007

Please sign in to comment.