diff --git a/apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts b/apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts index 1b922c6b162ed..667722ffcc1ec 100644 --- a/apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts +++ b/apps/meteor/app/custom-sounds/server/methods/insertOrUpdateSound.ts @@ -87,14 +87,12 @@ Meteor.methods({ } if (soundData.name !== soundData.previousName) { - await CustomSounds.setName(soundData._id, soundData.name); - void api.broadcast('notify.updateCustomSound', { - soundData: { - _id: soundData._id, - name: soundData.name, - extension: soundData.extension, - }, - }); + const updatedSound = await CustomSounds.setName(soundData._id, soundData.name); + if (updatedSound) { + void api.broadcast('notify.updateCustomSound', { + soundData: updatedSound, + }); + } } return soundData._id; diff --git a/apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts b/apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts index 64286bb71d86a..14b117794aa22 100644 --- a/apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts +++ b/apps/meteor/app/custom-sounds/server/methods/uploadCustomSound.ts @@ -1,6 +1,7 @@ import { api } from '@rocket.chat/core-services'; import type { RequiredField } from '@rocket.chat/core-typings'; import type { ServerMethods } from '@rocket.chat/ddp-client'; +import { CustomSounds } from '@rocket.chat/models'; import { Meteor } from 'meteor/meteor'; import type { ICustomSoundData } from './insertOrUpdateSound'; @@ -28,8 +29,13 @@ Meteor.methods({ return new Promise((resolve) => { const ws = RocketChatFileCustomSoundsInstance.createWriteStream(`${soundData._id}.${soundData.extension}`, contentType); - ws.on('end', () => { - setTimeout(() => api.broadcast('notify.updateCustomSound', { soundData }), 500); + ws.on('end', async () => { + setTimeout(async () => { + const sound = await CustomSounds.findOneById(soundData._id); + if (sound) { + void api.broadcast('notify.updateCustomSound', { soundData: sound }); + } + }, 500); resolve(); }); diff --git a/apps/meteor/app/file-upload/server/lib/FileUpload.ts b/apps/meteor/app/file-upload/server/lib/FileUpload.ts index 7402c59f01bde..26ff37979ca32 100644 --- a/apps/meteor/app/file-upload/server/lib/FileUpload.ts +++ b/apps/meteor/app/file-upload/server/lib/FileUpload.ts @@ -284,7 +284,7 @@ export const FileUpload = { ); }, - async resizeImagePreview(fileParam: IUpload) { + async resizeImagePreview(fileParam: Pick) { let file = await Uploads.findOneById(fileParam._id); if (!file) { return; @@ -302,7 +302,7 @@ export const FileUpload = { return sharp(await FileUpload.getBuffer(file)).metadata(); }, - async createImageThumbnail(fileParam: IUpload) { + async createImageThumbnail(fileParam: Pick) { if (!settings.get('Message_Attachments_Thumbnails_Enabled')) { return; } @@ -808,7 +808,7 @@ export class FileUploadClass { } private async _validateFile( - fileData: OptionalId, + fileData: Omit, '_updatedAt'>, content: stream.Readable | Buffer | string, ): Promise { const filter = this.store.getFilter(); @@ -835,7 +835,7 @@ export class FileUploadClass { } async _doInsert( - fileData: OptionalId, + fileData: Omit, '_updatedAt'>, content: stream.Readable | Buffer | string, options?: { session?: ClientSession }, ): Promise { @@ -860,7 +860,7 @@ export class FileUploadClass { } async insert( - fileData: OptionalId, + fileData: Omit, '_updatedAt'>, streamOrBuffer: stream.Readable | Buffer | string, options?: { session?: ClientSession }, ): Promise { diff --git a/apps/meteor/app/file-upload/ufs/AmazonS3/server.ts b/apps/meteor/app/file-upload/ufs/AmazonS3/server.ts index 9e00e4ea497f3..af0fc6c267ad9 100644 --- a/apps/meteor/app/file-upload/ufs/AmazonS3/server.ts +++ b/apps/meteor/app/file-upload/ufs/AmazonS3/server.ts @@ -4,7 +4,6 @@ import type { IUpload } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; import S3 from 'aws-sdk/clients/s3'; import { check } from 'meteor/check'; -import type { OptionalId } from 'mongodb'; import _ from 'underscore'; import { SystemLogger } from '../../../../server/lib/logger/system'; @@ -25,11 +24,11 @@ export type S3Options = StoreOptions & { region: string; }; URLExpiryTimeSpan: number; - getPath: (file: OptionalId) => string; + getPath: (file: Omit) => string; }; class AmazonS3Store extends UploadFS.Store { - protected getPath: (file: IUpload) => string; + protected getPath: (file: Omit) => string; constructor(options: S3Options) { // Default options @@ -102,7 +101,7 @@ class AmazonS3Store extends UploadFS.Store { } file.AmazonS3 = { - path: classOptions.getPath(file), + path: classOptions.getPath(file as Omit), }; file.store = this.options.name; // assign store to file diff --git a/apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts b/apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts index e2b71ac8052d7..1503f02892920 100644 --- a/apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts +++ b/apps/meteor/app/file-upload/ufs/GoogleStorage/server.ts @@ -3,7 +3,6 @@ import { Storage } from '@google-cloud/storage'; import type { IUpload } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; import { check } from 'meteor/check'; -import type { OptionalId } from 'mongodb'; import { SystemLogger } from '../../../../server/lib/logger/system'; import { UploadFS } from '../../../../server/ufs'; @@ -19,11 +18,11 @@ type GStoreOptions = StoreOptions & { }; bucket: string; URLExpiryTimeSpan: number; - getPath: (file: OptionalId) => string; + getPath: (file: Omit) => string; }; class GoogleStorageStore extends UploadFS.Store { - protected getPath: (file: IUpload) => string; + protected getPath: (file: Omit) => string; constructor(options: GStoreOptions) { super(options); @@ -80,7 +79,7 @@ class GoogleStorageStore extends UploadFS.Store { } file.GoogleStorage = { - path: options.getPath(file), + path: options.getPath(file as Omit), }; file.store = this.options.name; // assign store to file diff --git a/apps/meteor/app/file-upload/ufs/Webdav/server.ts b/apps/meteor/app/file-upload/ufs/Webdav/server.ts index e5a8a62b5d059..cec619cffd20b 100644 --- a/apps/meteor/app/file-upload/ufs/Webdav/server.ts +++ b/apps/meteor/app/file-upload/ufs/Webdav/server.ts @@ -3,7 +3,6 @@ import stream from 'stream'; import type { IUpload } from '@rocket.chat/core-typings'; import { Random } from '@rocket.chat/random'; import { check } from 'meteor/check'; -import type { OptionalId } from 'mongodb'; import { SystemLogger } from '../../../../server/lib/logger/system'; import { UploadFS } from '../../../../server/ufs'; @@ -19,11 +18,11 @@ type WebdavOptions = StoreOptions & { }; }; uploadFolderPath: string; - getPath: (file: OptionalId) => string; + getPath: (file: Omit) => string; }; class WebdavStore extends UploadFS.Store { - protected getPath: (file: IUpload) => string; + protected getPath: (file: Omit) => string; constructor(options: WebdavOptions) { super(options); @@ -72,7 +71,7 @@ class WebdavStore extends UploadFS.Store { } file.Webdav = { - path: options.getPath(file), + path: options.getPath(file as Omit), }; file.store = this.options.name; diff --git a/apps/meteor/app/importer/server/classes/converters/RecordConverter.ts b/apps/meteor/app/importer/server/classes/converters/RecordConverter.ts index 4b3658febde3b..e8fe9a13754d8 100644 --- a/apps/meteor/app/importer/server/classes/converters/RecordConverter.ts +++ b/apps/meteor/app/importer/server/classes/converters/RecordConverter.ts @@ -158,6 +158,7 @@ export class RecordConverter, fileUrl: string) => { +const getUploadFile = async (details: Omit, fileUrl: string) => { const isSsrfSafe = await checkUrlForSsrf(fileUrl); if (!isSsrfSafe) { throw new Meteor.Error('error-invalid-url', 'Invalid URL'); diff --git a/apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts b/apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts index 92f3ed840682f..188b427874aef 100644 --- a/apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts +++ b/apps/meteor/app/livechat/server/business-hour/LivechatBusinessHours.ts @@ -3,7 +3,7 @@ import { LivechatBusinessHourTypes } from '@rocket.chat/core-typings'; import moment from 'moment-timezone'; import { ObjectId } from 'mongodb'; -export const createDefaultBusinessHourRow = (): ILivechatBusinessHour => { +export const createDefaultBusinessHourRow = (): Omit => { const days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']; const closedDays = ['Saturday', 'Sunday']; return { diff --git a/apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts b/apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts index fb379eb9b6693..aa70b15175c61 100644 --- a/apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts +++ b/apps/meteor/app/livechat/server/business-hour/filterBusinessHoursThatMustBeOpened.ts @@ -2,7 +2,7 @@ import type { ILivechatBusinessHour } from '@rocket.chat/core-typings'; import moment from 'moment'; export const filterBusinessHoursThatMustBeOpened = async ( - businessHours: ILivechatBusinessHour[], + businessHours: Omit[], ): Promise[]> => { const currentTime = moment(moment().format('dddd:HH:mm:ss'), 'dddd:HH:mm:ss'); diff --git a/apps/meteor/client/components/ImageGallery/ImageGallery.tsx b/apps/meteor/client/components/ImageGallery/ImageGallery.tsx index 9884c463e8986..cb98fbd068703 100644 --- a/apps/meteor/client/components/ImageGallery/ImageGallery.tsx +++ b/apps/meteor/client/components/ImageGallery/ImageGallery.tsx @@ -98,7 +98,15 @@ const swiperStyle = css` } `; -export const ImageGallery = ({ images, onClose, loadMore }: { images: IUpload[]; onClose: () => void; loadMore?: () => void }) => { +export const ImageGallery = ({ + images, + onClose, + loadMore, +}: { + images: Pick[]; + onClose: () => void; + loadMore?: () => void; +}) => { const { t } = useTranslation(); const swiperRef = useRef(null); const [, setSwiperInst] = useState(); diff --git a/apps/meteor/client/hooks/useWorkspaceInfo.ts b/apps/meteor/client/hooks/useWorkspaceInfo.ts index e5efd1f6a508d..657711cf8abf0 100644 --- a/apps/meteor/client/hooks/useWorkspaceInfo.ts +++ b/apps/meteor/client/hooks/useWorkspaceInfo.ts @@ -53,15 +53,15 @@ export const useWorkspaceInfo = ({ refreshStatistics }: { refreshStatistics?: bo queryFn: () => getStatistics({ refresh: refreshStatistics ? 'true' : 'false' }), staleTime: Infinity, placeholderData: keepPreviousData, - select: (data: unknown) => { - const statsData = data as Serialized; + select: (data: Serialized): IStats => { return { - ...statsData, - lastMessageSentAt: statsData.lastMessageSentAt ? new Date(statsData.lastMessageSentAt) : undefined, + ...data, + lastMessageSentAt: data.lastMessageSentAt ? new Date(data.lastMessageSentAt) : undefined, + _updatedAt: new Date(data._updatedAt), }; }, }, - ], + ] as const, }); }; diff --git a/apps/meteor/client/lib/userStatuses.ts b/apps/meteor/client/lib/userStatuses.ts index 631c1d1ea0442..5d334ccd99c21 100644 --- a/apps/meteor/client/lib/userStatuses.ts +++ b/apps/meteor/client/lib/userStatuses.ts @@ -33,7 +33,7 @@ export class UserStatuses implements Iterable { this.store.set(customUserStatus.id, customUserStatus); } - public createFromCustom(customUserStatus: ICustomUserStatus): UserStatusDescriptor { + public createFromCustom(customUserStatus: Omit): UserStatusDescriptor { if (!this.isValidType(customUserStatus.statusType)) { throw new Error('Invalid user status type'); } diff --git a/apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx b/apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx index 03499b5a214c4..4dfcedaa1752f 100644 --- a/apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx +++ b/apps/meteor/client/providers/CustomSoundProvider/CustomSoundProvider.tsx @@ -23,7 +23,7 @@ const CustomSoundProvider = ({ children }: CustomSoundProviderProps) => { const { notificationsSoundVolume, voipRingerVolume } = useUserSoundPreferences(); const { data: list } = useQuery({ - queryFn: async () => { + queryFn: async (): Promise[]> => { const customSoundsList = await sdk.call('listCustomSounds'); if (!customSoundsList.length) { return defaultSounds; diff --git a/apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts b/apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts index 49cc0a14b6c81..5383ed6e9fe95 100644 --- a/apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts +++ b/apps/meteor/client/providers/CustomSoundProvider/lib/helpers.ts @@ -25,7 +25,7 @@ export const soundTranslationKeys: Record = { 'ringtone': 'Sound_Ringtone', }; -export const defaultSounds: ICustomSound[] = [ +export const defaultSounds: Omit[] = [ { _id: 'chime', name: 'Sound_Chime', extension: 'mp3', src: getAssetUrl('sounds/chime.mp3') }, { _id: 'door', name: 'Sound_Door', extension: 'mp3', src: getAssetUrl('sounds/door.mp3') }, { _id: 'beep', name: 'Sound_Beep', extension: 'mp3', src: getAssetUrl('sounds/beep.mp3') }, diff --git a/apps/meteor/client/startup/roles.ts b/apps/meteor/client/startup/roles.ts index de1121d25d69d..1c57f436018dd 100644 --- a/apps/meteor/client/startup/roles.ts +++ b/apps/meteor/client/startup/roles.ts @@ -11,7 +11,7 @@ Meteor.startup(() => { onLoggedIn(async () => { const { roles } = await sdk.rest.get('/v1/roles.list'); // if a role is checked before this collection is populated, it will return undefined - Roles.state.replaceAll(roles); + Roles.state.replaceAll(roles.map((role) => ({ ...role, _updatedAt: new Date(role._updatedAt) }))); }); type ClientAction = 'inserted' | 'updated' | 'removed' | 'changed'; diff --git a/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx b/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx index 9b2bdb4f63eb9..1f8cdec005127 100644 --- a/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx +++ b/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.spec.tsx @@ -42,6 +42,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'owner', + _updatedAt: new Date(), }, { description: 'Administrator', @@ -49,6 +50,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'admin', + _updatedAt: new Date(), }, ]; diff --git a/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx b/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx index aa6727e3e939b..6edd0faaed95d 100644 --- a/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx +++ b/apps/meteor/client/views/admin/permissions/PermissionsTable/PermissionsTable.stories.tsx @@ -24,6 +24,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'owner', + _updatedAt: new Date(), }, { description: 'Administrator', @@ -31,6 +32,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'admin', + _updatedAt: new Date(), }, { description: 'Leader', @@ -38,6 +40,7 @@ const roles: IRole[] = [ protected: false, scope: 'Subscriptions', _id: 'leader', + _updatedAt: new Date(), }, { description: 'Moderator', @@ -45,6 +48,7 @@ const roles: IRole[] = [ protected: false, scope: 'Subscriptions', _id: 'moderator', + _updatedAt: new Date(), }, { description: 'User', @@ -52,6 +56,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'user', + _updatedAt: new Date(), }, { description: 'Guest', @@ -59,6 +64,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'guest', + _updatedAt: new Date(), }, { description: 'Bot', @@ -66,6 +72,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'bot', + _updatedAt: new Date(), }, { description: 'App', @@ -73,6 +80,7 @@ const roles: IRole[] = [ protected: true, scope: 'Users', _id: 'app', + _updatedAt: new Date(), }, ]; diff --git a/apps/meteor/client/views/admin/users/AdminUserForm.tsx b/apps/meteor/client/views/admin/users/AdminUserForm.tsx index 0f128cfeda2ef..e23197b6231c3 100644 --- a/apps/meteor/client/views/admin/users/AdminUserForm.tsx +++ b/apps/meteor/client/views/admin/users/AdminUserForm.tsx @@ -50,7 +50,7 @@ type AdminUserFormProps = { onReload: () => void; context: string; refetchUserFormData?: () => void; - roleData: { roles: IRole[] } | undefined; + roleData: { roles: Serialized[] } | undefined; roleError: Error | null; }; diff --git a/apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx b/apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx index e24cbb5d154a6..8e599cc13796d 100644 --- a/apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx +++ b/apps/meteor/client/views/admin/users/AdminUserFormWithData.tsx @@ -1,4 +1,4 @@ -import type { IRole, IUser } from '@rocket.chat/core-typings'; +import type { IRole, IUser, Serialized } from '@rocket.chat/core-typings'; import { Box, Callout } from '@rocket.chat/fuselage'; import { useEffectEvent } from '@rocket.chat/fuselage-hooks'; import type { ReactElement } from 'react'; @@ -12,7 +12,7 @@ type AdminUserFormWithDataProps = { uid: IUser['_id']; onReload: () => void; context: string; - roleData: { roles: IRole[] } | undefined; + roleData: { roles: Serialized[] } | undefined; roleError: Error | null; }; diff --git a/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx b/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx index 56077c49125f6..e5caa47d1d1c3 100644 --- a/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx +++ b/apps/meteor/client/views/admin/users/UsersTable/UsersTable.tsx @@ -24,7 +24,7 @@ import { useShowVoipExtension } from '../useShowVoipExtension'; type UsersTableProps = { tab: AdminUsersTab; - roleData: { roles: IRole[] } | undefined; + roleData: { roles: Serialized[] } | undefined; users: Serialized[]; total: number; isLoading: boolean; diff --git a/apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx b/apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx index 5f7265c1b2fb6..42e007de6f508 100644 --- a/apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx +++ b/apps/meteor/client/views/admin/users/UsersTable/UsersTableFilters.tsx @@ -1,4 +1,4 @@ -import type { IRole } from '@rocket.chat/core-typings'; +import type { IRole, Serialized } from '@rocket.chat/core-typings'; import { Box, Icon, Margins, TextInput } from '@rocket.chat/fuselage'; import { useBreakpoints } from '@rocket.chat/fuselage-hooks'; import type { OptionProp } from '@rocket.chat/ui-client'; @@ -11,7 +11,7 @@ import type { UsersFilters } from '../AdminUsersPage'; type UsersTableFiltersProps = { setUsersFilters: Dispatch>; - roleData: { roles: IRole[] } | undefined; + roleData: { roles: Serialized[] } | undefined; }; const UsersTableFilters = ({ roleData, setUsersFilters }: UsersTableFiltersProps) => { diff --git a/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx index d9fbddc9e3e92..6c52749684d84 100644 --- a/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx +++ b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.stories.tsx @@ -25,7 +25,6 @@ Default.args = { connected: true, }, instanceRecord: { - _updatedAt: new Date(), _createdAt: new Date(), _id: 'instance-id', name: 'instance-name', diff --git a/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx index 0553f692d5d22..06eb87223d30c 100644 --- a/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx +++ b/apps/meteor/client/views/admin/workspace/DeploymentCard/components/InstancesModal/InstancesModal.tsx @@ -70,15 +70,6 @@ const InstancesModal = ({ instances = [], onClose }: InstancesModalProps) => { > {formatDateAndTime(instanceRecord?._createdAt)} - - {t('Instance_Record')} > {t('Updated_at')} - - } - > - {formatDateAndTime(instanceRecord?._updatedAt)} - ))} diff --git a/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx b/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx index a8202f637b17b..2110fbbe6a55b 100644 --- a/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx +++ b/apps/meteor/client/views/omnichannel/tags/TagEdit.tsx @@ -24,7 +24,7 @@ type TagEditPayload = { }; type TagEditProps = { - tagData?: ILivechatTag; + tagData?: Serialized; currentDepartments?: Serialized[]; onClose: () => void; }; diff --git a/apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx b/apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx index ae0ae162deccd..a62497a0d5e31 100644 --- a/apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx +++ b/apps/meteor/client/views/omnichannel/tags/TagEditWithDepartmentData.tsx @@ -1,4 +1,4 @@ -import type { ILivechatTag } from '@rocket.chat/core-typings'; +import type { ILivechatTag, Serialized } from '@rocket.chat/core-typings'; import { Callout } from '@rocket.chat/fuselage'; import { ContextualbarSkeletonBody } from '@rocket.chat/ui-client'; import { useTranslation, useEndpoint } from '@rocket.chat/ui-contexts'; @@ -6,7 +6,7 @@ import { useQuery } from '@tanstack/react-query'; import TagEdit from './TagEdit'; -const TagEditWithDepartmentData = ({ tagData, onClose }: { tagData: ILivechatTag; onClose: () => void }) => { +const TagEditWithDepartmentData = ({ tagData, onClose }: { tagData: Serialized; onClose: () => void }) => { const t = useTranslation(); const getDepartmentsById = useEndpoint('GET', '/v1/livechat/department.listByIds'); diff --git a/apps/meteor/client/views/room/ImageGallery/hooks/useImagesList.ts b/apps/meteor/client/views/room/ImageGallery/hooks/useImagesList.ts index 6cf84aa0d96a3..72f0937e9019e 100644 --- a/apps/meteor/client/views/room/ImageGallery/hooks/useImagesList.ts +++ b/apps/meteor/client/views/room/ImageGallery/hooks/useImagesList.ts @@ -26,6 +26,7 @@ export const useImagesList = ({ roomId, startingFromId }: { roomId: IRoom['_id'] uploadedAt: file.uploadedAt ? new Date(file.uploadedAt) : undefined, modifiedAt: file.modifiedAt ? new Date(file.modifiedAt) : undefined, expiresAt: file.expiresAt ? new Date(file.expiresAt) : undefined, + _updatedAt: new Date(file._updatedAt), })); for await (const file of items) { diff --git a/apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx b/apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx index bae5571abf330..35d05fb0e9fca 100644 --- a/apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx +++ b/apps/meteor/client/views/room/contextualBar/RoomFiles/RoomFiles.stories.tsx @@ -27,6 +27,7 @@ Default.args = { _id: 'rocket.cat', username: 'rocket.cat', }, + _updatedAt: new Date(), }, { _id: '2', @@ -37,6 +38,7 @@ Default.args = { _id: 'rocket.cat', username: 'rocket.cat', }, + _updatedAt: new Date(), }, ], text: 'Ipsum', diff --git a/apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx b/apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx index 27fa12c8cc9f6..dde7696274477 100644 --- a/apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx +++ b/apps/meteor/client/views/room/contextualBar/RoomFiles/components/FileItem.stories.tsx @@ -23,5 +23,6 @@ Default.args = { _id: 'rocket.cat', username: 'rocket.cat', }, + _updatedAt: new Date(), }, }; diff --git a/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts b/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts index 954f5acb80647..4fc17e6449efb 100644 --- a/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts +++ b/apps/meteor/client/views/room/contextualBar/RoomFiles/hooks/useFilesList.ts @@ -42,6 +42,7 @@ export const useFilesList = ({ rid, type, text }: { rid: Required['rid' uploadedAt: file.uploadedAt ? new Date(file.uploadedAt) : undefined, modifiedAt: file.modifiedAt ? new Date(file.modifiedAt) : undefined, expiresAt: file.expiresAt ? new Date(file.expiresAt) : undefined, + _updatedAt: new Date(file._updatedAt), })); for await (const file of items) { diff --git a/apps/meteor/ee/server/lib/roles/insertRole.ts b/apps/meteor/ee/server/lib/roles/insertRole.ts index 321490055c034..d9151fee7b876 100644 --- a/apps/meteor/ee/server/lib/roles/insertRole.ts +++ b/apps/meteor/ee/server/lib/roles/insertRole.ts @@ -9,7 +9,7 @@ type InsertRoleOptions = { broadcastUpdate?: boolean; }; -export const insertRoleAsync = async (roleData: Omit, options: InsertRoleOptions = {}): Promise => { +export const insertRoleAsync = async (roleData: Omit, options: InsertRoleOptions = {}): Promise => { const { name, scope, description, mandatory2fa } = roleData; if (await Roles.findOneByName(name)) { diff --git a/apps/meteor/ee/server/lib/roles/updateRole.ts b/apps/meteor/ee/server/lib/roles/updateRole.ts index 0cde11cd0a7a4..7f1cf926c22db 100644 --- a/apps/meteor/ee/server/lib/roles/updateRole.ts +++ b/apps/meteor/ee/server/lib/roles/updateRole.ts @@ -9,7 +9,11 @@ type UpdateRoleOptions = { broadcastUpdate?: boolean; }; -export const updateRole = async (roleId: IRole['_id'], roleData: Omit, options: UpdateRoleOptions = {}): Promise => { +export const updateRole = async ( + roleId: IRole['_id'], + roleData: Omit, + options: UpdateRoleOptions = {}, +): Promise => { const role = await Roles.findOneById(roleId); if (!role) { diff --git a/apps/meteor/ee/server/models/raw/LivechatTag.ts b/apps/meteor/ee/server/models/raw/LivechatTag.ts index 0002679054336..ff4e144362cfd 100644 --- a/apps/meteor/ee/server/models/raw/LivechatTag.ts +++ b/apps/meteor/ee/server/models/raw/LivechatTag.ts @@ -29,7 +29,7 @@ export class LivechatTagRaw extends BaseRaw implements ILivechatTa _id: string | undefined, { name, description }: { name: string; description?: string }, departments: string[] = [], - ): Promise { + ): Promise> { const record = { name, description, diff --git a/apps/meteor/server/services/import/service.ts b/apps/meteor/server/services/import/service.ts index b2a39260a3f08..636bf4d1877ee 100644 --- a/apps/meteor/server/services/import/service.ts +++ b/apps/meteor/server/services/import/service.ts @@ -144,6 +144,7 @@ export class ImportService extends ServiceClassInternal implements IImportServic roles: data.roles ? [...new Set([...data.roles, ...defaultRoles])] : defaultRoles, }, dataType: 'user', + _updatedAt: new Date(), })), ); diff --git a/apps/meteor/server/ufs/ufs-filter.ts b/apps/meteor/server/ufs/ufs-filter.ts index 37002260a4ed5..5cc85cf1a2b8e 100644 --- a/apps/meteor/server/ufs/ufs-filter.ts +++ b/apps/meteor/server/ufs/ufs-filter.ts @@ -59,7 +59,7 @@ export class Filter { } } - async check(file: OptionalId, content?: Buffer | string) { + async check(file: Omit, '_updatedAt'>, content?: Buffer | string) { let error = null; if (typeof file !== 'object' || !file) { error = this.options.invalidFileError(); @@ -137,7 +137,7 @@ export class Filter { return result; } - async onCheck(_file: OptionalId, _content?: Buffer | string) { + async onCheck(_file: Omit, '_updatedAt'>, _content?: Buffer | string) { return true; } } diff --git a/apps/meteor/server/ufs/ufs-store.ts b/apps/meteor/server/ufs/ufs-store.ts index 3c6d6c983850f..6368d28689616 100644 --- a/apps/meteor/server/ufs/ufs-store.ts +++ b/apps/meteor/server/ufs/ufs-store.ts @@ -42,7 +42,7 @@ export class Store { callback?: (err?: Error, copyId?: string, copy?: OptionalId, store?: Store) => void, ) => Promise; - public create: (file: OptionalId, options?: { session?: ClientSession }) => Promise; + public create: (file: Omit, '_updatedAt'>, options?: { session?: ClientSession }) => Promise; public write: ( rs: stream.Readable, diff --git a/apps/meteor/tests/data/livechat/department.ts b/apps/meteor/tests/data/livechat/department.ts index dec18b189e82d..128a0ada4887e 100644 --- a/apps/meteor/tests/data/livechat/department.ts +++ b/apps/meteor/tests/data/livechat/department.ts @@ -197,7 +197,7 @@ export const archiveDepartment = async (departmentId: string): Promise => .expect(200); }; -export const disableDepartment = async (department: ILivechatDepartment): Promise => { +export const disableDepartment = async (department: Omit): Promise => { department.enabled = false; delete department._updatedAt; const updatedDepartment = await updateDepartment(department._id, department); diff --git a/apps/meteor/tests/mocks/data.ts b/apps/meteor/tests/mocks/data.ts index fb8859a3055b2..b0de7222184a3 100644 --- a/apps/meteor/tests/mocks/data.ts +++ b/apps/meteor/tests/mocks/data.ts @@ -440,6 +440,7 @@ export function createFakeTag(overrides?: Partial>): Se description: 'description', numDepartments: 0, departments: [], + _updatedAt: new Date().toISOString(), ...overrides, }; } diff --git a/packages/core-services/src/events/Events.ts b/packages/core-services/src/events/Events.ts index b80b6a7d90061..0161e68649e6e 100644 --- a/packages/core-services/src/events/Events.ts +++ b/packages/core-services/src/events/Events.ts @@ -3,7 +3,6 @@ import type { ISetting as AppsSetting } from '@rocket.chat/apps-engine/definitio import type { IEmailInbox, IEmoji, - IInquiry, IInstanceStatus, IIntegration, IIntegrationHistory, @@ -72,7 +71,7 @@ export type EventSignatures = { 'license.sync'(): void; 'license.actions'(actions: Record, boolean>): void; - 'livechat-inquiry-queue-observer'(data: { action: string; inquiry: IInquiry }): void; + 'livechat-inquiry-queue-observer'(data: { action: string; inquiry: ILivechatInquiryRecord }): void; 'message'(data: { action: string; message: IMessage }): void; 'meteor.clientVersionUpdated'(data: AutoUpdateRecord): void; 'notify.desktop'(uid: string, data: INotificationDesktop): void; diff --git a/packages/core-typings/src/IBanner.ts b/packages/core-typings/src/IBanner.ts index a78378e90c82f..1ef708924441e 100644 --- a/packages/core-typings/src/IBanner.ts +++ b/packages/core-typings/src/IBanner.ts @@ -1,7 +1,7 @@ import type * as UiKit from '@rocket.chat/ui-kit'; import * as z from 'zod'; -import type { IRocketChatRecord } from './IRocketChatRecord'; +import { IRocketChatRecordSchema, type IRocketChatRecord } from './IRocketChatRecord'; import type { IUser } from './IUser'; import { TimestampSchema } from './utils'; @@ -10,9 +10,7 @@ export enum BannerPlatform { Mobile = 'mobile', } -export const IBannerSchema = z.object({ - _id: z.string(), - _updatedAt: TimestampSchema.optional(), +export const IBannerSchema = IRocketChatRecordSchema.extend({ platform: z.array(z.enum(BannerPlatform)), // pĺatforms a banner could be shown expireAt: TimestampSchema, // date when banner should not be shown anymore startAt: TimestampSchema, // start date a banner should be presented @@ -34,7 +32,7 @@ export const IBannerSchema = z.object({ surface: z.enum(['banner', 'modal']), }); -export interface IBanner extends z.infer {} +export interface IBanner extends z.infer, IRocketChatRecord {} export type InactiveBanner = IBanner & { active: false; diff --git a/packages/core-typings/src/ICredentialToken.ts b/packages/core-typings/src/ICredentialToken.ts index ceaf44203cbad..319357d6fd24a 100644 --- a/packages/core-typings/src/ICredentialToken.ts +++ b/packages/core-typings/src/ICredentialToken.ts @@ -1,6 +1,6 @@ -export interface ICredentialToken { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; +export interface ICredentialToken extends IRocketChatRecord { userInfo: { username?: string; attributes?: any; diff --git a/packages/core-typings/src/ICronHistoryItem.ts b/packages/core-typings/src/ICronHistoryItem.ts index fdf42ea88f739..c269b57a8ae30 100644 --- a/packages/core-typings/src/ICronHistoryItem.ts +++ b/packages/core-typings/src/ICronHistoryItem.ts @@ -1,5 +1,6 @@ -export interface ICronHistoryItem { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface ICronHistoryItem extends IRocketChatRecord { name: string; intendedAt: Date; startedAt: Date; diff --git a/packages/core-typings/src/ICustomSound.ts b/packages/core-typings/src/ICustomSound.ts index de925a0516db5..47d880851478b 100644 --- a/packages/core-typings/src/ICustomSound.ts +++ b/packages/core-typings/src/ICustomSound.ts @@ -1,8 +1,8 @@ -export interface ICustomSound { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface ICustomSound extends IRocketChatRecord { name: string; extension: string; src?: string; random?: unknown; - _updatedAt?: Date; } diff --git a/packages/core-typings/src/ICustomUserStatus.ts b/packages/core-typings/src/ICustomUserStatus.ts index a1d9e40a22698..4341ba80f91d5 100644 --- a/packages/core-typings/src/ICustomUserStatus.ts +++ b/packages/core-typings/src/ICustomUserStatus.ts @@ -1,5 +1,4 @@ +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IUserStatus } from './IUserStatus'; -export interface ICustomUserStatus extends IUserStatus { - _updatedAt?: Date; -} +export interface ICustomUserStatus extends IUserStatus, IRocketChatRecord {} diff --git a/packages/core-typings/src/IEmailInbox.ts b/packages/core-typings/src/IEmailInbox.ts index 32b73dc9efc93..c594626ebab15 100644 --- a/packages/core-typings/src/IEmailInbox.ts +++ b/packages/core-typings/src/IEmailInbox.ts @@ -1,5 +1,6 @@ -export interface IEmailInbox { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IEmailInbox extends IRocketChatRecord { active: boolean; name: string; email: string; @@ -26,7 +27,6 @@ export interface IEmailInbox { _id: string; username?: string; } | null; - _updatedAt: Date; } export type IEmailInboxPayload = Omit; diff --git a/packages/core-typings/src/IEmailMessageHistory.ts b/packages/core-typings/src/IEmailMessageHistory.ts index cacfac34d9800..ce74eb93accd2 100644 --- a/packages/core-typings/src/IEmailMessageHistory.ts +++ b/packages/core-typings/src/IEmailMessageHistory.ts @@ -1,5 +1,6 @@ -export interface IEmailMessageHistory { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IEmailMessageHistory extends IRocketChatRecord { email: string; createdAt?: Date; } diff --git a/packages/core-typings/src/IInquiry.ts b/packages/core-typings/src/IInquiry.ts index 24d8d4291a941..53aa481727839 100644 --- a/packages/core-typings/src/IInquiry.ts +++ b/packages/core-typings/src/IInquiry.ts @@ -6,12 +6,6 @@ import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IOmnichannelRoom, OmnichannelSourceType } from './IRoom'; import type { SelectedAgent } from './omnichannel/routing'; -export interface IInquiry { - _id: string; - _updatedAt?: Date; - department?: string; -} - export enum LivechatInquiryStatus { VERIFYING = 'verifying', QUEUED = 'queued', diff --git a/packages/core-typings/src/IInstanceStatus.ts b/packages/core-typings/src/IInstanceStatus.ts index d5fd280280b47..a1b762db622bf 100644 --- a/packages/core-typings/src/IInstanceStatus.ts +++ b/packages/core-typings/src/IInstanceStatus.ts @@ -1,6 +1,5 @@ -import type { IRocketChatRecord } from './IRocketChatRecord'; - -export interface IInstanceStatus extends IRocketChatRecord { +export interface IInstanceStatus { + _id: string; _createdAt: Date; name: string; pid: number; diff --git a/packages/core-typings/src/IIntegrationHistory.ts b/packages/core-typings/src/IIntegrationHistory.ts index 3b9750a540906..9abd882604601 100644 --- a/packages/core-typings/src/IIntegrationHistory.ts +++ b/packages/core-typings/src/IIntegrationHistory.ts @@ -10,7 +10,6 @@ export interface IIntegrationHistory extends IRocketChatRecord { }; event: OutgoingIntegrationEvent; _createdAt: Date; - _updatedAt: Date; data?: { user?: any; room?: any; diff --git a/packages/core-typings/src/ILivechatBusinessHour.ts b/packages/core-typings/src/ILivechatBusinessHour.ts index 9991272a69f48..e2f705f784b31 100644 --- a/packages/core-typings/src/ILivechatBusinessHour.ts +++ b/packages/core-typings/src/ILivechatBusinessHour.ts @@ -1,4 +1,5 @@ import type { ILivechatDepartment } from './ILivechatDepartment'; +import type { IRocketChatRecord } from './IRocketChatRecord'; export enum LivechatBusinessHourTypes { DEFAULT = 'default', @@ -29,14 +30,12 @@ export interface IBusinessHourTimezone { utc: string; } -export interface ILivechatBusinessHour { - _id: string; +export interface ILivechatBusinessHour extends IRocketChatRecord { name: string; active: boolean; type: LivechatBusinessHourTypes; timezone: IBusinessHourTimezone; ts: Date; workHours: IBusinessHourWorkHour[]; - _updatedAt?: Date; departments?: ILivechatDepartment[]; } diff --git a/packages/core-typings/src/ILivechatDepartment.ts b/packages/core-typings/src/ILivechatDepartment.ts index 3910635960fc7..f8b1d9fa0d025 100644 --- a/packages/core-typings/src/ILivechatDepartment.ts +++ b/packages/core-typings/src/ILivechatDepartment.ts @@ -1,5 +1,6 @@ -export interface ILivechatDepartment { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface ILivechatDepartment extends IRocketChatRecord { name: string; enabled: boolean; description?: string; @@ -10,7 +11,6 @@ export interface ILivechatDepartment { chatClosingTags?: string[]; offlineMessageChannelName: string; numAgents: number; - _updatedAt?: Date; businessHourId?: string; fallbackForwardDepartment?: string; archived?: boolean; diff --git a/packages/core-typings/src/ILivechatDepartmentRecord.ts b/packages/core-typings/src/ILivechatDepartmentRecord.ts index 383007e69a947..940c10090de40 100644 --- a/packages/core-typings/src/ILivechatDepartmentRecord.ts +++ b/packages/core-typings/src/ILivechatDepartmentRecord.ts @@ -2,7 +2,6 @@ import type { IRocketChatRecord } from './IRocketChatRecord'; /** @deprecated */ export interface ILivechatDepartmentRecord extends IRocketChatRecord { - _id: string; name: string; enabled: boolean; description?: string; diff --git a/packages/core-typings/src/ILivechatTag.ts b/packages/core-typings/src/ILivechatTag.ts index e391f29812216..50802b8772937 100644 --- a/packages/core-typings/src/ILivechatTag.ts +++ b/packages/core-typings/src/ILivechatTag.ts @@ -1,5 +1,6 @@ -export interface ILivechatTag { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface ILivechatTag extends IRocketChatRecord { name: string; description?: string; numDepartments: number; diff --git a/packages/core-typings/src/ILivechatTagRecord.ts b/packages/core-typings/src/ILivechatTagRecord.ts index af03bb0cba5fd..32550f44cdb1b 100644 --- a/packages/core-typings/src/ILivechatTagRecord.ts +++ b/packages/core-typings/src/ILivechatTagRecord.ts @@ -1,7 +1,6 @@ import type { IRocketChatRecord } from './IRocketChatRecord'; export interface ILivechatTagRecord extends IRocketChatRecord { - _id: string; name: string; description: string; numDepartments: number; diff --git a/packages/core-typings/src/INotification.ts b/packages/core-typings/src/INotification.ts index 1310d97ae4826..c9da1a8ae8090 100644 --- a/packages/core-typings/src/INotification.ts +++ b/packages/core-typings/src/INotification.ts @@ -1,5 +1,6 @@ import type { ICalendarEvent } from './ICalendarEvent'; import type { IMessage } from './IMessage'; +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IRoom } from './IRoom'; import type { ISubscription } from './ISubscription'; @@ -37,8 +38,7 @@ export interface INotificationItemEmail { export type NotificationItem = INotificationItemPush | INotificationItemEmail; -export interface INotification { - _id: string; +export interface INotification extends IRocketChatRecord { uid: string; rid: string; mid: string; diff --git a/packages/core-typings/src/INps.ts b/packages/core-typings/src/INps.ts index 12b3a1a15d890..fb8d842fd310e 100644 --- a/packages/core-typings/src/INps.ts +++ b/packages/core-typings/src/INps.ts @@ -23,7 +23,6 @@ export enum INpsVoteStatus { } export interface INpsVote extends IRocketChatRecord { - _id: string; npsId: INps['_id']; ts: Date; identifier: string; // voter identifier diff --git a/packages/core-typings/src/IOAuthAccessToken.ts b/packages/core-typings/src/IOAuthAccessToken.ts index 2a6fb5fd34eee..e0cd154a218e9 100644 --- a/packages/core-typings/src/IOAuthAccessToken.ts +++ b/packages/core-typings/src/IOAuthAccessToken.ts @@ -1,5 +1,6 @@ -export interface IOAuthAccessToken { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IOAuthAccessToken extends IRocketChatRecord { accessToken: string; expires?: Date; clientId: string; diff --git a/packages/core-typings/src/IOAuthApps.ts b/packages/core-typings/src/IOAuthApps.ts index 435888a462901..8003170233aa7 100644 --- a/packages/core-typings/src/IOAuthApps.ts +++ b/packages/core-typings/src/IOAuthApps.ts @@ -1,5 +1,6 @@ -export interface IOAuthApps { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IOAuthApps extends IRocketChatRecord { name: string; active: boolean; clientId: string; @@ -10,6 +11,5 @@ export interface IOAuthApps { _id: string; username: string; }; - _updatedAt: Date; appId?: string; } diff --git a/packages/core-typings/src/IOAuthAuthCode.ts b/packages/core-typings/src/IOAuthAuthCode.ts index ccddd08038e82..7921c67801cf1 100644 --- a/packages/core-typings/src/IOAuthAuthCode.ts +++ b/packages/core-typings/src/IOAuthAuthCode.ts @@ -1,5 +1,6 @@ -export interface IOAuthAuthCode { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IOAuthAuthCode extends IRocketChatRecord { authCode: string; clientId: string; userId: string; diff --git a/packages/core-typings/src/IOAuthRefreshToken.ts b/packages/core-typings/src/IOAuthRefreshToken.ts index ae1febc511b0f..c229f1534722d 100644 --- a/packages/core-typings/src/IOAuthRefreshToken.ts +++ b/packages/core-typings/src/IOAuthRefreshToken.ts @@ -1,5 +1,6 @@ -export interface IOAuthRefreshToken { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IOAuthRefreshToken extends IRocketChatRecord { refreshToken: string; expires?: Date; clientId: string; diff --git a/packages/core-typings/src/IOEmbedCache.ts b/packages/core-typings/src/IOEmbedCache.ts index b99341bddf63c..12a158ebbd06a 100644 --- a/packages/core-typings/src/IOEmbedCache.ts +++ b/packages/core-typings/src/IOEmbedCache.ts @@ -1,6 +1,6 @@ -export interface IOEmbedCache { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; +export interface IOEmbedCache extends IRocketChatRecord { data: any; - updatedAt: Date; + updatedAt: Date; // TODO: this field name differs from `_updatedAt` on `IRocketChatRecord`, should we unify this? } diff --git a/packages/core-typings/src/IOmnichannelBusinessUnit.ts b/packages/core-typings/src/IOmnichannelBusinessUnit.ts index fff6495534eb2..a5c7258636c0a 100644 --- a/packages/core-typings/src/IOmnichannelBusinessUnit.ts +++ b/packages/core-typings/src/IOmnichannelBusinessUnit.ts @@ -1,7 +1,6 @@ import type { IRocketChatRecord } from './IRocketChatRecord'; export interface IOmnichannelBusinessUnit extends IRocketChatRecord { - _id: string; name: string; visibility: 'public' | 'private'; type: string; diff --git a/packages/core-typings/src/IPermission.ts b/packages/core-typings/src/IPermission.ts index b53ef0c12b332..9f597aa038d1d 100644 --- a/packages/core-typings/src/IPermission.ts +++ b/packages/core-typings/src/IPermission.ts @@ -1,6 +1,6 @@ -export interface IPermission { - _id: string; - _updatedAt: Date; +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IPermission extends IRocketChatRecord { roles: string[]; group?: string; groupPermissionId?: string; diff --git a/packages/core-typings/src/IReadReceipt.ts b/packages/core-typings/src/IReadReceipt.ts index 1b4941cf1d238..cff525e062335 100644 --- a/packages/core-typings/src/IReadReceipt.ts +++ b/packages/core-typings/src/IReadReceipt.ts @@ -1,8 +1,9 @@ import type { IMessage } from './IMessage/IMessage'; +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IRoom } from './IRoom'; import type { IUser } from './IUser'; -export interface IReadReceipt { +export interface IReadReceipt extends IRocketChatRecord { token?: string; messageId: IMessage['_id']; roomId: IRoom['_id']; @@ -12,7 +13,6 @@ export interface IReadReceipt { drid?: IMessage['drid']; tmid?: IMessage['tmid']; userId: IUser['_id']; - _id: string; } export interface IReadReceiptWithUser extends IReadReceipt { diff --git a/packages/core-typings/src/IRocketChatRecord.ts b/packages/core-typings/src/IRocketChatRecord.ts index 7cb9606b2268b..5da5321171164 100644 --- a/packages/core-typings/src/IRocketChatRecord.ts +++ b/packages/core-typings/src/IRocketChatRecord.ts @@ -1,9 +1,14 @@ import type { WithId } from 'mongodb'; +import * as z from 'zod'; -export interface IRocketChatRecord { - _id: string; - _updatedAt: Date; -} +import { TimestampSchema } from './utils'; + +export const IRocketChatRecordSchema = z.object({ + _id: z.string(), + _updatedAt: TimestampSchema, +}); + +export interface IRocketChatRecord extends z.infer {} export type RocketChatRecordDeleted = WithId & { _updatedAt: Date; diff --git a/packages/core-typings/src/IRole.ts b/packages/core-typings/src/IRole.ts index d0f15f3a9f236..3b48ce8d7a206 100644 --- a/packages/core-typings/src/IRole.ts +++ b/packages/core-typings/src/IRole.ts @@ -1,8 +1,9 @@ -export interface IRole { +import type { IRocketChatRecord } from './IRocketChatRecord'; + +export interface IRole extends IRocketChatRecord { description: string; mandatory2fa?: boolean; name: string; protected: boolean; scope: 'Users' | 'Subscriptions'; - _id: string; } diff --git a/packages/core-typings/src/IServerEvent.ts b/packages/core-typings/src/IServerEvent.ts index 4be4e0f74a3e3..cde15a8e01ab7 100644 --- a/packages/core-typings/src/IServerEvent.ts +++ b/packages/core-typings/src/IServerEvent.ts @@ -1,3 +1,4 @@ +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IUser } from './IUser'; import type { IServerEventAbacActionPerformed, @@ -14,8 +15,7 @@ export enum ServerEventType { LOGIN = 'login', } -export interface IServerEvent { - _id: string; +export interface IServerEvent extends IRocketChatRecord { t: ServerEventType | keyof IServerEvents; ts: Date; diff --git a/packages/core-typings/src/ISession.ts b/packages/core-typings/src/ISession.ts index 19dfe0432f2f7..f280b4fe817b0 100644 --- a/packages/core-typings/src/ISession.ts +++ b/packages/core-typings/src/ISession.ts @@ -1,3 +1,4 @@ +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IRole } from './IRole'; import type { IUser } from './IUser'; @@ -12,8 +13,7 @@ export interface ISessionDevice { version: string; } -export interface ISession { - _id: string; +export interface ISession extends IRocketChatRecord { type: 'session' | 'computed-session' | 'user_daily'; mostImportantRole: IRole['_id']; userId: string; @@ -25,7 +25,6 @@ export interface ISession { day: number; instanceId: string; sessionId: string; - _updatedAt: Date; createdAt: Date; host: string; ip: string; diff --git a/packages/core-typings/src/ISmarshHistory.ts b/packages/core-typings/src/ISmarshHistory.ts index 43ba0d8f91a8c..7e0d819d6fb9c 100644 --- a/packages/core-typings/src/ISmarshHistory.ts +++ b/packages/core-typings/src/ISmarshHistory.ts @@ -1,6 +1,6 @@ -export interface ISmarshHistory { - _id: string; +import type { IRocketChatRecord } from './IRocketChatRecord'; +export interface ISmarshHistory extends IRocketChatRecord { lastRan: Date; lastResult: string; } diff --git a/packages/core-typings/src/IStats.ts b/packages/core-typings/src/IStats.ts index e6fbf30ca15eb..18e85f252d9be 100644 --- a/packages/core-typings/src/IStats.ts +++ b/packages/core-typings/src/IStats.ts @@ -1,6 +1,7 @@ import type { CpuInfo } from 'os'; import type { IMatrixFederationStatistics } from './IMatrixFederationStatistics'; +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { DeviceSessionAggregationResult, OSSessionAggregationResult, UserSessionAggregationResult } from './ISession'; import type { ISettingStatisticsObject } from './ISetting'; import type { ITeamStats } from './ITeam'; @@ -17,8 +18,7 @@ interface IVoIPPeriodStats { callsDuration?: number; } -export interface IStats { - _id: string; +export interface IStats extends IRocketChatRecord { wizard: { organizationType?: string; industry?: string; diff --git a/packages/core-typings/src/IUpload.ts b/packages/core-typings/src/IUpload.ts index 660a498badb74..ab9653496c8e4 100644 --- a/packages/core-typings/src/IUpload.ts +++ b/packages/core-typings/src/IUpload.ts @@ -1,8 +1,8 @@ import type { EncryptedContent } from './IMessage'; +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IUser } from './IUser'; -export interface IUpload { - _id: string; +export interface IUpload extends IRocketChatRecord { typeGroup?: string; description?: string; type?: string; diff --git a/packages/core-typings/src/IUser.ts b/packages/core-typings/src/IUser.ts index a018ed386b1dc..fae8d6c4523da 100644 --- a/packages/core-typings/src/IUser.ts +++ b/packages/core-typings/src/IUser.ts @@ -190,7 +190,6 @@ export interface IUser extends IRocketChatRecord { oauth?: { authorizedClients: string[]; }; - _updatedAt: Date; e2e?: { private_key: string; public_key: string; diff --git a/packages/core-typings/src/MessageReads.ts b/packages/core-typings/src/MessageReads.ts index c95cec5c5d170..abd2b55361589 100644 --- a/packages/core-typings/src/MessageReads.ts +++ b/packages/core-typings/src/MessageReads.ts @@ -1,9 +1,10 @@ import type { IMessage } from './IMessage/IMessage'; +import type { IRocketChatRecord } from './IRocketChatRecord'; import type { IUser } from './IUser'; -export type MessageReads = { - _id: string; +// eslint-disable-next-line @typescript-eslint/naming-convention +export interface MessageReads extends IRocketChatRecord { tmid: IMessage['_id']; ls: Date; userId: IUser['_id']; -}; +} diff --git a/packages/core-typings/src/ee/IWorkspaceCredentials.ts b/packages/core-typings/src/ee/IWorkspaceCredentials.ts index 1fda00d0c8b3e..83a92e35747bf 100644 --- a/packages/core-typings/src/ee/IWorkspaceCredentials.ts +++ b/packages/core-typings/src/ee/IWorkspaceCredentials.ts @@ -1,7 +1,6 @@ import type { IRocketChatRecord } from '../IRocketChatRecord'; export interface IWorkspaceCredentials extends IRocketChatRecord { - _id: string; scope: string; expirationDate: Date; accessToken: string; diff --git a/packages/core-typings/src/federation/v1/FederationKey.ts b/packages/core-typings/src/federation/v1/FederationKey.ts index 665fc0c4894ae..59c2fe7875b42 100644 --- a/packages/core-typings/src/federation/v1/FederationKey.ts +++ b/packages/core-typings/src/federation/v1/FederationKey.ts @@ -1,5 +1,8 @@ -export type FederationKey = { +import type { IRocketChatRecord } from '../../IRocketChatRecord'; + +// eslint-disable-next-line @typescript-eslint/naming-convention +export interface FederationKey extends IRocketChatRecord { _id: string; type: 'private' | 'public'; key: string; -}; +} diff --git a/packages/core-typings/src/import/IImportRecord.ts b/packages/core-typings/src/import/IImportRecord.ts index 5f572e54dee0c..4886555720219 100644 --- a/packages/core-typings/src/import/IImportRecord.ts +++ b/packages/core-typings/src/import/IImportRecord.ts @@ -2,14 +2,14 @@ import type { IImportChannel } from './IImportChannel'; import type { IImportContact } from './IImportContact'; import type { IImportMessage } from './IImportMessage'; import type { IImportUser } from './IImportUser'; +import type { IRocketChatRecord } from '../IRocketChatRecord'; export type IImportRecordType = 'user' | 'channel' | 'message' | 'contact'; export type IImportData = IImportUser | IImportChannel | IImportMessage | IImportContact; -export interface IImportRecord { +export interface IImportRecord extends IRocketChatRecord { data: IImportData; dataType: IImportRecordType; - _id: string; options?: Record; errors?: Array<{ message: string; diff --git a/packages/core-typings/src/migrations/IControl.ts b/packages/core-typings/src/migrations/IControl.ts index 2d1a3902265ca..8820dc8ebe768 100644 --- a/packages/core-typings/src/migrations/IControl.ts +++ b/packages/core-typings/src/migrations/IControl.ts @@ -1,5 +1,6 @@ -export interface IControl { - _id: string; +import type { IRocketChatRecord } from '../IRocketChatRecord'; + +export interface IControl extends IRocketChatRecord { version: number; locked: boolean; hash?: string; diff --git a/packages/model-typings/src/models/ICredentialTokensModel.ts b/packages/model-typings/src/models/ICredentialTokensModel.ts index 9643a183dfcd0..600d2aac82502 100644 --- a/packages/model-typings/src/models/ICredentialTokensModel.ts +++ b/packages/model-typings/src/models/ICredentialTokensModel.ts @@ -3,6 +3,6 @@ import type { ICredentialToken } from '@rocket.chat/core-typings'; import type { IBaseModel } from './IBaseModel'; export interface ICredentialTokensModel extends IBaseModel { - create(_id: string, userInfo: ICredentialToken['userInfo']): Promise; + create(_id: string, userInfo: ICredentialToken['userInfo']): Promise; findOneNotExpiredById(_id: string): Promise; } diff --git a/packages/model-typings/src/models/ICustomSoundsModel.ts b/packages/model-typings/src/models/ICustomSoundsModel.ts index 1709f4efe4a98..b45f5f46095cf 100644 --- a/packages/model-typings/src/models/ICustomSoundsModel.ts +++ b/packages/model-typings/src/models/ICustomSoundsModel.ts @@ -1,11 +1,11 @@ import type { ICustomSound } from '@rocket.chat/core-typings'; -import type { FindCursor, FindOptions, InsertOneResult, UpdateResult, WithId } from 'mongodb'; +import type { FindCursor, FindOptions, InsertOneResult, WithId } from 'mongodb'; import type { IBaseModel } from './IBaseModel'; export interface ICustomSoundsModel extends IBaseModel { findByName(name: string, options?: FindOptions): FindCursor; findByNameExceptId(name: string, except: string, options?: FindOptions): FindCursor; - setName(_id: string, name: string): Promise; - create(data: Omit): Promise>>; + setName(_id: string, name: string): Promise; + create(data: Omit): Promise>>; } diff --git a/packages/model-typings/src/models/IEmailMessageHistoryModel.ts b/packages/model-typings/src/models/IEmailMessageHistoryModel.ts index 0b050f9a4340c..4c6dabe0230d0 100644 --- a/packages/model-typings/src/models/IEmailMessageHistoryModel.ts +++ b/packages/model-typings/src/models/IEmailMessageHistoryModel.ts @@ -1,8 +1,8 @@ import type { IEmailMessageHistory } from '@rocket.chat/core-typings'; import type { InsertOneResult, WithId } from 'mongodb'; -import type { IBaseModel } from './IBaseModel'; +import type { IBaseModel, InsertionModel } from './IBaseModel'; export interface IEmailMessageHistoryModel extends IBaseModel { - create({ _id, email }: IEmailMessageHistory): Promise>>; + create({ _id, email }: InsertionModel): Promise>>; } diff --git a/packages/model-typings/src/models/ILivechatBusinessHoursModel.ts b/packages/model-typings/src/models/ILivechatBusinessHoursModel.ts index e13ebb9b08ae0..99599d2c3dba5 100644 --- a/packages/model-typings/src/models/ILivechatBusinessHoursModel.ts +++ b/packages/model-typings/src/models/ILivechatBusinessHoursModel.ts @@ -23,7 +23,7 @@ export interface ILivechatBusinessHoursModel extends IBaseModel(options?: any): Promise; findActiveAndOpenBusinessHoursByDay(day: string, options?: FindOptions): Promise; findDefaultActiveAndOpenBusinessHoursByDay(day: string, options?: any): Promise; - insertOne(data: Omit): Promise; + insertOne(data: Omit): Promise; findHoursToScheduleJobs(): Promise; findActiveBusinessHoursToOpen( diff --git a/packages/model-typings/src/models/ILivechatTagModel.ts b/packages/model-typings/src/models/ILivechatTagModel.ts index f32e4f3fd79b8..d9afde775745b 100644 --- a/packages/model-typings/src/models/ILivechatTagModel.ts +++ b/packages/model-typings/src/models/ILivechatTagModel.ts @@ -9,6 +9,6 @@ export interface ILivechatTagModel extends IBaseModel { _id: string | undefined, { name, description }: { name: string; description?: string }, departments?: string[], - ): Promise; + ): Promise>; removeById(_id: string): Promise; } diff --git a/packages/models/src/models/CredentialTokens.ts b/packages/models/src/models/CredentialTokens.ts index 5623aec70d2aa..cdeb1d0f59c7e 100644 --- a/packages/models/src/models/CredentialTokens.ts +++ b/packages/models/src/models/CredentialTokens.ts @@ -1,5 +1,5 @@ import type { ICredentialToken, RocketChatRecordDeleted } from '@rocket.chat/core-typings'; -import type { ICredentialTokensModel } from '@rocket.chat/model-typings'; +import type { ICredentialTokensModel, InsertionModel } from '@rocket.chat/model-typings'; import type { Collection, Db, IndexDescription } from 'mongodb'; import { BaseRaw } from './BaseRaw'; @@ -13,16 +13,15 @@ export class CredentialTokensRaw extends BaseRaw implements IC return [{ key: { expireAt: 1 }, sparse: true, expireAfterSeconds: 0 }]; } - async create(_id: string, userInfo: ICredentialToken['userInfo']): Promise { + async create(_id: string, userInfo: ICredentialToken['userInfo']): Promise { const validForMilliseconds = 60000; // Valid for 60 seconds - const token = { + const token: InsertionModel = { _id, userInfo, expireAt: new Date(Date.now() + validForMilliseconds), }; await this.insertOne(token); - return token; } findOneNotExpiredById(_id: string): Promise { diff --git a/packages/models/src/models/CustomSounds.ts b/packages/models/src/models/CustomSounds.ts index 07c5b9c594a13..fe03437cee603 100644 --- a/packages/models/src/models/CustomSounds.ts +++ b/packages/models/src/models/CustomSounds.ts @@ -1,6 +1,6 @@ import type { ICustomSound, RocketChatRecordDeleted } from '@rocket.chat/core-typings'; import type { ICustomSoundsModel } from '@rocket.chat/model-typings'; -import type { Collection, FindCursor, Db, FindOptions, IndexDescription, InsertOneResult, UpdateResult, WithId } from 'mongodb'; +import type { Collection, FindCursor, Db, FindOptions, IndexDescription, InsertOneResult, WithId } from 'mongodb'; import { BaseRaw } from './BaseRaw'; @@ -32,18 +32,18 @@ export class CustomSoundsRaw extends BaseRaw implements ICustomSou } // update - setName(_id: string, name: string): Promise { + setName(_id: string, name: string): Promise { const update = { $set: { name, }, }; - return this.updateOne({ _id }, update); + return this.findOneAndUpdate({ _id }, update, { returnDocument: 'after' }); } // INSERT - create(data: Omit): Promise>> { + create(data: Omit): Promise>> { return this.insertOne(data); } } diff --git a/packages/models/src/models/EmailMessageHistory.ts b/packages/models/src/models/EmailMessageHistory.ts index ff874971e92ff..8130807f19a55 100644 --- a/packages/models/src/models/EmailMessageHistory.ts +++ b/packages/models/src/models/EmailMessageHistory.ts @@ -1,5 +1,5 @@ import type { IEmailMessageHistory, RocketChatRecordDeleted } from '@rocket.chat/core-typings'; -import type { IEmailMessageHistoryModel } from '@rocket.chat/model-typings'; +import type { IEmailMessageHistoryModel, InsertionModel } from '@rocket.chat/model-typings'; import type { Collection, Db, InsertOneResult, WithId, IndexDescription } from 'mongodb'; import { BaseRaw } from './BaseRaw'; @@ -13,7 +13,7 @@ export class EmailMessageHistoryRaw extends BaseRaw implem return [{ key: { createdAt: 1 }, expireAfterSeconds: 60 * 60 * 24 }]; } - async create({ _id, email }: IEmailMessageHistory): Promise>> { + async create({ _id, email }: InsertionModel): Promise>> { return this.insertOne({ _id, email, diff --git a/packages/models/src/models/LivechatBusinessHours.ts b/packages/models/src/models/LivechatBusinessHours.ts index 39d076cbd1951..7cd53eab3f385 100644 --- a/packages/models/src/models/LivechatBusinessHours.ts +++ b/packages/models/src/models/LivechatBusinessHours.ts @@ -72,7 +72,7 @@ export class LivechatBusinessHoursRaw extends BaseRaw imp ).toArray(); } - override async insertOne(data: Omit): Promise { + override async insertOne(data: Omit): Promise { return super.insertOne({ ...data, ts: new Date(), diff --git a/packages/models/src/models/LivechatRooms.ts b/packages/models/src/models/LivechatRooms.ts index d388e7a39fd6e..171d80cf8b4cd 100644 --- a/packages/models/src/models/LivechatRooms.ts +++ b/packages/models/src/models/LivechatRooms.ts @@ -34,9 +34,6 @@ import type { Updater } from '../updater'; import { BaseRaw } from './BaseRaw'; import { readSecondaryPreferred } from '../readSecondaryPreferred'; -/** - * @extends BaseRaw - */ export class LivechatRoomsRaw extends BaseRaw implements ILivechatRoomsModel { constructor(db: Db, trash?: Collection>) { super(db, 'room', trash); diff --git a/packages/models/src/models/OEmbedCache.ts b/packages/models/src/models/OEmbedCache.ts index 77ed9c64f6708..6d4193b4953a9 100644 --- a/packages/models/src/models/OEmbedCache.ts +++ b/packages/models/src/models/OEmbedCache.ts @@ -18,6 +18,7 @@ export class OEmbedCacheRaw extends BaseRaw implements IOEmbedCach _id, data, updatedAt: new Date(), + _updatedAt: new Date(), // TODO: insertOne inserts the field `_updatedAt` synchronously but it's not guaranteed }; record._id = (await this.insertOne(record)).insertedId; return record; diff --git a/packages/models/src/models/Roles.ts b/packages/models/src/models/Roles.ts index f636d9044e13a..6ccc80642ec00 100644 --- a/packages/models/src/models/Roles.ts +++ b/packages/models/src/models/Roles.ts @@ -250,6 +250,7 @@ export class RolesRaw extends BaseRaw implements IRolesModel { return { _id: res.insertedId, + _updatedAt: new Date(), // TODO: this should be set by the BaseRaw, but we need to set it here to return a complete IRole object ...role, }; } diff --git a/packages/rest-typings/src/v1/omnichannel.ts b/packages/rest-typings/src/v1/omnichannel.ts index 801396f3bc31f..c2d92fac9be8a 100644 --- a/packages/rest-typings/src/v1/omnichannel.ts +++ b/packages/rest-typings/src/v1/omnichannel.ts @@ -617,7 +617,7 @@ const POSTLivechatTagsSaveSuccessResponseSchema = { additionalProperties: false, }; -export const POSTLivechatTagsSaveSuccessResponse = ajv.compile(POSTLivechatTagsSaveSuccessResponseSchema); +export const POSTLivechatTagsSaveSuccessResponse = ajv.compile>(POSTLivechatTagsSaveSuccessResponseSchema); type POSTLivechatTagsDeleteParams = { id: string; diff --git a/packages/ui-contexts/src/CustomSoundContext.ts b/packages/ui-contexts/src/CustomSoundContext.ts index a8c7a64f844e0..36e9617367ea3 100644 --- a/packages/ui-contexts/src/CustomSoundContext.ts +++ b/packages/ui-contexts/src/CustomSoundContext.ts @@ -36,7 +36,7 @@ export type CustomSoundContextValue = { stopNewMessage: () => void; playNewMessageCustom: (soundId: ICustomSound['_id']) => void; }; - list: ICustomSound[]; + list: Omit[]; }; export const CustomSoundContext = createContext({