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 @@ -9,8 +9,13 @@ ThreadPermissionsInfo, ThreadRolePermissionsBlob, } from '../types/thread-permission-types.js'; -import type { RoleInfo, ThreadCurrentUserInfo } from '../types/thread-types.js'; +import type { + MemberInfo, + RoleInfo, + ThreadCurrentUserInfo, +} from '../types/thread-types.js'; import { + memberInfoValidator, roleInfoValidator, threadCurrentUserInfoValidator, } from '../types/thread-types.js'; @@ -211,6 +216,17 @@ permissions: tHexEncodedPermissionsBitmask, }); +export type MinimallyEncodedMemberInfo = { + ...MemberInfo, + +permissions: string, +}; + +const minimallyEncodedMemberInfoValidator: TInterface = + tShape({ + ...memberInfoValidator.meta.props, + permissions: tHexEncodedPermissionsBitmask, + }); + export { permissionsToBitmaskHex, hasPermission, @@ -220,4 +236,5 @@ decodeThreadRolePermissionsBitmaskArray, minimallyEncodedRoleInfoValidator, minimallyEncodedThreadCurrentUserInfoValidator, + minimallyEncodedMemberInfoValidator, }; 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 @@ -4,6 +4,7 @@ decodeRolePermissionBitmask, decodeThreadRolePermissionsBitmaskArray, hasPermission, + minimallyEncodedMemberInfoValidator, minimallyEncodedRoleInfoValidator, minimallyEncodedThreadCurrentUserInfoValidator, permissionsToBitmaskHex, @@ -323,3 +324,49 @@ ).toBe(false); }); }); + +describe('minimallyEncodedMemberInfoValidator', () => { + it('should validate correctly formed MinimallyEncodedMemberInfo', () => { + expect( + minimallyEncodedMemberInfoValidator.is({ + id: 'memberID', + permissions: 'ABCDEF', + isSender: true, + }), + ).toBe(true); + + expect( + minimallyEncodedMemberInfoValidator.is({ + id: 'memberID', + permissions: '01b', + isSender: false, + }), + ).toBe(true); + }); + + it('should NOT validate malformed MinimallyEncodedMemberInfo', () => { + expect( + minimallyEncodedMemberInfoValidator.is({ + id: 'memberID', + permissions: 'INVALID', + isSender: false, + }), + ).toBe(false); + + expect( + minimallyEncodedMemberInfoValidator.is({ + id: 'memberID', + permissions: 100, + isSender: false, + }), + ).toBe(false); + + expect( + minimallyEncodedMemberInfoValidator.is({ + id: 'memberID', + permissions: 'ABCDEFABCDEFABCDE', + isSender: false, + }), + ).toBe(false); + }); +}); diff --git a/lib/types/thread-types.js b/lib/types/thread-types.js --- a/lib/types/thread-types.js +++ b/lib/types/thread-types.js @@ -41,7 +41,7 @@ +permissions: ThreadPermissionsInfo, +isSender: boolean, }; -const memberInfoValidator = tShape({ +export const memberInfoValidator: TInterface = tShape({ id: t.String, role: t.maybe(tID), permissions: threadPermissionsInfoValidator,