@stndrds/schema 1.0.0-alpha.71 → 1.0.0-alpha.73
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/chunk-6P3NPTYV.mjs +58 -0
- package/dist/{chunk-INXFKM4S.mjs → chunk-ABOLTRIR.mjs} +87 -55
- package/dist/{chunk-4GHZ6AUF.js → chunk-EWDCS5EE.js} +237 -205
- package/dist/chunk-JZO52C3F.js +58 -0
- package/dist/default-roles-76HUWY6T.js +23 -0
- package/dist/{default-roles-42X3TJI5.mjs → default-roles-OAMHLOCS.mjs} +3 -1
- package/dist/index.d.mts +18 -25
- package/dist/index.d.ts +18 -25
- package/dist/index.js +31 -6
- package/dist/index.mjs +27 -2
- package/dist/{runtime-BV9XBP1p.d.ts → runtime-CJVwSgr6.d.ts} +55 -104
- package/dist/{runtime-DzpQ5gRG.d.mts → runtime-Ca41jw8q.d.mts} +55 -104
- package/dist/runtime.d.mts +1 -1
- package/dist/runtime.d.ts +1 -1
- package/dist/runtime.js +3 -2
- package/dist/runtime.mjs +2 -1
- package/package.json +2 -2
- package/dist/chunk-36UBIXJN.js +0 -82
- package/dist/chunk-V5QXU2OK.mjs +0 -82
- package/dist/default-roles-C3FYDYMN.js +0 -21
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// src/constants/default-roles.ts
|
|
2
|
+
var SYSTEM_RESOURCES = {
|
|
3
|
+
/** User profiles, invitations, roles and permissions management */
|
|
4
|
+
PEOPLE: "people",
|
|
5
|
+
/** Object definitions, attributes, tenant settings and audit logs */
|
|
6
|
+
WORKSPACE: "workspace"
|
|
7
|
+
};
|
|
8
|
+
var ALL_SYSTEM_RESOURCES = [
|
|
9
|
+
SYSTEM_RESOURCES.PEOPLE,
|
|
10
|
+
SYSTEM_RESOURCES.WORKSPACE
|
|
11
|
+
];
|
|
12
|
+
var SYSTEM_RESOURCE_LABELS = {
|
|
13
|
+
people: "People",
|
|
14
|
+
workspace: "Workspace"
|
|
15
|
+
};
|
|
16
|
+
var DEFAULT_ROLES = {
|
|
17
|
+
/** Full platform access - can manage everything */
|
|
18
|
+
OWNER: "owner",
|
|
19
|
+
/** Standard user - can work with business data and view people */
|
|
20
|
+
MEMBER: "member"
|
|
21
|
+
};
|
|
22
|
+
var DEFAULT_ROLE_LABELS = {
|
|
23
|
+
owner: "Owner",
|
|
24
|
+
member: "Member"
|
|
25
|
+
};
|
|
26
|
+
var DEFAULT_ROLE_DESCRIPTIONS = {
|
|
27
|
+
owner: "Full access to all platform features and data",
|
|
28
|
+
member: "Can view, create, edit and delete business data"
|
|
29
|
+
};
|
|
30
|
+
var ALL_ACTIONS = ["read", "create", "update", "delete"];
|
|
31
|
+
var DEFAULT_ROLE_PERMISSIONS = {
|
|
32
|
+
owner: {
|
|
33
|
+
system: [{ target: "*", actions: ALL_ACTIONS }],
|
|
34
|
+
object: [{ target: "*", actions: ALL_ACTIONS }]
|
|
35
|
+
},
|
|
36
|
+
member: {
|
|
37
|
+
system: [{ target: "people", actions: ["read"] }],
|
|
38
|
+
object: [{ target: "*", actions: ALL_ACTIONS }]
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
function isDefaultRole(roleName) {
|
|
42
|
+
return Object.values(DEFAULT_ROLES).includes(roleName);
|
|
43
|
+
}
|
|
44
|
+
function isAdminRole(roleName) {
|
|
45
|
+
return roleName === DEFAULT_ROLES.OWNER;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
SYSTEM_RESOURCES,
|
|
50
|
+
ALL_SYSTEM_RESOURCES,
|
|
51
|
+
SYSTEM_RESOURCE_LABELS,
|
|
52
|
+
DEFAULT_ROLES,
|
|
53
|
+
DEFAULT_ROLE_LABELS,
|
|
54
|
+
DEFAULT_ROLE_DESCRIPTIONS,
|
|
55
|
+
DEFAULT_ROLE_PERMISSIONS,
|
|
56
|
+
isDefaultRole,
|
|
57
|
+
isAdminRole
|
|
58
|
+
};
|
|
@@ -13,6 +13,9 @@ import {
|
|
|
13
13
|
validateObject,
|
|
14
14
|
validateObjectOrThrow
|
|
15
15
|
} from "./chunk-5SZ5OISG.mjs";
|
|
16
|
+
import {
|
|
17
|
+
isAdminRole
|
|
18
|
+
} from "./chunk-6P3NPTYV.mjs";
|
|
16
19
|
import {
|
|
17
20
|
__require
|
|
18
21
|
} from "./chunk-Y6FXYEAI.mjs";
|
|
@@ -3700,13 +3703,24 @@ function parsePipeExpression(pipeExpr) {
|
|
|
3700
3703
|
}
|
|
3701
3704
|
function renderLabelExpression(template, values, fallback = DEFAULT_LABEL_FALLBACK) {
|
|
3702
3705
|
const result = template.replace(/\{\{\s*([^}]+)\s*\}\}/g, (_, expr) => {
|
|
3703
|
-
const
|
|
3704
|
-
const
|
|
3705
|
-
|
|
3706
|
+
const orParts = expr.split("||").map((s) => s.trim());
|
|
3707
|
+
const lastPart = orParts[orParts.length - 1];
|
|
3708
|
+
const pipeSplit = lastPart.split("|").map((s) => s.trim());
|
|
3709
|
+
orParts[orParts.length - 1] = pipeSplit[0];
|
|
3710
|
+
const pipes = pipeSplit.slice(1).filter(Boolean);
|
|
3711
|
+
const alternatives = orParts.filter(Boolean);
|
|
3712
|
+
let value = "";
|
|
3713
|
+
for (const alt of alternatives) {
|
|
3714
|
+
const v = getValue(values, alt);
|
|
3715
|
+
if (v != null && v !== "") {
|
|
3716
|
+
value = v;
|
|
3717
|
+
break;
|
|
3718
|
+
}
|
|
3719
|
+
}
|
|
3706
3720
|
const isEmpty3 = value == null || value === "";
|
|
3707
|
-
if (isEmpty3 &&
|
|
3708
|
-
for (
|
|
3709
|
-
const { name: pipeName, args } = parsePipeExpression(
|
|
3721
|
+
if (isEmpty3 && pipes.length === 0) return "";
|
|
3722
|
+
for (const pipeExpr of pipes) {
|
|
3723
|
+
const { name: pipeName, args } = parsePipeExpression(pipeExpr);
|
|
3710
3724
|
const simpleFn = simplePipes[pipeName];
|
|
3711
3725
|
if (simpleFn) {
|
|
3712
3726
|
if (value != null && value !== "") {
|
|
@@ -3728,13 +3742,19 @@ function isLabelExpression(value) {
|
|
|
3728
3742
|
}
|
|
3729
3743
|
function extractAttributeNames(template) {
|
|
3730
3744
|
const names = [];
|
|
3731
|
-
const regex = /\{\{\s*([
|
|
3745
|
+
const regex = /\{\{\s*([^}]+)\s*\}\}/g;
|
|
3732
3746
|
let match;
|
|
3733
3747
|
while ((match = regex.exec(template)) !== null) {
|
|
3734
|
-
const
|
|
3735
|
-
const
|
|
3736
|
-
|
|
3737
|
-
|
|
3748
|
+
const expr = match[1].trim();
|
|
3749
|
+
const orParts = expr.split("||").map((s) => s.trim());
|
|
3750
|
+
const lastPart = orParts[orParts.length - 1];
|
|
3751
|
+
orParts[orParts.length - 1] = lastPart.split("|")[0].trim();
|
|
3752
|
+
for (const part of orParts) {
|
|
3753
|
+
if (!part) continue;
|
|
3754
|
+
const rootName = part.split(".")[0];
|
|
3755
|
+
if (rootName && !names.includes(rootName)) {
|
|
3756
|
+
names.push(rootName);
|
|
3757
|
+
}
|
|
3738
3758
|
}
|
|
3739
3759
|
}
|
|
3740
3760
|
return names;
|
|
@@ -4303,7 +4323,6 @@ function createMockUserProfilesRepository(stores) {
|
|
|
4303
4323
|
firstName: data.firstName,
|
|
4304
4324
|
lastName: data.lastName,
|
|
4305
4325
|
avatarUrl: data.avatarUrl,
|
|
4306
|
-
role: data.role ?? "member",
|
|
4307
4326
|
status: data.status ?? "active",
|
|
4308
4327
|
createdAt: /* @__PURE__ */ new Date(),
|
|
4309
4328
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -4336,12 +4355,23 @@ function createMockUserProfilesRepository(stores) {
|
|
|
4336
4355
|
}
|
|
4337
4356
|
return Promise.resolve(results);
|
|
4338
4357
|
},
|
|
4339
|
-
|
|
4358
|
+
getUsersWithRoles(filters) {
|
|
4340
4359
|
const tenantId = getTenantId();
|
|
4341
|
-
const
|
|
4342
|
-
(
|
|
4343
|
-
)
|
|
4344
|
-
|
|
4360
|
+
const profiles = Array.from(stores.userProfiles.values()).filter(
|
|
4361
|
+
(p) => p.tenantId === tenantId
|
|
4362
|
+
);
|
|
4363
|
+
const results = [];
|
|
4364
|
+
for (const profile of profiles) {
|
|
4365
|
+
const roleIds = Array.from(stores.userRoles.values()).filter((ur) => ur.userProfileId === profile.id && ur.tenantId === tenantId).map((ur) => ur.roleId);
|
|
4366
|
+
const roles = Array.from(stores.roles.values()).filter((r) => roleIds.includes(r.id));
|
|
4367
|
+
if (filters?.allowedRoles && filters.allowedRoles.length > 0) {
|
|
4368
|
+
const allowed = filters.allowedRoles;
|
|
4369
|
+
const hasMatchingRole = roles.some((r) => allowed.includes(r.name));
|
|
4370
|
+
if (!hasMatchingRole) continue;
|
|
4371
|
+
}
|
|
4372
|
+
results.push({ ...profile, roles });
|
|
4373
|
+
}
|
|
4374
|
+
return Promise.resolve(results);
|
|
4345
4375
|
},
|
|
4346
4376
|
updateLastLogin(id) {
|
|
4347
4377
|
const profile = stores.userProfiles.get(id);
|
|
@@ -4360,7 +4390,6 @@ function createMockUserProfilesRepository(stores) {
|
|
|
4360
4390
|
email: data.email,
|
|
4361
4391
|
firstName: data.firstName,
|
|
4362
4392
|
lastName: data.lastName,
|
|
4363
|
-
role: data.role ?? "member",
|
|
4364
4393
|
status: "pending",
|
|
4365
4394
|
createdAt: /* @__PURE__ */ new Date(),
|
|
4366
4395
|
updatedAt: /* @__PURE__ */ new Date()
|
|
@@ -4452,7 +4481,6 @@ function createMockPermissionsRepository(stores) {
|
|
|
4452
4481
|
scope: input.scope,
|
|
4453
4482
|
target: input.target,
|
|
4454
4483
|
actions: input.actions,
|
|
4455
|
-
filter: input.filter,
|
|
4456
4484
|
createdAt: /* @__PURE__ */ new Date()
|
|
4457
4485
|
};
|
|
4458
4486
|
stores.permissions.set(perm.id, perm);
|
|
@@ -4497,7 +4525,7 @@ function createMockPermissionsRepository(stores) {
|
|
|
4497
4525
|
const tenantId = getTenantId();
|
|
4498
4526
|
const userRoleIds = Array.from(stores.userRoles.values()).filter((ur) => ur.userProfileId === userProfileId && ur.tenantId === tenantId).map((ur) => ur.roleId);
|
|
4499
4527
|
const userRoles = Array.from(stores.roles.values()).filter((r) => userRoleIds.includes(r.id));
|
|
4500
|
-
const
|
|
4528
|
+
const hasAdmin = userRoles.some((r) => isAdminRole(r.name));
|
|
4501
4529
|
const userPermissions = Array.from(stores.permissions.values()).filter(
|
|
4502
4530
|
(p) => userRoleIds.includes(p.roleId)
|
|
4503
4531
|
);
|
|
@@ -4524,7 +4552,18 @@ function createMockPermissionsRepository(stores) {
|
|
|
4524
4552
|
}
|
|
4525
4553
|
}
|
|
4526
4554
|
}
|
|
4527
|
-
return Promise.resolve({ isAdmin, objectPermissions, systemPermissions });
|
|
4555
|
+
return Promise.resolve({ isAdmin: hasAdmin, objectPermissions, systemPermissions });
|
|
4556
|
+
},
|
|
4557
|
+
countUsersWithRole(roleName) {
|
|
4558
|
+
const tenantId = getTenantId();
|
|
4559
|
+
const role = Array.from(stores.roles.values()).find(
|
|
4560
|
+
(r) => r.tenantId === tenantId && r.name === roleName
|
|
4561
|
+
);
|
|
4562
|
+
if (!role) return Promise.resolve(0);
|
|
4563
|
+
const userIds = new Set(
|
|
4564
|
+
Array.from(stores.userRoles.values()).filter((ur) => ur.roleId === role.id && ur.tenantId === tenantId).map((ur) => ur.userProfileId)
|
|
4565
|
+
);
|
|
4566
|
+
return Promise.resolve(userIds.size);
|
|
4528
4567
|
}
|
|
4529
4568
|
};
|
|
4530
4569
|
}
|
|
@@ -10072,6 +10111,21 @@ var UserService = class extends BaseService {
|
|
|
10072
10111
|
}
|
|
10073
10112
|
const users = await this.adapter.userProfiles.findByIds([...allIds]);
|
|
10074
10113
|
const userMap = new Map(users.map((u) => [u.id, u]));
|
|
10114
|
+
const allAllowedRoles = /* @__PURE__ */ new Set();
|
|
10115
|
+
for (const [, { attr }] of attrIdMap) {
|
|
10116
|
+
if (attr.allowedRoles && attr.allowedRoles.length > 0) {
|
|
10117
|
+
for (const role of attr.allowedRoles) {
|
|
10118
|
+
allAllowedRoles.add(role);
|
|
10119
|
+
}
|
|
10120
|
+
}
|
|
10121
|
+
}
|
|
10122
|
+
let userRolesMap;
|
|
10123
|
+
if (allAllowedRoles.size > 0) {
|
|
10124
|
+
const usersWithRoles = await this.adapter.userProfiles.getUsersWithRoles({
|
|
10125
|
+
allowedRoles: [...allAllowedRoles]
|
|
10126
|
+
});
|
|
10127
|
+
userRolesMap = new Map(usersWithRoles.map((u) => [u.id, u.roles.map((r) => r.name)]));
|
|
10128
|
+
}
|
|
10075
10129
|
for (const [attrName, { attr, ids }] of attrIdMap) {
|
|
10076
10130
|
const invalidIds = [];
|
|
10077
10131
|
const roleErrors = [];
|
|
@@ -10085,8 +10139,10 @@ var UserService = class extends BaseService {
|
|
|
10085
10139
|
invalidIds.push(id);
|
|
10086
10140
|
continue;
|
|
10087
10141
|
}
|
|
10088
|
-
if (attr.allowedRoles && attr.allowedRoles.length > 0) {
|
|
10089
|
-
|
|
10142
|
+
if (attr.allowedRoles && attr.allowedRoles.length > 0 && userRolesMap) {
|
|
10143
|
+
const userRoleNames = userRolesMap.get(id) ?? [];
|
|
10144
|
+
const hasAllowedRole = attr.allowedRoles.some((role) => userRoleNames.includes(role));
|
|
10145
|
+
if (!hasAllowedRole) {
|
|
10090
10146
|
roleErrors.push(id);
|
|
10091
10147
|
}
|
|
10092
10148
|
}
|
|
@@ -14877,7 +14933,6 @@ var UserProfileService = class extends BaseService {
|
|
|
14877
14933
|
* email: authUser.email,
|
|
14878
14934
|
* firstName: authUser.user_metadata.first_name,
|
|
14879
14935
|
* lastName: authUser.user_metadata.last_name,
|
|
14880
|
-
* role: "member",
|
|
14881
14936
|
* status: "active"
|
|
14882
14937
|
* });
|
|
14883
14938
|
* ```
|
|
@@ -14956,7 +15011,6 @@ var UserProfileService = class extends BaseService {
|
|
|
14956
15011
|
* {
|
|
14957
15012
|
* authId: authUser.id,
|
|
14958
15013
|
* email: authUser.email,
|
|
14959
|
-
* role: "member",
|
|
14960
15014
|
* status: "active"
|
|
14961
15015
|
* }
|
|
14962
15016
|
* );
|
|
@@ -14981,7 +15035,6 @@ var UserProfileService = class extends BaseService {
|
|
|
14981
15035
|
const changes = buildAuditChanges(existing, data, [
|
|
14982
15036
|
"firstName",
|
|
14983
15037
|
"lastName",
|
|
14984
|
-
"role",
|
|
14985
15038
|
"status"
|
|
14986
15039
|
]);
|
|
14987
15040
|
if (changes.length > 0) {
|
|
@@ -15005,11 +15058,13 @@ var UserProfileService = class extends BaseService {
|
|
|
15005
15058
|
*/
|
|
15006
15059
|
async deleteProfile(profileId, options) {
|
|
15007
15060
|
const profile = await this.getProfileOrThrow(profileId);
|
|
15008
|
-
if (options?.checkAdmin) {
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15061
|
+
if (options?.checkAdmin && this.adapter.permissions) {
|
|
15062
|
+
const ownerCount = await this.adapter.permissions.countUsersWithRole("owner");
|
|
15063
|
+
if (ownerCount <= 1) {
|
|
15064
|
+
const userRoles = await this.adapter.permissions.getUserRoles(profileId);
|
|
15065
|
+
const isOwner = userRoles.some((r) => r.name === "owner");
|
|
15066
|
+
if (isOwner) {
|
|
15067
|
+
throw new Error("Cannot delete the last owner user");
|
|
15013
15068
|
}
|
|
15014
15069
|
}
|
|
15015
15070
|
}
|
|
@@ -15045,15 +15100,6 @@ var UserProfileService = class extends BaseService {
|
|
|
15045
15100
|
async updateLastLogin(profileId) {
|
|
15046
15101
|
await this.adapter.userProfiles.updateLastLogin(profileId);
|
|
15047
15102
|
}
|
|
15048
|
-
/**
|
|
15049
|
-
* Change user role
|
|
15050
|
-
*
|
|
15051
|
-
* @param profileId - Profile UUID
|
|
15052
|
-
* @param newRole - New role
|
|
15053
|
-
*/
|
|
15054
|
-
async changeRole(profileId, newRole) {
|
|
15055
|
-
return await this.updateProfile(profileId, { role: newRole });
|
|
15056
|
-
}
|
|
15057
15103
|
/**
|
|
15058
15104
|
* Change user status
|
|
15059
15105
|
*
|
|
@@ -15075,19 +15121,6 @@ var UserProfileService = class extends BaseService {
|
|
|
15075
15121
|
() => this.adapter.userProfiles.findByEmail(email)
|
|
15076
15122
|
);
|
|
15077
15123
|
}
|
|
15078
|
-
/**
|
|
15079
|
-
* Check if user has role
|
|
15080
|
-
*/
|
|
15081
|
-
async hasRole(profileId, role) {
|
|
15082
|
-
const profile = await this.getProfile(profileId);
|
|
15083
|
-
return profile?.role === role;
|
|
15084
|
-
}
|
|
15085
|
-
/**
|
|
15086
|
-
* Check if user is admin
|
|
15087
|
-
*/
|
|
15088
|
-
async isAdmin(profileId) {
|
|
15089
|
-
return await this.hasRole(profileId, "admin");
|
|
15090
|
-
}
|
|
15091
15124
|
/**
|
|
15092
15125
|
* Invite a new user by email.
|
|
15093
15126
|
*
|
|
@@ -15108,7 +15141,6 @@ var UserProfileService = class extends BaseService {
|
|
|
15108
15141
|
* email: "john@example.com",
|
|
15109
15142
|
* firstName: "John",
|
|
15110
15143
|
* lastName: "Doe",
|
|
15111
|
-
* role: "member",
|
|
15112
15144
|
* redirectTo: "https://app.example.com/welcome",
|
|
15113
15145
|
* });
|
|
15114
15146
|
* // Email sent automatically, profile.status === "pending"
|
|
@@ -17348,7 +17380,7 @@ var PermissionService = class extends BaseService {
|
|
|
17348
17380
|
DEFAULT_ROLE_LABELS,
|
|
17349
17381
|
DEFAULT_ROLE_DESCRIPTIONS,
|
|
17350
17382
|
DEFAULT_ROLE_PERMISSIONS
|
|
17351
|
-
} = await import("./default-roles-
|
|
17383
|
+
} = await import("./default-roles-OAMHLOCS.mjs");
|
|
17352
17384
|
const existingRoles = await this.getRoles();
|
|
17353
17385
|
const existingRoleNames = existingRoles.reduce((set, r) => set.add(r.name), /* @__PURE__ */ new Set());
|
|
17354
17386
|
for (const roleName of Object.values(DEFAULT_ROLES)) {
|