@fonderie/workspaces 5.0.0 → 5.2.0

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.
package/dist/index.d.cts CHANGED
@@ -19,7 +19,7 @@ interface IWorkspacesConfig {
19
19
  personalWorkspace?: boolean;
20
20
  routes?: Partial<Record<WorkspaceRouteId, WorkspaceRouteOverride>>;
21
21
  }
22
- type WorkspaceRouteId = 'createWorkspace' | 'listWorkspaces' | 'getWorkspace' | 'updateWorkspace' | 'archive' | 'restore' | 'getSettings' | 'updateSettings' | 'listMembers' | 'removeMember' | 'getMemberRoles' | 'addMemberRole' | 'removeMemberRole' | 'listInvitations' | 'invite' | 'cancelInvitation' | 'acceptInvitation' | 'createRole' | 'listRoles' | 'getRole' | 'updateRole' | 'removeRole' | 'setRolePermissions';
22
+ type WorkspaceRouteId = 'createWorkspace' | 'listWorkspaces' | 'getWorkspace' | 'updateWorkspace' | 'archive' | 'restore' | 'getSettings' | 'updateSettings' | 'listMembers' | 'removeMember' | 'getMemberRoles' | 'addMemberRole' | 'removeMemberRole' | 'listInvitations' | 'invite' | 'cancelInvitation' | 'acceptInvitation' | 'createRole' | 'listRoles' | 'getRole' | 'updateRole' | 'removeRole' | 'getRolePermissions' | 'setRolePermissions';
23
23
  type WorkspaceRouteOverride = string | {
24
24
  method?: string;
25
25
  path?: string;
@@ -59,6 +59,7 @@ interface IWorkspaceDTO {
59
59
  isPersonal: boolean;
60
60
  isArchived: boolean;
61
61
  archivedAt: string;
62
+ archivedBy: string;
62
63
  createdAt: string;
63
64
  updatedAt: string;
64
65
  }
@@ -77,6 +78,18 @@ interface IMemberDTO {
77
78
  roleName: string;
78
79
  confirmed: boolean;
79
80
  createdAt: string;
81
+ /**
82
+ * Identity, carried so a member list is renderable from this endpoint alone.
83
+ *
84
+ * listMembers() already joins the users table for these; without them a
85
+ * client has no name to show and falls back to printing a user id.
86
+ *
87
+ * Empty string when absent, matching every other string field in this file.
88
+ */
89
+ email: string;
90
+ firstName: string;
91
+ lastName: string;
92
+ profileImageUrl: string;
80
93
  }
81
94
  interface IInvitationDTO {
82
95
  id: string;
@@ -116,10 +129,10 @@ declare const updateWorkspaceSchema: z.ZodObject<{
116
129
  line1: z.ZodOptional<z.ZodString>;
117
130
  line2: z.ZodOptional<z.ZodString>;
118
131
  city: z.ZodOptional<z.ZodString>;
119
- region: z.ZodOptional<z.ZodString>;
120
- postalCode: z.ZodOptional<z.ZodString>;
132
+ state: z.ZodOptional<z.ZodString>;
133
+ zip: z.ZodOptional<z.ZodString>;
121
134
  country: z.ZodOptional<z.ZodString>;
122
- }, z.core.$loose>>>;
135
+ }, z.core.$strip>>>;
123
136
  }, z.core.$strip>;
