@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/README.md +2 -2
- package/brain/outcomes.md +1 -0
- package/brain/signatures.md +11 -0
- package/dist/index.cjs +80 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +25 -5
- package/dist/index.d.ts +25 -5
- package/dist/index.js +77 -11
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
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
|
-
|
|
120
|
-
|
|
132
|
+
state: z.ZodOptional<z.ZodString>;
|
|
133
|
+
zip: z.ZodOptional<z.ZodString>;
|
|
121
134
|
country: z.ZodOptional<z.ZodString>;
|
|
122
|
-
}, z.core.$
|
|
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
|
-
|
|
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
|
-
|
|
120
|
-
|
|
132
|
+
state: z.ZodOptional<z.ZodString>;
|
|
133
|
+
zip: z.ZodOptional<z.ZodString>;
|
|
121
134
|
country: z.ZodOptional<z.ZodString>;
|
|
122
|
-
}, z.core.$
|
|
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
|
-
|
|
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
|
-
|
|
46
|
-
|
|
45
|
+
state: z.string().max(100).optional(),
|
|
46
|
+
zip: z.string().max(20).optional(),
|
|
47
47
|
country: z.string().max(60).optional()
|
|
48
|
-
})
|
|
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 {
|
|
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:
|
|
645
|
-
|
|
646
|
-
|
|
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:
|
|
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:
|
|
678
|
-
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
|