diff --git a/lib/permissions/minimally-encoded-thread-permissions.js b/lib/permissions/minimally-encoded-thread-permissions.js --- a/lib/permissions/minimally-encoded-thread-permissions.js +++ b/lib/permissions/minimally-encoded-thread-permissions.js @@ -11,16 +11,18 @@ } from '../types/thread-permission-types.js'; import type { MemberInfo, + RawThreadInfo, RoleInfo, ThreadCurrentUserInfo, } from '../types/thread-types.js'; import { memberInfoValidator, + rawThreadInfoValidator, roleInfoValidator, threadCurrentUserInfoValidator, } from '../types/thread-types.js'; import { entries, invertObjectToMap } from '../utils/objects.js'; -import { tRegex, tShape } from '../utils/validation-utils.js'; +import { tID, tRegex, tShape } from '../utils/validation-utils.js'; import type { TRegex } from '../utils/validation-utils.js'; // `baseRolePermissionEncoding` maps permission names to indices. @@ -227,6 +229,21 @@ permissions: tHexEncodedPermissionsBitmask, }); +export type MinimallyEncodedRawThreadInfo = { + ...RawThreadInfo, + +members: $ReadOnlyArray, + +roles: { +[id: string]: MinimallyEncodedRoleInfo }, + +currentUser: MinimallyEncodedThreadCurrentUserInfo, +}; + +const minimallyEncodedRawThreadInfoValidator: TInterface = + tShape({ + ...rawThreadInfoValidator.meta.props, + members: t.list(minimallyEncodedMemberInfoValidator), + roles: t.dict(tID, minimallyEncodedRoleInfoValidator), + currentUser: minimallyEncodedThreadCurrentUserInfoValidator, + }); + export { permissionsToBitmaskHex, hasPermission, @@ -237,4 +254,5 @@ minimallyEncodedRoleInfoValidator, minimallyEncodedThreadCurrentUserInfoValidator, minimallyEncodedMemberInfoValidator, + minimallyEncodedRawThreadInfoValidator, }; diff --git a/lib/permissions/minimally-encoded-thread-permissions.test.js b/lib/permissions/minimally-encoded-thread-permissions.test.js --- a/lib/permissions/minimally-encoded-thread-permissions.test.js +++ b/lib/permissions/minimally-encoded-thread-permissions.test.js @@ -5,6 +5,7 @@ decodeThreadRolePermissionsBitmaskArray, hasPermission, minimallyEncodedMemberInfoValidator, + minimallyEncodedRawThreadInfoValidator, minimallyEncodedRoleInfoValidator, minimallyEncodedThreadCurrentUserInfoValidator, permissionsToBitmaskHex, @@ -12,6 +13,7 @@ threadRolePermissionsBlobToBitmaskArray, } from './minimally-encoded-thread-permissions.js'; import type { ThreadRolePermissionsBlob } from '../types/thread-permission-types.js'; +import { threadTypes } from '../types/thread-types-enum.js'; describe('minimallyEncodedThreadPermissions', () => { const permissions = { @@ -362,3 +364,70 @@ ).toBe(false); }); }); + +describe('minimallyEncodedRawThreadInfoValidator', () => { + const minimalRawThreadInfo = { + id: '85171', + type: threadTypes.PERSONAL, + name: '', + description: '', + color: '6d49ab', + creationTime: 1675887298557, + parentThreadID: '1', + members: [ + { + id: '256', + role: null, + permissions: '87fff', + isSender: false, + }, + { + id: '83853', + role: '85172', + permissions: '3027f', + isSender: true, + }, + ], + roles: { + '85172': { + id: '85172', + name: 'Members', + permissions: [ + '000', + '010', + '020', + '100', + '110', + '030', + '040', + '060', + '050', + '090', + '005', + '015', + '0a9', + ], + isDefault: true, + }, + }, + currentUser: { + role: '85172', + permissions: '3027f', + subscription: { + home: true, + pushNotifs: true, + }, + unread: false, + }, + repliesCount: 0, + containingThreadID: '1', + community: '1', + pinnedCount: 0, + }; + + it('should validate correctly formed MinimallyEncodedRawThreadInfo', () => { + expect( + minimallyEncodedRawThreadInfoValidator.is(minimalRawThreadInfo), + ).toBe(true); + }); +});