124
137
  declare const updateSettingsSchema: z.ZodObject<{
125
138
  locale: z.ZodOptional<z.ZodString>;
@@ -214,4 +227,11 @@ interface IImportMembership {
214
227
  }
215
228
  declare function importMembership(store: IStoreAdapter, m: IImportMembership): Promise<void>;
216
229
 
217
- export { EVENT_KEYS, type IImportMembership, type IImportRole, type IImportWorkspace, IInvitation, type IInvitationDTO, IMember, type IMemberDTO, IRole, type IRoleDTO, IWorkspace, type IWorkspaceDTO, IWorkspaceSettings, type IWorkspaceSettingsDTO, type IWorkspacesConfig, MESSAGE_KEYS, type WorkspacesEventKey, type WorkspacesMessageKey, WorkspacesModule, importMembership, importRole, importWorkspace, schemas, toInvitationDTO, toMemberDTO, toRoleDTO, toSettingsDTO, toWorkspaceDTO };
230
+ declare function deleteUserData(store: IStoreAdapter, userId: string): Promise<number>;
231
+ declare function exportUserData(store: IStoreAdapter, userId: string): Promise<unknown>;
232
+ declare function workspaceExportContributor(store: IStoreAdapter): {
233
+ name: string;
234
+ collect: (userId: string) => Promise<unknown>;
235
+ };
236
+
237
+ export { EVENT_KEYS, type IImportMembership, type IImportRole, type IImportWorkspace, IInvitation, type IInvitationDTO, IMember, type IMemberDTO, IRole, type IRoleDTO, IWorkspace, type IWorkspaceDTO, IWorkspaceSettings, type IWorkspaceSettingsDTO, type IWorkspacesConfig, MESSAGE_KEYS, type WorkspacesEventKey, type WorkspacesMessageKey, WorkspacesModule, deleteUserData, exportUserData, importMembership, importRole, importWorkspace, schemas, toInvitationDTO, toMemberDTO, toRoleDTO, toSettingsDTO, toWorkspaceDTO, workspaceExportContributor };
package/dist/index.d.ts CHANGED
@@ -19,7 +19,7 @@ interface IWorkspacesConfig {
19
19
  personalWorkspace?: boolean;
20
20
  routes?: Partial<Record<WorkspaceRouteId, WorkspaceRouteOverride>>;
21
21
  }
22
- type WorkspaceRouteId = 'createWorkspace' | 'listWorkspaces' | 'getWorkspace' | 'updateWorkspace' | 'archive' | 'restore' | 'getSettings' | 'updateSettings' | 'listMembers' | 'removeMember' | 'getMemberRoles' | 'addMemberRole' | 'removeMemberRole' | 'listInvitations' | 'invite' | 'cancelInvitation' | 'acceptInvitation' | 'createRole' | 'listRoles' | 'getRole' | 'updateRole' | 'removeRole' | 'setRolePermissions';
22
+ type WorkspaceRouteId = 'createWorkspace' | 'listWorkspaces' | 'getWorkspace' | 'updateWorkspace' | 'archive' | 'restore' | 'getSettings' | 'updateSettings' | 'listMembers' | 'removeMember' | 'getMemberRoles' | 'addMemberRole' | 'removeMemberRole' | 'listInvitations' | 'invite' | 'cancelInvitation' | 'acceptInvitation' | 'createRole' | 'listRoles' | 'getRole' | 'updateRole' | 'removeRole' | 'getRolePermissions' | 'setRolePermissions';
23
23
  type WorkspaceRouteOverride = string | {
24
24
  method?: string;
25
25
  path?: string;
@@ -59,6 +59,7 @@ interface IWorkspaceDTO {
59
59
  isPersonal: boolean;
60
60
  isArchived: boolean;
61
61
  archivedAt: string;
62
+ archivedBy: string;
62
63
  createdAt: string;
63
64
  updatedAt: string;
64
65
  }
@@ -77,6 +78,18 @@ interface IMemberDTO {
77
78
  roleName: string;
78
79
  confirmed: boolean;
79
80
  createdAt: string;
81
+ /**
82
+ * Identity, carried so a member list is renderable from this endpoint alone.
83
+ *
84
+ * listMembers() already joins the users table for these; without them a
85
+ * client has no name to show and falls back to printing a user id.
86
+ *
87
+ * Empty string when absent, matching every other string field in this file.
88
+ */
89
+ email: string;
90
+ firstName: string;
91
+ lastName: string;
92
+ profileImageUrl: string;
80
93
  }
81
94
  interface IInvitationDTO {
82
95
  id: string;
@@ -116,10 +129,10 @@ declare const updateWorkspaceSchema: z.ZodObject<{
116
129
  line1: z.ZodOptional<z.ZodString>;
117
130
  line2: z.ZodOptional<z.ZodString>;
118
131
  city: z.ZodOptional<z.ZodString>;
119
- region: z.ZodOptional<z.ZodString>;
120
- postalCode: z.ZodOptional<z.ZodString>;
132
+ state: z.ZodOptional<z.ZodString>;
133
+ zip: z.ZodOptional<z.ZodString>;
121
134
  country: z.ZodOptional<z.ZodString>;
122
- }, z.core.$loose>>>;
135
+ }, z.core.$strip>>>;
123
136
  }, z.core.$strip>;
124
137
  declare const updateSettingsSchema: z.ZodObject<{
125
138
  locale: z.ZodOptional<z.ZodString>;
@@ -214,4 +227,11 @@ interface IImportMembership {
214
227
  }
215
228
  declare function importMembership(store: IStoreAdapter, m: IImportMembership): Promise<void>;
216
229
 
217
- export { EVENT_KEYS, type IImportMembership, type IImportRole, type IImportWorkspace, IInvitation, type IInvitationDTO, IMember, type IMemberDTO, IRole, type IRoleDTO, IWorkspace, type IWorkspaceDTO, IWorkspaceSettings, type IWorkspaceSettingsDTO, type IWorkspacesConfig, MESSAGE_KEYS, type WorkspacesEventKey, type WorkspacesMessageKey, WorkspacesModule, importMembership, importRole, importWorkspace, schemas, toInvitationDTO, toMemberDTO, toRoleDTO, toSettingsDTO, toWorkspaceDTO };
230
+ declare function deleteUserData(store: IStoreAdapter, userId: string): Promise<number>;
231
+ declare function exportUserData(store: IStoreAdapter, userId: string): Promise<unknown>;
232
+ declare function workspaceExportContributor(store: IStoreAdapter): {
233
+ name: string;
234
+ collect: (userId: string) => Promise<unknown>;
235
+ };
236
+
237
+ export { EVENT_KEYS, type IImportMembership, type IImportRole, type IImportWorkspace, IInvitation, type IInvitationDTO, IMember, type IMemberDTO, IRole, type IRoleDTO, IWorkspace, type IWorkspaceDTO, IWorkspaceSettings, type IWorkspaceSettingsDTO, type IWorkspacesConfig, MESSAGE_KEYS, type WorkspacesEventKey, type WorkspacesMessageKey, WorkspacesModule, deleteUserData, exportUserData, importMembership, importRole, importWorkspace, schemas, toInvitationDTO, toMemberDTO, toRoleDTO, toSettingsDTO, toWorkspaceDTO, workspaceExportContributor };
package/dist/index.js CHANGED
@@ -42,10 +42,10 @@ var addressSchema = z.object({
42
42
  line1: z.string().max(200).optional(),
43
43
  line2: z.string().max(200).optional(),
44
44
  city: z.string().max(100).optional(),
45
- region: z.string().max(100).optional(),
46
- postalCode: z.string().max(20).optional(),
45
+ state: z.string().max(100).optional(),
46
+ zip: z.string().max(20).optional(),
47
47
  country: z.string().max(60).optional()
48
- }).passthrough();
48
+ });
49
49
  var updateWorkspaceSchema = z.object({
50
50
  name: z.string().trim().min(1).max(200).optional(),
51
51
  description: z.string().max(2e3).nullable().optional(),
@@ -586,6 +586,19 @@ async function setRolePermissions(roleId, workspaceId, permissions, store) {
586
586
  }
587
587
  });
