Skip to content

Commit

Permalink
chore(models): Filter update accumulator (#33018)
Browse files Browse the repository at this point in the history
  • Loading branch information
ggazzo authored Aug 9, 2024
1 parent b3e6d3f commit cab4ceb
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 5 deletions.
7 changes: 5 additions & 2 deletions packages/model-typings/src/updater.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
/* eslint-disable @typescript-eslint/naming-convention */
import type { Join, NestedPaths, PropertyType, ArrayElement, NestedPathsOfType, Filter } from 'mongodb';
import type { Join, NestedPaths, PropertyType, ArrayElement, NestedPathsOfType, Filter, UpdateFilter } from 'mongodb';

export interface Updater<T extends { _id: string }> {
set<P extends SetProps<T>, K extends keyof P>(key: K, value: P[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: AddToSetProps<T>[K]): Updater<T>;
addToSet<K extends keyof AddToSetProps<T>>(key: K, value: ArrayElementType<AddToSetProps<T>[K]>): Updater<T>;
persist(query: Filter<T>): Promise<void>;
hasChanges(): boolean;
getUpdateFilter(): UpdateFilter<T>;
}

type ArrayElementType<T> = T extends (infer E)[] ? E : T;

export type SetProps<TSchema extends { _id: string }> = Readonly<
{
[Property in Join<NestedPaths<TSchema, []>, '.'>]: PropertyType<TSchema, Property>;
Expand Down
18 changes: 17 additions & 1 deletion packages/models/src/updater.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { IOmnichannelRoom } from '@rocket.chat/core-typings';

import { UpdaterImpl } from './updater';

test('updater typings', () => {
Expand All @@ -15,6 +17,20 @@ test('updater typings', () => {
e: string[];
}>({} as any);

const omnichannel = new UpdaterImpl<IOmnichannelRoom>({} as any);
omnichannel.addToSet('v.activity', 'asd');
// @ts-expect-error

Check warning on line 22 in packages/models/src/updater.spec.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer
omnichannel.addToSet('v.activity', 1);
// @ts-expect-error

Check warning on line 24 in packages/models/src/updater.spec.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer
omnichannel.addToSet('v.activity', {
asdas: 1,
});

// @ts-expect-error

Check warning on line 29 in packages/models/src/updater.spec.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer
omnichannel.addToSet('v.activity.asd', {
asdas: 1,
});

updater.addToSet('e', 'a');

// @ts-expect-error

Check warning on line 36 in packages/models/src/updater.spec.ts

View workflow job for this annotation

GitHub Actions / 🔎 Code Check / Code Lint

Include a description after the "@ts-expect-error" directive to explain why the @ts-expect-error is necessary. The description must be 3 characters or longer
Expand Down Expand Up @@ -160,7 +176,7 @@ test('it should add items to array', async () => {
{
_id: 'test',
},
{ $addToSet: { $each: { a: ['b', 'c'] } } },
{ $addToSet: { a: { $each: ['b', 'c'] } } },
);
});

Expand Down
4 changes: 2 additions & 2 deletions packages/models/src/updater.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ export class UpdaterImpl<T extends { _id: string }> implements Updater<T> {
return Object.keys(this.getUpdateFilter()).length > 0;
}

private getUpdateFilter() {
getUpdateFilter() {
return {
...(this._set && { $set: Object.fromEntries(this._set) }),
...(this._unset && { $unset: Object.fromEntries([...this._unset.values()].map((k) => [k, 1])) }),
...(this._inc && { $inc: Object.fromEntries(this._inc) }),
...(this._addToSet && { $addToSet: { $each: Object.fromEntries(this._addToSet) } }),
...(this._addToSet && { $addToSet: Object.fromEntries([...this._addToSet.entries()].map(([k, v]) => [k, { $each: v }])) }),
} as unknown as UpdateFilter<T>;
}
}
Expand Down

0 comments on commit cab4ceb

Please sign in to comment.