@fabriktor/fx 0.0.146 → 0.0.147

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ import type { EmploymentActor } from "../contacts/scope.js";
3
3
  export type ChatFormRecipient = Pick<User, "id" | "account_identity">;
4
4
  export type ChatFormPolicy = {
5
5
  readonly sender_modes: readonly User["active_mode"][];
6
- readonly recipient_identities: readonly User["account_identity"][];
6
+ readonly recipient_modes: readonly User["active_mode"][];
7
7
  readonly allow_group: boolean;
8
8
  };
9
9
  export declare function canSendChatForm(policy: ChatFormPolicy, actor: EmploymentActor, recipients: readonly ChatFormRecipient[]): boolean;
@@ -1,7 +1,8 @@
1
1
  import { normalizeIDs, resolvedID } from "../core/id.js";
2
- import { isFabriktorUser } from "../users/users.js";
2
+ import { isFabriktorUser, userSupportsMode } from "../users/users.js";
3
3
  // Recipients are all other members of the conversation, resolved before use.
4
- // Recipient eligibility uses account identity, never their transient active mode.
4
+ // Sender modes apply now; recipient modes describe what their identity supports.
5
+ // Do not depend on the recipient's current mode, which Public() omits.
5
6
  export function canSendChatForm(policy, actor, recipients) {
6
7
  return (!!resolvedID(actor.owner_id) &&
7
8
  policy.sender_modes.includes(actor.active_mode) &&
@@ -11,5 +12,5 @@ export function canSendChatForm(policy, actor, recipients) {
11
12
  recipients.length &&
12
13
  recipients.every((recipient) => recipient.id !== actor.owner_id &&
13
14
  isFabriktorUser(recipient) &&
14
- policy.recipient_identities.includes(recipient.account_identity)));
15
+ policy.recipient_modes.some((mode) => userSupportsMode(recipient, mode))));
15
16
  }
@@ -7,7 +7,7 @@ import { type RoutesActor } from "./workspace.js";
7
7
  export declare const clientAvailabilityMinimumWindows = 3;
8
8
  export declare const availabilityRequestPolicy: {
9
9
  readonly sender_modes: readonly ["employer"];
10
- readonly recipient_identities: readonly ["client"];
10
+ readonly recipient_modes: readonly ["client"];
11
11
  readonly allow_group: false;
12
12
  };
13
13
  export declare const RoutesChatDataType: {
@@ -11,7 +11,7 @@ import { validateClientAvailabilityInput } from "./validation.js";
11
11
  export const clientAvailabilityMinimumWindows = 3;
12
12
  export const availabilityRequestPolicy = {
13
13
  sender_modes: [UserTypeEmployer],
14
- recipient_identities: [UserTypeClient],
14
+ recipient_modes: [UserTypeClient],
15
15
  allow_group: false,
16
16
  };
17
17
  export const RoutesChatDataType = {
@@ -15,6 +15,7 @@ export type UpdateExternalUserOptions = {
15
15
  owner_id: string;
16
16
  in: ExternalUserInput;
17
17
  };
18
+ export declare function userSupportsMode(user: Pick<User, "account_identity"> | null | undefined, mode: User["active_mode"]): boolean;
18
19
  export declare function isFabriktorUser(user: Pick<User, "account_identity"> | null | undefined): boolean;
19
20
  export declare function canManageExternalUser(user: User | null | undefined, owner_id: string): boolean;
20
21
  export type SearchExternalUsersOptions = SearchUsersOptions;
@@ -84,3 +85,4 @@ export declare class UsersFX implements UsersFXOperator {
84
85
  private updatedUser;
85
86
  }
86
87
  export declare function newUsersFX(opts: UsersFXOptions): UsersFX;
88
+ export declare function isWorkAccountIdentity(value: string): value is WorkAccountIdentity;
@@ -27,11 +27,22 @@ const msgWorkIdentityRequiresClient = "A work identity can only be established f
27
27
  const msgInvalidWorkIdentity = "Work identity must be employee or employer.";
28
28
  const resourceUsername = "username";
29
29
  const resourceUser = "user";
30
+ // Mirrors User.ValAccountMode. Public users expose identity, not active mode.
31
+ // A work identity retains Client mode even while its owner is working.
32
+ const accountModes = {
33
+ [UserTypeClient]: [UserTypeClient],
34
+ [UserTypeEmployee]: [UserTypeEmployee, UserTypeClient],
35
+ [UserTypeEmployer]: [UserTypeEmployer, UserTypeClient],
36
+ [UserTypeExternal]: [UserTypeExternal],
37
+ };
38
+ export function userSupportsMode(user, mode) {
39
+ return (!!user &&
40
+ Object.hasOwn(accountModes, user.account_identity) &&
41
+ accountModes[user.account_identity].includes(mode));
42
+ }
30
43
  // External records are private contacts, not messaging accounts.
31
44
  export function isFabriktorUser(user) {
32
- return (user?.account_identity === UserTypeClient ||
33
- user?.account_identity === UserTypeEmployee ||
34
- user?.account_identity === UserTypeEmployer);
45
+ return userSupportsMode(user, UserTypeClient);
35
46
  }
36
47
  export function canManageExternalUser(user, owner_id) {
37
48
  return (!!resolvedID(owner_id) &&
@@ -384,15 +395,12 @@ function errPhoneCodeRequired(field) {
384
395
  msg: msgPhoneCodeRequired,
385
396
  });
386
397
  }
387
- function isWorkAccountIdentity(value) {
398
+ export function isWorkAccountIdentity(value) {
388
399
  return value === UserTypeEmployee || value === UserTypeEmployer;
389
400
  }
390
401
  function validateActiveMode(accountIdentity, activeMode) {
391
- if ((accountIdentity === UserTypeEmployer &&
392
- (activeMode === UserTypeEmployer || activeMode === UserTypeClient)) ||
393
- (accountIdentity === UserTypeEmployee &&
394
- (activeMode === UserTypeEmployee || activeMode === UserTypeClient)) ||
395
- (accountIdentity === UserTypeClient && activeMode === UserTypeClient)) {
402
+ const user = { account_identity: accountIdentity };
403
+ if (isFabriktorUser(user) && userSupportsMode(user, activeMode)) {
396
404
  return;
397
405
  }
398
406
  throw errValidation({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabriktor/fx",
3
- "version": "0.0.146",
3
+ "version": "0.0.147",
4
4
  "description": "![Fabriktor Logo](./img/fabriktor-character.gif)",
5
5
  "type": "module",
6
6
  "exports": {