588
588
  }
589
+ async function getRolePermissions(roleId, workspaceId, store) {
590
+ return store.query(
591
+ `SELECT permission_key AS "permissionKey",
592
+ can_create AS "canCreate",
593
+ can_read AS "canRead",
594
+ can_update AS "canUpdate",
595
+ can_delete AS "canDelete"
596
+ FROM fonderie_role_permissions
597
+ WHERE role_id = $1 AND workspace_id = $2
598
+ ORDER BY permission_key`,
599
+ [roleId, workspaceId]
600
+ );
601
+ }
589
602
 
590
603
  // src/models/role.model.ts
591
604
  var RoleModel = class {
@@ -614,10 +627,13 @@ var RoleModel = class {
614
627
  setPermissions(roleId, workspaceId, permissions) {
615
628
  return setRolePermissions(roleId, workspaceId, permissions, this.store);
616
629
  }
630
+ getPermissions(roleId, workspaceId) {
631
+ return getRolePermissions(roleId, workspaceId, this.store);
632
+ }
617
633
  };
618
634
 
619
635
  // src/dtos/workspace.ts
620
- import { stringOrEmpty, booleanOrFalse } from "@fonderie/core/parser";
636
+ import { booleanOrFalse, dateOrEmpty, stringOrEmpty } from "@fonderie/core/parser";
621
637
  function toWorkspaceDTO(ws) {
622
638
  const addr = ws.address ?? {};
623
639
  return {
@@ -641,9 +657,10 @@ function toWorkspaceDTO(ws) {
641
657
  ownerId: stringOrEmpty(ws.ownerId),
642
658
  isPersonal: booleanOrFalse(ws.isPersonal),
643
659
  isArchived: ws.archivedAt !== null,
644
- archivedAt: stringOrEmpty(ws.archivedAt),
645
- createdAt: stringOrEmpty(ws.createdAt),
646
- updatedAt: stringOrEmpty(ws.updatedAt)
660
+ archivedAt: dateOrEmpty(ws.archivedAt),
661
+ archivedBy: stringOrEmpty(ws.archivedBy),
662
+ createdAt: dateOrEmpty(ws.createdAt),
663
+ updatedAt: dateOrEmpty(ws.updatedAt)
647
664
  };
648
665
  }
649
666
  function toRoleDTO(role) {
@@ -663,7 +680,11 @@ function toMemberDTO(m) {
663
680
  roleId: stringOrEmpty(m.roleId),
664
681
  roleName: stringOrEmpty(m.roleName),
665
682
  confirmed: booleanOrFalse(m.confirmed),
666
- createdAt: stringOrEmpty(m.createdAt)
683
+ createdAt: dateOrEmpty(m.createdAt),
684
+ email: stringOrEmpty(m.email),
685
+ firstName: stringOrEmpty(m.firstName),
686
+ lastName: stringOrEmpty(m.lastName),
687
+ profileImageUrl: stringOrEmpty(m.profileImageUrl)
667
688
  };
668
689
  }
669
690
  function toInvitationDTO(inv) {
@@ -674,8 +695,8 @@ function toInvitationDTO(inv) {
674
695
  roleId: stringOrEmpty(inv.roleId),
675
696
  token: stringOrEmpty(inv.token),
676
697
  status: stringOrEmpty(inv.status),
677
- expiresAt: stringOrEmpty(inv.expiresAt),
678
- createdAt: stringOrEmpty(inv.createdAt)
698
+ expiresAt: dateOrEmpty(inv.expiresAt),
699
+ createdAt: dateOrEmpty(inv.createdAt)
679
700
  };
680
701
  }
681
702
  function toSettingsDTO(s) {
@@ -994,6 +1015,24 @@ function roleController(store) {
994
1015
  await roles.delete(roleId, ctx.workspace.id);
995
1016
  return setApiResponse4(HTTP4.OK, "ROLE_DELETED", "Role deleted successfully.");
996
1017
  },
1018
+ async getPermissions(ctx) {
1019
+ if (!ctx.workspace) {
1020
+ return setApiResponse4(HTTP4.NOT_FOUND, "NOT_FOUND", "Workspace not found");
1021
+ }
1022
+ const params = ctx.meta["params"];
1023
+ const roleId = params?.["roleId"];
1024
+ if (!roleId) {
1025
+ return setApiResponse4(HTTP4.UNPROCESSABLE, "INVALID_PARAMETER", "roleId is required");
1026
+ }
1027
+ const role = await roles.findById(roleId);
1028
+ if (!role) {
1029
+ return setApiResponse4(HTTP4.NOT_FOUND, "NOT_FOUND", "Role not found");
1030
+ }
1031
+ const permissions = await roles.getPermissions(roleId, ctx.workspace.id);
1032
+ return setApiResponse4(HTTP4.OK, "PERMISSIONS_FETCHED", "Role permissions retrieved successfully.", {
1033
+ permissions
1034
+ });
1035
+ },
997
1036
  async setPermissions(ctx) {
998
1037
  if (!ctx.workspace) {
999
1038
  return setApiResponse4(HTTP4.NOT_FOUND, "NOT_FOUND", "Workspace not found");
@@ -1304,6 +1343,7 @@ function buildWorkspaceRoutes(store, config, bus) {
1304
1343
  R("getRole", "GET", "/workspaces/roles/:roleId", requireAuth, wsCtx, role.get),
1305
1344
  R("updateRole", "PUT", "/workspaces/roles/:roleId", requireAuth, wsCtx, validate(updateRoleSchema), role.update),
1306
1345
  R("removeRole", "DELETE", "/workspaces/roles/:roleId", requireAuth, wsCtx, role.remove),
1346
+ R("getRolePermissions", "GET", "/workspaces/roles/:roleId/permissions", requireAuth, wsCtx, role.getPermissions),
1307
1347
  R("setRolePermissions", "POST", "/workspaces/roles/:roleId/permissions", requireAuth, wsCtx, validate(setRolePermissionsSchema), role.setPermissions),
1308
1348
  // ── Workspace lifecycle
1309
1349
  R("archive", "POST", "/workspaces/archive", requireAuth, wsCtx, workspace.archive),
@@ -1460,10 +1500,35 @@ async function importMembership(store, m) {
1460
1500
  vals
1461
1501
  );
1462
1502
  }
1503
+
1504
+ // src/retention.ts
1505
+ async function deleteUserData(store, userId) {
1506
+ const rows = await store.query(
1507
+ `DELETE FROM fonderie_role_user_workspaces WHERE user_id = $1 RETURNING user_id`,
1508
+ [userId]
1509
+ );
1510
+ return rows.length;
1511
+ }
1512
+ async function exportUserData(store, userId) {
1513
+ const rows = await store.query(
1514
+ `SELECT ruw.workspace_id, ruw.role_id, r.name AS role_name
1515
+ FROM fonderie_role_user_workspaces ruw
1516
+ JOIN fonderie_roles r ON r.id = ruw.role_id
1517
+ WHERE ruw.user_id = $1 AND ruw.removed = false
1518
+ ORDER BY ruw.workspace_id`,
1519
+ [userId]
1520
+ );
1521
+ return { memberships: rows };
1522
+ }
1523
+ function workspaceExportContributor(store) {
1524
+ return { name: "workspaces", collect: (userId) => exportUserData(store, userId) };
1525
+ }
1463
1526
  export {
1464
1527
  EVENT_KEYS,
1465
1528
  MESSAGE_KEYS,
1466
1529
  WorkspacesModule,
1530
+ deleteUserData,
1531
+ exportUserData,
1467
1532
  importMembership,
1468
1533
  importRole,
1469
1534
  importWorkspace,
@@ -1474,6 +1539,7 @@ export {
1474
1539
  toRoleDTO,
1475
1540
  toSettingsDTO,
1476
1541
  toWorkspaceDTO,
1477
- withWorkspace
1542
+ withWorkspace,
1543
+ workspaceExportContributor
1478
1544
  };
1479
1545
  //# sourceMappingURL=index.js.map