diff --git a/lib/permissions/minimally-encoded-thread-permissions-test-data.js b/lib/permissions/minimally-encoded-thread-permissions-test-data.js --- a/lib/permissions/minimally-encoded-thread-permissions-test-data.js +++ b/lib/permissions/minimally-encoded-thread-permissions-test-data.js @@ -1,6 +1,6 @@ // @flow -import type { MinimallyEncodedRawThreadInfo } from './minimally-encoded-thread-permissions.js'; +import type { MinimallyEncodedRawThreadInfo } from '../types/minimally-encoded-thread-permissions-types.js'; import { threadTypes } from '../types/thread-types-enum.js'; import type { RawThreadInfo } from '../types/thread-types.js'; 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 @@ -1,31 +1,16 @@ // @flow import invariant from 'invariant'; -import _mapValues from 'lodash/fp/mapValues.js'; -import t, { type TInterface } from 'tcomb'; import { parseThreadPermissionString } from './prefixes.js'; +import { tHexEncodedRolePermission } from '../types/minimally-encoded-thread-permissions-types.js'; import type { ThreadPermission, ThreadPermissionInfo, ThreadPermissionsInfo, ThreadRolePermissionsBlob, } 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 { tBool, tID, tRegex, tShape } from '../utils/validation-utils.js'; -import type { TRegex } from '../utils/validation-utils.js'; // `baseRolePermissionEncoding` maps permission names to indices. // These indices represent the 6-bit basePermission part of the 10-bit role @@ -95,7 +80,7 @@ permissionsBitmaskHex: string, ): ThreadPermissionsInfo => { invariant( - tHexEncodedPermissionsBitmask.is(permissionsBitmaskHex), + tHexEncodedRolePermission.is(permissionsBitmaskHex), 'permissionsBitmaskHex must be valid hex string.', ); @@ -220,150 +205,6 @@ ]), ); -export type MinimallyEncodedRoleInfo = $ReadOnly<{ - ...RoleInfo, - +minimallyEncoded: true, - +permissions: $ReadOnlyArray, -}>; - -const tHexEncodedRolePermission: TRegex = tRegex(/^[0-9a-fA-F]{3,}$/); -const minimallyEncodedRoleInfoValidator: TInterface = - tShape({ - ...roleInfoValidator.meta.props, - minimallyEncoded: tBool(true), - permissions: t.list(tHexEncodedRolePermission), - }); - -const minimallyEncodeRoleInfo = ( - roleInfo: RoleInfo, -): MinimallyEncodedRoleInfo => ({ - ...roleInfo, - minimallyEncoded: true, - permissions: threadRolePermissionsBlobToBitmaskArray(roleInfo.permissions), -}); - -const decodeMinimallyEncodedRoleInfo = ( - minimallyEncodedRoleInfo: MinimallyEncodedRoleInfo, -): RoleInfo => { - const { minimallyEncoded, ...rest } = minimallyEncodedRoleInfo; - return { - ...rest, - permissions: decodeThreadRolePermissionsBitmaskArray( - minimallyEncodedRoleInfo.permissions, - ), - }; -}; - -export type MinimallyEncodedThreadCurrentUserInfo = $ReadOnly<{ - ...ThreadCurrentUserInfo, - +minimallyEncoded: true, - +permissions: string, -}>; - -const tHexEncodedPermissionsBitmask: TRegex = tRegex(/^[0-9a-fA-F]+$/); -const minimallyEncodedThreadCurrentUserInfoValidator: TInterface = - tShape({ - ...threadCurrentUserInfoValidator.meta.props, - minimallyEncoded: tBool(true), - permissions: tHexEncodedPermissionsBitmask, - }); - -const minimallyEncodeThreadCurrentUserInfo = ( - threadCurrentUserInfo: ThreadCurrentUserInfo, -): MinimallyEncodedThreadCurrentUserInfo => ({ - ...threadCurrentUserInfo, - minimallyEncoded: true, - permissions: permissionsToBitmaskHex(threadCurrentUserInfo.permissions), -}); - -const decodeMinimallyEncodedThreadCurrentUserInfo = ( - minimallyEncodedThreadCurrentUserInfo: MinimallyEncodedThreadCurrentUserInfo, -): ThreadCurrentUserInfo => { - const { minimallyEncoded, ...rest } = minimallyEncodedThreadCurrentUserInfo; - return { - ...rest, - permissions: threadPermissionsFromBitmaskHex( - minimallyEncodedThreadCurrentUserInfo.permissions, - ), - }; -}; - -export type MinimallyEncodedMemberInfo = $ReadOnly<{ - ...MemberInfo, - +minimallyEncoded: true, - +permissions: string, -}>; - -const minimallyEncodedMemberInfoValidator: TInterface = - tShape({ - ...memberInfoValidator.meta.props, - minimallyEncoded: tBool(true), - permissions: tHexEncodedPermissionsBitmask, - }); - -const minimallyEncodeMemberInfo = ( - memberInfo: MemberInfo, -): MinimallyEncodedMemberInfo => ({ - ...memberInfo, - minimallyEncoded: true, - permissions: permissionsToBitmaskHex(memberInfo.permissions), -}); - -const decodeMinimallyEncodedMemberInfo = ( - minimallyEncodedMemberInfo: MinimallyEncodedMemberInfo, -): MemberInfo => { - const { minimallyEncoded, ...rest } = minimallyEncodedMemberInfo; - return { - ...rest, - permissions: threadPermissionsFromBitmaskHex( - minimallyEncodedMemberInfo.permissions, - ), - }; -}; - -export type MinimallyEncodedRawThreadInfo = $ReadOnly<{ - ...RawThreadInfo, - +minimallyEncoded: true, - +members: $ReadOnlyArray, - +roles: { +[id: string]: MinimallyEncodedRoleInfo }, - +currentUser: MinimallyEncodedThreadCurrentUserInfo, -}>; - -const minimallyEncodedRawThreadInfoValidator: TInterface = - tShape({ - ...rawThreadInfoValidator.meta.props, - minimallyEncoded: tBool(true), - members: t.list(minimallyEncodedMemberInfoValidator), - roles: t.dict(tID, minimallyEncodedRoleInfoValidator), - currentUser: minimallyEncodedThreadCurrentUserInfoValidator, - }); - -const minimallyEncodeRawThreadInfo = ( - rawThreadInfo: RawThreadInfo, -): MinimallyEncodedRawThreadInfo => { - const { members, roles, currentUser, ...rest } = rawThreadInfo; - return { - ...rest, - minimallyEncoded: true, - members: members.map(minimallyEncodeMemberInfo), - roles: _mapValues(minimallyEncodeRoleInfo)(roles), - currentUser: minimallyEncodeThreadCurrentUserInfo(currentUser), - }; -}; - -const decodeMinimallyEncodedRawThreadInfo = ( - minimallyEncodedRawThreadInfo: MinimallyEncodedRawThreadInfo, -): RawThreadInfo => { - const { minimallyEncoded, members, roles, currentUser, ...rest } = - minimallyEncodedRawThreadInfo; - return { - ...rest, - members: members.map(decodeMinimallyEncodedMemberInfo), - roles: _mapValues(decodeMinimallyEncodedRoleInfo)(roles), - currentUser: decodeMinimallyEncodedThreadCurrentUserInfo(currentUser), - }; -}; - export { permissionsToBitmaskHex, threadPermissionsFromBitmaskHex, @@ -372,10 +213,4 @@ decodeRolePermissionBitmask, threadRolePermissionsBlobToBitmaskArray, decodeThreadRolePermissionsBitmaskArray, - minimallyEncodedRoleInfoValidator, - minimallyEncodedThreadCurrentUserInfoValidator, - minimallyEncodedMemberInfoValidator, - minimallyEncodedRawThreadInfoValidator, - minimallyEncodeRawThreadInfo, - decodeMinimallyEncodedRawThreadInfo, }; 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 @@ -6,20 +6,22 @@ expectedDecodedExampleRawThreadInfoA, } from './minimally-encoded-thread-permissions-test-data.js'; import { - decodeMinimallyEncodedRawThreadInfo, decodeRolePermissionBitmask, decodeThreadRolePermissionsBitmaskArray, hasPermission, - minimallyEncodedMemberInfoValidator, - minimallyEncodedRawThreadInfoValidator, - minimallyEncodedRoleInfoValidator, - minimallyEncodedThreadCurrentUserInfoValidator, - minimallyEncodeRawThreadInfo, permissionsToBitmaskHex, rolePermissionToBitmaskHex, threadPermissionsFromBitmaskHex, threadRolePermissionsBlobToBitmaskArray, } from './minimally-encoded-thread-permissions.js'; +import { + minimallyEncodedMemberInfoValidator, + minimallyEncodedThreadCurrentUserInfoValidator, + minimallyEncodedRawThreadInfoValidator, + minimallyEncodedRoleInfoValidator, + minimallyEncodeRawThreadInfo, + decodeMinimallyEncodedRawThreadInfo, +} from '../types/minimally-encoded-thread-permissions-types.js'; import type { ThreadRolePermissionsBlob } from '../types/thread-permission-types.js'; const permissions = { diff --git a/lib/types/minimally-encoded-thread-permissions-types.js b/lib/types/minimally-encoded-thread-permissions-types.js new file mode 100644 --- /dev/null +++ b/lib/types/minimally-encoded-thread-permissions-types.js @@ -0,0 +1,201 @@ +// @flow + +import _mapValues from 'lodash/fp/mapValues.js'; +import type { TInterface } from 'tcomb'; +import t from 'tcomb'; + +import type { + MemberInfo, + RawThreadInfo, + RoleInfo, + ThreadCurrentUserInfo, +} from './thread-types.js'; +import { + memberInfoValidator, + rawThreadInfoValidator, + roleInfoValidator, + threadCurrentUserInfoValidator, +} from './thread-types.js'; +import { + decodeThreadRolePermissionsBitmaskArray, + permissionsToBitmaskHex, + threadPermissionsFromBitmaskHex, + threadRolePermissionsBlobToBitmaskArray, +} from '../permissions/minimally-encoded-thread-permissions.js'; +import type { TRegex } from '../utils/validation-utils.js'; +import { tBool, tID, tRegex, tShape } from '../utils/validation-utils.js'; + +// ------------------ MinimallyEncodedRoleInfo START -------------------------- + +export type MinimallyEncodedRoleInfo = $ReadOnly<{ + ...RoleInfo, + +minimallyEncoded: true, + +permissions: $ReadOnlyArray, +}>; + +const tHexEncodedRolePermission: TRegex = tRegex(/^[0-9a-fA-F]{3,}$/); +const minimallyEncodedRoleInfoValidator: TInterface = + tShape({ + ...roleInfoValidator.meta.props, + minimallyEncoded: tBool(true), + permissions: t.list(tHexEncodedRolePermission), + }); + +const minimallyEncodeRoleInfo = ( + roleInfo: RoleInfo, +): MinimallyEncodedRoleInfo => ({ + ...roleInfo, + minimallyEncoded: true, + permissions: threadRolePermissionsBlobToBitmaskArray(roleInfo.permissions), +}); + +const decodeMinimallyEncodedRoleInfo = ( + minimallyEncodedRoleInfo: MinimallyEncodedRoleInfo, +): RoleInfo => { + const { minimallyEncoded, ...rest } = minimallyEncodedRoleInfo; + return { + ...rest, + permissions: decodeThreadRolePermissionsBitmaskArray( + minimallyEncodedRoleInfo.permissions, + ), + }; +}; + +// ------------------ MinimallyEncodedRoleInfo END ---------------------------- + +// ------------------ MinimallyEncodedThreadCurrentUserInfo START ------------- + +export type MinimallyEncodedThreadCurrentUserInfo = $ReadOnly<{ + ...ThreadCurrentUserInfo, + +minimallyEncoded: true, + +permissions: string, +}>; + +const tHexEncodedPermissionsBitmask: TRegex = tRegex(/^[0-9a-fA-F]+$/); +const minimallyEncodedThreadCurrentUserInfoValidator: TInterface = + tShape({ + ...threadCurrentUserInfoValidator.meta.props, + minimallyEncoded: tBool(true), + permissions: tHexEncodedPermissionsBitmask, + }); + +const minimallyEncodeThreadCurrentUserInfo = ( + threadCurrentUserInfo: ThreadCurrentUserInfo, +): MinimallyEncodedThreadCurrentUserInfo => ({ + ...threadCurrentUserInfo, + minimallyEncoded: true, + permissions: permissionsToBitmaskHex(threadCurrentUserInfo.permissions), +}); + +const decodeMinimallyEncodedThreadCurrentUserInfo = ( + minimallyEncodedThreadCurrentUserInfo: MinimallyEncodedThreadCurrentUserInfo, +): ThreadCurrentUserInfo => { + const { minimallyEncoded, ...rest } = minimallyEncodedThreadCurrentUserInfo; + return { + ...rest, + permissions: threadPermissionsFromBitmaskHex( + minimallyEncodedThreadCurrentUserInfo.permissions, + ), + }; +}; + +// ------------------ MinimallyEncodedThreadCurrentUserInfo END --------------- + +// ------------------ MinimallyEncodedMemberInfo START ------------------------ + +export type MinimallyEncodedMemberInfo = $ReadOnly<{ + ...MemberInfo, + +minimallyEncoded: true, + +permissions: string, +}>; + +const minimallyEncodedMemberInfoValidator: TInterface = + tShape({ + ...memberInfoValidator.meta.props, + minimallyEncoded: tBool(true), + permissions: tHexEncodedPermissionsBitmask, + }); + +const minimallyEncodeMemberInfo = ( + memberInfo: MemberInfo, +): MinimallyEncodedMemberInfo => ({ + ...memberInfo, + minimallyEncoded: true, + permissions: permissionsToBitmaskHex(memberInfo.permissions), +}); + +const decodeMinimallyEncodedMemberInfo = ( + minimallyEncodedMemberInfo: MinimallyEncodedMemberInfo, +): MemberInfo => { + const { minimallyEncoded, ...rest } = minimallyEncodedMemberInfo; + return { + ...rest, + permissions: threadPermissionsFromBitmaskHex( + minimallyEncodedMemberInfo.permissions, + ), + }; +}; + +// ------------------ MinimallyEncodedMemberInfo END -------------------------- + +// ------------------ MinimallyEncodedRawThreadInfo START --------------------- + +export type MinimallyEncodedRawThreadInfo = $ReadOnly<{ + ...RawThreadInfo, + +minimallyEncoded: true, + +members: $ReadOnlyArray, + +roles: { +[id: string]: MinimallyEncodedRoleInfo }, + +currentUser: MinimallyEncodedThreadCurrentUserInfo, +}>; + +const minimallyEncodedRawThreadInfoValidator: TInterface = + tShape({ + ...rawThreadInfoValidator.meta.props, + minimallyEncoded: tBool(true), + members: t.list(minimallyEncodedMemberInfoValidator), + roles: t.dict(tID, minimallyEncodedRoleInfoValidator), + currentUser: minimallyEncodedThreadCurrentUserInfoValidator, + }); + +const minimallyEncodeRawThreadInfo = ( + rawThreadInfo: RawThreadInfo, +): MinimallyEncodedRawThreadInfo => { + const { members, roles, currentUser, ...rest } = rawThreadInfo; + return { + ...rest, + minimallyEncoded: true, + members: members.map(minimallyEncodeMemberInfo), + roles: _mapValues(minimallyEncodeRoleInfo)(roles), + currentUser: minimallyEncodeThreadCurrentUserInfo(currentUser), + }; +}; + +const decodeMinimallyEncodedRawThreadInfo = ( + minimallyEncodedRawThreadInfo: MinimallyEncodedRawThreadInfo, +): RawThreadInfo => { + const { minimallyEncoded, members, roles, currentUser, ...rest } = + minimallyEncodedRawThreadInfo; + return { + ...rest, + members: members.map(decodeMinimallyEncodedMemberInfo), + roles: _mapValues(decodeMinimallyEncodedRoleInfo)(roles), + currentUser: decodeMinimallyEncodedThreadCurrentUserInfo(currentUser), + }; +}; + +export { + tHexEncodedRolePermission, + minimallyEncodedRoleInfoValidator, + minimallyEncodeRoleInfo, + decodeMinimallyEncodedRoleInfo, + tHexEncodedPermissionsBitmask, + minimallyEncodedThreadCurrentUserInfoValidator, + minimallyEncodeThreadCurrentUserInfo, + decodeMinimallyEncodedThreadCurrentUserInfo, + minimallyEncodedMemberInfoValidator, + minimallyEncodeMemberInfo, + decodeMinimallyEncodedMemberInfo, + minimallyEncodedRawThreadInfoValidator, + minimallyEncodeRawThreadInfo, + decodeMinimallyEncodedRawThreadInfo, +};