@memberjunction/core-entities-server 6.1.0-edge.5 → 6.1.0-edge.7
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/custom/MJAIBridgeProviderEntityServer.server.d.ts +1 -5
- package/dist/custom/MJAIBridgeProviderEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIBridgeProviderEntityServer.server.js +13 -12
- package/dist/custom/MJAIBridgeProviderEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIRemoteBrowserProviderEntityServer.server.d.ts +2 -6
- package/dist/custom/MJAIRemoteBrowserProviderEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIRemoteBrowserProviderEntityServer.server.js +16 -14
- package/dist/custom/MJAIRemoteBrowserProviderEntityServer.server.js.map +1 -1
- package/dist/custom/MJActionEntityServer.server.d.ts +2 -2
- package/dist/custom/MJActionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJActionEntityServer.server.js +8 -6
- package/dist/custom/MJActionEntityServer.server.js.map +1 -1
- package/dist/custom/MJApplicationEntityServer.server.d.ts +2 -2
- package/dist/custom/MJApplicationEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJApplicationEntityServer.server.js +4 -4
- package/dist/custom/MJApplicationEntityServer.server.js.map +1 -1
- package/dist/custom/MJEntityEntityServer.server.d.ts +36 -0
- package/dist/custom/MJEntityEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJEntityEntityServer.server.js +77 -0
- package/dist/custom/MJEntityEntityServer.server.js.map +1 -0
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts +167 -0
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.js +347 -0
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.js.map +1 -0
- package/dist/custom/MJRemoteOperationEntityServer.server.d.ts +2 -2
- package/dist/custom/MJRemoteOperationEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJRemoteOperationEntityServer.server.js +6 -4
- package/dist/custom/MJRemoteOperationEntityServer.server.js.map +1 -1
- package/dist/custom/MJRoleEntityServer.server.d.ts +78 -0
- package/dist/custom/MJRoleEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJRoleEntityServer.server.js +131 -0
- package/dist/custom/MJRoleEntityServer.server.js.map +1 -0
- package/dist/custom/MJUserEntityServer.server.d.ts +243 -0
- package/dist/custom/MJUserEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJUserEntityServer.server.js +335 -0
- package/dist/custom/MJUserEntityServer.server.js.map +1 -0
- package/dist/custom/MJUserRoleEntityServer.server.d.ts +243 -0
- package/dist/custom/MJUserRoleEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJUserRoleEntityServer.server.js +376 -0
- package/dist/custom/MJUserRoleEntityServer.server.js.map +1 -0
- package/dist/custom/MJUserViewEntityServer.server.d.ts +12 -1
- package/dist/custom/MJUserViewEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserViewEntityServer.server.js +33 -1
- package/dist/custom/MJUserViewEntityServer.server.js.map +1 -1
- package/dist/custom/fieldPermissionDelta.d.ts +57 -0
- package/dist/custom/fieldPermissionDelta.d.ts.map +1 -0
- package/dist/custom/fieldPermissionDelta.js +196 -0
- package/dist/custom/fieldPermissionDelta.js.map +1 -0
- package/dist/custom/fieldPermissionReconciler.d.ts +34 -0
- package/dist/custom/fieldPermissionReconciler.d.ts.map +1 -0
- package/dist/custom/fieldPermissionReconciler.js +96 -0
- package/dist/custom/fieldPermissionReconciler.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +28 -28
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { FieldPermissionAccess } from '@memberjunction/core';
|
|
2
|
+
/**
|
|
3
|
+
* Computes the field-permission rows an entity is missing and the ones it should no longer
|
|
4
|
+
* have. Pure — no I/O, no entity objects, no provider. Everything comes off `EntityInfo`.
|
|
5
|
+
*
|
|
6
|
+
* **Snapshot defaults mirror entity-level permissions**, so enabling field security on an
|
|
7
|
+
* entity changes no behavior until an administrator tightens a specific field. A role that can
|
|
8
|
+
* read the entity gets `ReadAccess = 'Allow'`; its Update and Create follow the entity-level
|
|
9
|
+
* grants, defaulting to `No Access`.
|
|
10
|
+
*
|
|
11
|
+
* **A role without entity-level read gets no rows at all.** The entity-level gate already
|
|
12
|
+
* excludes it, so rows would be noise — and a row granting Update without Read would violate
|
|
13
|
+
* the Read-required CHECK constraint anyway.
|
|
14
|
+
*
|
|
15
|
+
* **Unrestrictable fields (primary keys, `__mj_` columns) get no rows.** They are forced open
|
|
16
|
+
* in the aggregation regardless, so rows for them are clutter that would also trip the
|
|
17
|
+
* save-time guard.
|
|
18
|
+
*
|
|
19
|
+
* **No role is excluded — including the ones the MJ system user holds.** Those rows are what
|
|
20
|
+
* keeps the system user working now that the aggregation has no bypass for it: it holds the
|
|
21
|
+
* standard roles (UI, Developer, Integration), which carry entity read on essentially
|
|
22
|
+
* everything, so the snapshot grants them `Allow` here and the save-time guards refuse any
|
|
23
|
+
* later `Deny` aimed at them. Access the server relies on is therefore visible in the data
|
|
24
|
+
* rather than implied by an exemption in code.
|
|
25
|
+
*/
|
|
26
|
+
export function ComputeFieldPermissionDelta(entity) {
|
|
27
|
+
const accessByRoleID = buildRoleEntityAccessMap(entity);
|
|
28
|
+
const rolesWithEntityPermission = buildRolesWithAnyEntityPermission(entity);
|
|
29
|
+
const restrictableFields = entity.Fields.filter(isRestrictable);
|
|
30
|
+
// The two halves ask DIFFERENT questions of the same permission rows, and must not share an
|
|
31
|
+
// answer. Creating a snapshot row is a grant, so it is offered only to roles that can actually
|
|
32
|
+
// READ the entity (`accessByRoleID`). Deleting a row destroys an administrator's configuration,
|
|
33
|
+
// so it is justified only when the row can no longer influence any decision — which turns on
|
|
34
|
+
// whether the role relates to the entity at all, never on the strength of that relationship.
|
|
35
|
+
return {
|
|
36
|
+
ToInsert: computeMissingRows(restrictableFields, accessByRoleID),
|
|
37
|
+
ToDelete: computeOrphanRowIDs(entity, rolesWithEntityPermission),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* A field is restrictable when field security could meaningfully apply to it. Primary keys and
|
|
42
|
+
* `__mj_` system columns are not, and neither is any field on the security-configuration or
|
|
43
|
+
* identity entities.
|
|
44
|
+
*/
|
|
45
|
+
function isRestrictable(field) {
|
|
46
|
+
return !field.IsUnrestrictableField && !field.IsOnUnrestrictableEntity;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Every role holding ANY entity-permission row for this entity, whatever it grants and whichever
|
|
50
|
+
* `Type` it carries.
|
|
51
|
+
*
|
|
52
|
+
* This is the orphan test's criterion, and it is deliberately weaker than
|
|
53
|
+
* {@link buildRoleEntityAccessMap}. A field rule bound to a role is live at runtime purely on ROLE
|
|
54
|
+
* MEMBERSHIP — `EntityFieldInfo.AggregateFieldRulesForUser` matches on
|
|
55
|
+
* `user.UserRoles.find(...)` and never consults that role's entity-level access. So a role that
|
|
56
|
+
* grants nothing at entity level still contributes its field rules to the aggregate of any user who
|
|
57
|
+
* holds it AND gets entity access from a different role. Judging such a row inert because its own
|
|
58
|
+
* role cannot read the entity confuses a per-role fact with a per-user one, and deleting it on that
|
|
59
|
+
* basis destroys a `Deny` that was fully in force — turning "a Deny always wins" into
|
|
60
|
+
* "a Deny wins until reconciliation runs".
|
|
61
|
+
*
|
|
62
|
+
* Membership of this set is what `MJEntityFieldPermissionEntityServer.Validate()` requires before a
|
|
63
|
+
* field rule may be written at all, so the rule reconciliation enforces on cleanup is the same one
|
|
64
|
+
* authoring enforces on write.
|
|
65
|
+
*/
|
|
66
|
+
function buildRolesWithAnyEntityPermission(entity) {
|
|
67
|
+
const roleIDs = new Set();
|
|
68
|
+
for (const permission of entity.Permissions) {
|
|
69
|
+
const roleID = normalizeID(permission.RoleID);
|
|
70
|
+
if (roleID) {
|
|
71
|
+
roleIDs.add(roleID);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return roleIDs;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Each role's effective entity-level access, aggregating its own Allow/Deny rows the same way
|
|
78
|
+
* `EntityInfo.GetUserPermisions` does one level up: a Deny beats an Allow for the same action.
|
|
79
|
+
*
|
|
80
|
+
* Roles resolving to no read access are omitted entirely, so callers can treat presence in the
|
|
81
|
+
* map as "this role should have rows."
|
|
82
|
+
*/
|
|
83
|
+
function buildRoleEntityAccessMap(entity) {
|
|
84
|
+
const allow = new Map();
|
|
85
|
+
const deny = new Map();
|
|
86
|
+
for (const permission of entity.Permissions) {
|
|
87
|
+
const roleID = normalizeID(permission.RoleID);
|
|
88
|
+
if (!roleID) {
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const bucket = isDenyPermission(permission) ? deny : allow;
|
|
92
|
+
foldPermissionInto(bucket, roleID, permission);
|
|
93
|
+
}
|
|
94
|
+
const effective = new Map();
|
|
95
|
+
for (const [roleID, granted] of allow) {
|
|
96
|
+
const blocked = deny.get(roleID) ?? { CanRead: false, CanUpdate: false, CanCreate: false };
|
|
97
|
+
const access = {
|
|
98
|
+
CanRead: granted.CanRead && !blocked.CanRead,
|
|
99
|
+
CanUpdate: granted.CanUpdate && !blocked.CanUpdate,
|
|
100
|
+
CanCreate: granted.CanCreate && !blocked.CanCreate,
|
|
101
|
+
};
|
|
102
|
+
if (access.CanRead) {
|
|
103
|
+
effective.set(roleID, access);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return effective;
|
|
107
|
+
}
|
|
108
|
+
function isDenyPermission(permission) {
|
|
109
|
+
return (permission.Type ?? 'Allow').trim().toLowerCase() === 'deny';
|
|
110
|
+
}
|
|
111
|
+
function foldPermissionInto(bucket, roleID, permission) {
|
|
112
|
+
const current = bucket.get(roleID) ?? { CanRead: false, CanUpdate: false, CanCreate: false };
|
|
113
|
+
current.CanRead = current.CanRead || !!permission.CanRead;
|
|
114
|
+
current.CanUpdate = current.CanUpdate || !!permission.CanUpdate;
|
|
115
|
+
current.CanCreate = current.CanCreate || !!permission.CanCreate;
|
|
116
|
+
bucket.set(roleID, current);
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Every (restrictable field × qualifying role) pair that has no row yet, at snapshot defaults.
|
|
120
|
+
*/
|
|
121
|
+
function computeMissingRows(fields, accessByRoleID) {
|
|
122
|
+
const missing = [];
|
|
123
|
+
for (const field of fields) {
|
|
124
|
+
const existingRoleIDs = new Set(field.FieldPermissions.map(fp => normalizeID(fp.RoleID)).filter(Boolean));
|
|
125
|
+
for (const [roleID, access] of accessByRoleID) {
|
|
126
|
+
if (existingRoleIDs.has(roleID)) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
// A read-only field cannot be written through the API by anyone — it is excluded from
|
|
130
|
+
// the generated create input and from the update SET list — so an Update or Create
|
|
131
|
+
// verb on it can never decide anything. Writing `Allow` there would author a rule
|
|
132
|
+
// that reads as a granted permission and is in fact inert, on ~1,000 fields x every
|
|
133
|
+
// qualifying role. Read stays meaningful and is untouched: restricting a foreign-key
|
|
134
|
+
// display column ("who does this record belong to") is a legitimate and common use.
|
|
135
|
+
const writable = !field.ReadOnly;
|
|
136
|
+
missing.push({
|
|
137
|
+
EntityFieldID: field.ID,
|
|
138
|
+
RoleID: roleID,
|
|
139
|
+
// Read is Allow by construction — buildRoleEntityAccessMap omits roles without
|
|
140
|
+
// it — which is what keeps these rows on the right side of the Read-required
|
|
141
|
+
// CHECK constraint no matter what Update and Create resolve to.
|
|
142
|
+
ReadAccess: FieldPermissionAccess.Allow,
|
|
143
|
+
UpdateAccess: writable && access.CanUpdate ? FieldPermissionAccess.Allow : FieldPermissionAccess.NoAccess,
|
|
144
|
+
CreateAccess: writable && access.CanCreate ? FieldPermissionAccess.Allow : FieldPermissionAccess.NoAccess,
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return missing;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Rows that should no longer exist. Two ways a row becomes an orphan:
|
|
152
|
+
*
|
|
153
|
+
* - its field is no longer restrictable (a column was made a primary key, or the entity joined
|
|
154
|
+
* the unrestrictable list), so the aggregation returns fully-open for it regardless of any rule;
|
|
155
|
+
* - its role holds no entity-permission row for this entity at all, so no user can carry the rule
|
|
156
|
+
* into an aggregate through this entity — which also covers a role that no longer exists.
|
|
157
|
+
*
|
|
158
|
+
* A row whose FIELD was dropped disappears with the field's cascade, so it never reaches this
|
|
159
|
+
* walk — `entity.Fields` is the live set.
|
|
160
|
+
*
|
|
161
|
+
* **A role's entity-level ACCESS is deliberately not part of this test**, and an earlier version of
|
|
162
|
+
* this function that used it was wrong. It reasoned that a role without entity read is excluded by
|
|
163
|
+
* the entity gate, so its field rules cannot matter. But `EntityInfo.GetUserPermisions` aggregates
|
|
164
|
+
* the entity gate across ALL of a user's roles, exactly as the field aggregation does — so a user
|
|
165
|
+
* reading the entity through role S still carries role R's field rules, whatever R grants on its
|
|
166
|
+
* own. Deleting them silently restored access an administrator had explicitly denied, and
|
|
167
|
+
* `computeMissingRows` only ever writes `Allow`, so it never came back.
|
|
168
|
+
*/
|
|
169
|
+
function computeOrphanRowIDs(entity, rolesWithEntityPermission) {
|
|
170
|
+
const orphans = [];
|
|
171
|
+
for (const field of entity.Fields) {
|
|
172
|
+
const fieldIsRestrictable = isRestrictable(field);
|
|
173
|
+
for (const permission of field.FieldPermissions) {
|
|
174
|
+
const roleID = normalizeID(permission.RoleID);
|
|
175
|
+
if (!fieldIsRestrictable || !roleID || !rolesWithEntityPermission.has(roleID)) {
|
|
176
|
+
orphans.push(permission.ID);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return orphans;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Lowercased ID for map keys. UUIDs arrive with different casing depending on their source, so
|
|
184
|
+
* normalize once here rather than scanning with a comparator on every lookup.
|
|
185
|
+
*/
|
|
186
|
+
function normalizeID(id) {
|
|
187
|
+
return (id ?? '').trim().toLowerCase();
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* True when the delta would change nothing, so callers can skip opening a transaction at all.
|
|
191
|
+
* Reconciliation runs on ordinary saves, and the overwhelmingly common answer is "nothing to do".
|
|
192
|
+
*/
|
|
193
|
+
export function IsEmptyFieldPermissionDelta(delta) {
|
|
194
|
+
return delta.ToInsert.length === 0 && delta.ToDelete.length === 0;
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=fieldPermissionDelta.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldPermissionDelta.js","sourceRoot":"","sources":["../../src/custom/fieldPermissionDelta.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { EntityInfo, IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
2
|
+
/** What a reconciliation run actually wrote. */
|
|
3
|
+
export type FieldPermissionReconcileResult = {
|
|
4
|
+
Inserted: number;
|
|
5
|
+
Deleted: number;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Brings an entity's field-permission rows in line with its fields and entity-level
|
|
9
|
+
* permissions, writing the whole delta in one transaction.
|
|
10
|
+
*
|
|
11
|
+
* Every row goes through `BaseEntity.Save()` / `.Delete()` rather than direct SQL, so the
|
|
12
|
+
* save-time target guard, validation and entity actions all run — the delta function and the
|
|
13
|
+
* guard agree instead of one bypassing the other. `AllowDirectSQLInsert` stays off.
|
|
14
|
+
*
|
|
15
|
+
* Returns immediately when there is nothing to do, which is the overwhelmingly common case:
|
|
16
|
+
* reconciliation is triggered from ordinary saves, and a transaction opened to write zero rows
|
|
17
|
+
* is pure cost.
|
|
18
|
+
*
|
|
19
|
+
* @param entity the entity to reconcile — its `Fields` and `Permissions` are the desired state
|
|
20
|
+
* @param provider the provider to transact on and to build entity objects from
|
|
21
|
+
* @param contextUser the user the writes are attributed to
|
|
22
|
+
*/
|
|
23
|
+
export declare function ReconcileFieldPermissions(entity: EntityInfo, provider: IMetadataProvider, contextUser: UserInfo): Promise<FieldPermissionReconcileResult>;
|
|
24
|
+
/**
|
|
25
|
+
* Runs {@link ReconcileFieldPermissions} and swallows failures into a logged error.
|
|
26
|
+
*
|
|
27
|
+
* For the adapters that reconcile as a SIDE EFFECT of some other save — a role being granted
|
|
28
|
+
* entity access, say. The triggering save has already committed by then, so throwing would
|
|
29
|
+
* report a failure for work that succeeded. The rows stay missing until the next reconciliation,
|
|
30
|
+
* which is a visible loss of access rather than a silent loss of protection: a field with no row
|
|
31
|
+
* on an enabled entity is denied.
|
|
32
|
+
*/
|
|
33
|
+
export declare function ReconcileFieldPermissionsQuietly(entity: EntityInfo, provider: IMetadataProvider, contextUser: UserInfo): Promise<FieldPermissionReconcileResult>;
|
|
34
|
+
//# sourceMappingURL=fieldPermissionReconciler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldPermissionReconciler.d.ts","sourceRoot":"","sources":["../../src/custom/fieldPermissionReconciler.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,UAAU,EACV,iBAAiB,EAIjB,QAAQ,EACX,MAAM,sBAAsB,CAAC;AAI9B,gDAAgD;AAChD,MAAM,MAAM,8BAA8B,GAAG;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB,CAAC;AAIF;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,yBAAyB,CAC3C,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,QAAQ,GACtB,OAAO,CAAC,8BAA8B,CAAC,CAmBzC;AAuDD;;;;;;;;GAQG;AACH,wBAAsB,gCAAgC,CAClD,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,iBAAiB,EAC3B,WAAW,EAAE,QAAQ,GACtB,OAAO,CAAC,8BAA8B,CAAC,CAOzC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { LogDebug, LogError, RunInEntityTransaction, } from '@memberjunction/core';
|
|
2
|
+
import { ComputeFieldPermissionDelta, IsEmptyFieldPermissionDelta } from './fieldPermissionDelta.js';
|
|
3
|
+
const NOTHING_DONE = { Inserted: 0, Deleted: 0 };
|
|
4
|
+
/**
|
|
5
|
+
* Brings an entity's field-permission rows in line with its fields and entity-level
|
|
6
|
+
* permissions, writing the whole delta in one transaction.
|
|
7
|
+
*
|
|
8
|
+
* Every row goes through `BaseEntity.Save()` / `.Delete()` rather than direct SQL, so the
|
|
9
|
+
* save-time target guard, validation and entity actions all run — the delta function and the
|
|
10
|
+
* guard agree instead of one bypassing the other. `AllowDirectSQLInsert` stays off.
|
|
11
|
+
*
|
|
12
|
+
* Returns immediately when there is nothing to do, which is the overwhelmingly common case:
|
|
13
|
+
* reconciliation is triggered from ordinary saves, and a transaction opened to write zero rows
|
|
14
|
+
* is pure cost.
|
|
15
|
+
*
|
|
16
|
+
* @param entity the entity to reconcile — its `Fields` and `Permissions` are the desired state
|
|
17
|
+
* @param provider the provider to transact on and to build entity objects from
|
|
18
|
+
* @param contextUser the user the writes are attributed to
|
|
19
|
+
*/
|
|
20
|
+
export async function ReconcileFieldPermissions(entity, provider, contextUser) {
|
|
21
|
+
if (!entity || !provider) {
|
|
22
|
+
return NOTHING_DONE;
|
|
23
|
+
}
|
|
24
|
+
const delta = ComputeFieldPermissionDelta(entity);
|
|
25
|
+
if (IsEmptyFieldPermissionDelta(delta)) {
|
|
26
|
+
return NOTHING_DONE;
|
|
27
|
+
}
|
|
28
|
+
LogDebug(`[FieldSecurity] Reconciling '${entity.Name}': ` +
|
|
29
|
+
`${delta.ToInsert.length} row(s) to add, ${delta.ToDelete.length} to remove`);
|
|
30
|
+
return RunInEntityTransaction(provider, async () => {
|
|
31
|
+
const deleted = await deleteRows(delta.ToDelete, provider, contextUser);
|
|
32
|
+
const inserted = await insertRows(delta.ToInsert, provider, contextUser, entity);
|
|
33
|
+
return { Inserted: inserted, Deleted: deleted };
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Deletes happen BEFORE inserts. A row can be an orphan for one (field, role) while the same
|
|
38
|
+
* pair needs a fresh row at snapshot defaults — doing it the other way round would collide on
|
|
39
|
+
* the (EntityFieldID, RoleID) uniqueness constraint.
|
|
40
|
+
*/
|
|
41
|
+
async function deleteRows(ids, provider, contextUser) {
|
|
42
|
+
let deleted = 0;
|
|
43
|
+
for (const id of ids) {
|
|
44
|
+
const row = await provider.GetEntityObject('MJ: Entity Field Permissions', contextUser);
|
|
45
|
+
if (!(await row.Load(id))) {
|
|
46
|
+
// Already gone — another reconciliation, or a cascade from a dropped field.
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (await row.Delete()) {
|
|
50
|
+
deleted++;
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
throw new Error(`Field-permission reconciliation could not remove row '${id}': ` +
|
|
54
|
+
`${row.LatestResult?.CompleteMessage ?? 'no error reported'}`);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return deleted;
|
|
58
|
+
}
|
|
59
|
+
async function insertRows(rows, provider, contextUser, entity) {
|
|
60
|
+
let inserted = 0;
|
|
61
|
+
for (const spec of rows) {
|
|
62
|
+
const row = await provider.GetEntityObject('MJ: Entity Field Permissions', contextUser);
|
|
63
|
+
row.NewRecord();
|
|
64
|
+
row.EntityFieldID = spec.EntityFieldID;
|
|
65
|
+
row.RoleID = spec.RoleID;
|
|
66
|
+
row.ReadAccess = spec.ReadAccess;
|
|
67
|
+
row.UpdateAccess = spec.UpdateAccess;
|
|
68
|
+
row.CreateAccess = spec.CreateAccess;
|
|
69
|
+
if (!(await row.Save())) {
|
|
70
|
+
throw new Error(`Field-permission reconciliation could not add a row for '${entity.Name}' ` +
|
|
71
|
+
`(field ${spec.EntityFieldID}, role ${spec.RoleID}): ` +
|
|
72
|
+
`${row.LatestResult?.CompleteMessage ?? 'no error reported'}`);
|
|
73
|
+
}
|
|
74
|
+
inserted++;
|
|
75
|
+
}
|
|
76
|
+
return inserted;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Runs {@link ReconcileFieldPermissions} and swallows failures into a logged error.
|
|
80
|
+
*
|
|
81
|
+
* For the adapters that reconcile as a SIDE EFFECT of some other save — a role being granted
|
|
82
|
+
* entity access, say. The triggering save has already committed by then, so throwing would
|
|
83
|
+
* report a failure for work that succeeded. The rows stay missing until the next reconciliation,
|
|
84
|
+
* which is a visible loss of access rather than a silent loss of protection: a field with no row
|
|
85
|
+
* on an enabled entity is denied.
|
|
86
|
+
*/
|
|
87
|
+
export async function ReconcileFieldPermissionsQuietly(entity, provider, contextUser) {
|
|
88
|
+
try {
|
|
89
|
+
return await ReconcileFieldPermissions(entity, provider, contextUser);
|
|
90
|
+
}
|
|
91
|
+
catch (e) {
|
|
92
|
+
LogError(`[FieldSecurity] Reconciliation of '${entity?.Name}' failed`, undefined, e);
|
|
93
|
+
return NOTHING_DONE;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=fieldPermissionReconciler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fieldPermissionReconciler.js","sourceRoot":"","sources":["../../src/custom/fieldPermissionReconciler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -35,11 +35,18 @@ export * from './custom/MJMaterializedResultEntityServer.server.js';
|
|
|
35
35
|
export * from './custom/MJAISkillPermissionEntityServer.server.js';
|
|
36
36
|
export * from './custom/MJAISkillEntityServer.server.js';
|
|
37
37
|
export * from './custom/MJMLTrainingPipelineEntityServer.server.js';
|
|
38
|
+
export * from './custom/MJUserEntityServer.server.js';
|
|
39
|
+
export * from './custom/MJRoleEntityServer.server.js';
|
|
40
|
+
export * from './custom/MJUserRoleEntityServer.server.js';
|
|
38
41
|
export * from './custom/MJUserRoutineEntityServer.server.js';
|
|
39
42
|
export * from './custom/MJUserRoutineRecipientEntityServer.server.js';
|
|
40
43
|
export * from './custom/MJAPIKeyScopeEntityServer.server.js';
|
|
41
44
|
export * from './custom/MJAPIApplicationScopeEntityServer.server.js';
|
|
42
45
|
export * from './custom/MJRowLevelSecurityFilterEntityServer.server.js';
|
|
46
|
+
export * from './custom/MJEntityFieldPermissionEntityServer.server.js';
|
|
47
|
+
export * from './custom/MJEntityEntityServer.server.js';
|
|
48
|
+
export * from './custom/fieldPermissionDelta.js';
|
|
49
|
+
export * from './custom/fieldPermissionReconciler.js';
|
|
43
50
|
export * from './custom/rowFilterValidation.js';
|
|
44
51
|
export * from './custom/json-schema-lite.js';
|
|
45
52
|
export * from './custom/IntegrationLLMPKCallback.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oCAAoC,CAAC;AACnD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -35,11 +35,18 @@ export * from './custom/MJMaterializedResultEntityServer.server.js';
|
|
|
35
35
|
export * from './custom/MJAISkillPermissionEntityServer.server.js';
|
|
36
36
|
export * from './custom/MJAISkillEntityServer.server.js';
|
|
37
37
|
export * from './custom/MJMLTrainingPipelineEntityServer.server.js';
|
|
38
|
+
export * from './custom/MJUserEntityServer.server.js';
|
|
39
|
+
export * from './custom/MJRoleEntityServer.server.js';
|
|
40
|
+
export * from './custom/MJUserRoleEntityServer.server.js';
|
|
38
41
|
export * from './custom/MJUserRoutineEntityServer.server.js';
|
|
39
42
|
export * from './custom/MJUserRoutineRecipientEntityServer.server.js';
|
|
40
43
|
export * from './custom/MJAPIKeyScopeEntityServer.server.js';
|
|
41
44
|
export * from './custom/MJAPIApplicationScopeEntityServer.server.js';
|
|
42
45
|
export * from './custom/MJRowLevelSecurityFilterEntityServer.server.js';
|
|
46
|
+
export * from './custom/MJEntityFieldPermissionEntityServer.server.js';
|
|
47
|
+
export * from './custom/MJEntityEntityServer.server.js';
|
|
48
|
+
export * from './custom/fieldPermissionDelta.js';
|
|
49
|
+
export * from './custom/fieldPermissionReconciler.js';
|
|
43
50
|
export * from './custom/rowFilterValidation.js';
|
|
44
51
|
export * from './custom/json-schema-lite.js';
|
|
45
52
|
export * from './custom/IntegrationLLMPKCallback.js';
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,wCAAwC,CAAC;AACvD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,kDAAkD,CAAC;AACjE,cAAc,4DAA4D,CAAC;AAC3E,cAAc,4CAA4C,CAAC;AAC3D,cAAc,qCAAqC,CAAC;AACpD,cAAc,wCAAwC,CAAC;AACvD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,wCAAwC,CAAC;AACvD,cAAc,oCAAoC,CAAC;AACnD,cAAc,0CAA0C,CAAC;AACzD,cAAc,sCAAsC,CAAC;AACrD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,yCAAyC,CAAC;AACxD,cAAc,+CAA+C,CAAC;AAC9D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,8CAA8C,CAAC;AAC7D,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mCAAmC,CAAC;AAClD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,wCAAwC,CAAC;AACvD,cAAc,6CAA6C,CAAC;AAC5D,cAAc,0CAA0C,CAAC;AACzD,cAAc,kDAAkD,CAAC;AACjE,cAAc,uCAAuC,CAAC;AACtD,cAAc,8CAA8C,CAAC;AAC7D,cAAc,gDAAgD,CAAC;AAC/D,cAAc,qDAAqD,CAAC;AACpE,cAAc,uDAAuD,CAAC;AACtE,cAAc,oDAAoD,CAAC;AACnE,cAAc,+DAA+D,CAAC;AAC9E,cAAc,uDAAuD,CAAC;AACtE,cAAc,kDAAkD,CAAC;AACjE,cAAc,iDAAiD,CAAC;AAChE,cAAc,uCAAuC,CAAC;AACtD,cAAc,kDAAkD,CAAC;AACjE,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,wCAAwC,CAAC;AACvD,cAAc,2CAA2C,CAAC;AAC1D,cAAc,oDAAoD,CAAC;AACnE,cAAc,2CAA2C,CAAC;AAC1D,cAAc,mDAAmD,CAAC;AAClE,cAAc,sDAAsD,CAAC;AACrE,cAAc,qDAAqD,CAAC;AACpE,cAAc,sCAAsC,CAAC;AACrD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oCAAoC,CAAC;AACnD,cAAc,8BAA8B,CAAC;AAC7C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mCAAmC,CAAC;AAClD,cAAc,eAAe,CAAC;AAE9B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,yCAAyC,CAAC;AACxD,cAAc,qCAAqC,CAAC;AACpD,cAAc,+CAA+C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memberjunction/core-entities-server",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "6.1.0-edge.
|
|
4
|
+
"version": "6.1.0-edge.7",
|
|
5
5
|
"description": "Entity subclasses for the metadata layer of MemberJunction that are only used on server side applications like MJAPI, distributed as part of each release of MemberJunction",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -15,33 +15,33 @@
|
|
|
15
15
|
"typescript": "^5.9.3"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@memberjunction/actions-base": "6.1.0-edge.
|
|
19
|
-
"@memberjunction/ai": "6.1.0-edge.
|
|
20
|
-
"@memberjunction/ai-core-plus": "6.1.0-edge.
|
|
21
|
-
"@memberjunction/ai-engine-base": "6.1.0-edge.
|
|
22
|
-
"@memberjunction/ai-prompts": "6.1.0-edge.
|
|
23
|
-
"@memberjunction/ai-provider-bundle": "6.1.0-edge.
|
|
24
|
-
"@memberjunction/ai-vector-dupe": "6.1.0-edge.
|
|
25
|
-
"@memberjunction/ai-vectordb": "6.1.0-edge.
|
|
26
|
-
"@memberjunction/ai-vectors-memory": "6.1.0-edge.
|
|
27
|
-
"@memberjunction/aiengine": "6.1.0-edge.
|
|
28
|
-
"@memberjunction/core": "6.1.0-edge.
|
|
29
|
-
"@memberjunction/core-entities": "6.1.0-edge.
|
|
30
|
-
"@memberjunction/predictive-studio-core": "6.1.0-edge.
|
|
31
|
-
"@memberjunction/doc-utils": "6.1.0-edge.
|
|
32
|
-
"@memberjunction/generic-database-provider": "6.1.0-edge.
|
|
33
|
-
"@memberjunction/global": "6.1.0-edge.
|
|
34
|
-
"@memberjunction/integration-engine": "6.1.0-edge.
|
|
35
|
-
"@memberjunction/integration-pk-classifier": "6.1.0-edge.
|
|
36
|
-
"@memberjunction/scheduling-engine": "6.1.0-edge.
|
|
37
|
-
"@memberjunction/sql-converter": "6.1.0-edge.
|
|
38
|
-
"@memberjunction/sql-dialect": "6.1.0-edge.
|
|
39
|
-
"@memberjunction/sql-parser": "6.1.0-edge.
|
|
40
|
-
"@memberjunction/sqlserver-dataprovider": "6.1.0-edge.
|
|
41
|
-
"@memberjunction/tag-engine": "6.1.0-edge.
|
|
42
|
-
"@memberjunction/communication-engine": "6.1.0-edge.
|
|
43
|
-
"@memberjunction/communication-types": "6.1.0-edge.
|
|
44
|
-
"@memberjunction/templates": "6.1.0-edge.
|
|
18
|
+
"@memberjunction/actions-base": "6.1.0-edge.7",
|
|
19
|
+
"@memberjunction/ai": "6.1.0-edge.7",
|
|
20
|
+
"@memberjunction/ai-core-plus": "6.1.0-edge.7",
|
|
21
|
+
"@memberjunction/ai-engine-base": "6.1.0-edge.7",
|
|
22
|
+
"@memberjunction/ai-prompts": "6.1.0-edge.7",
|
|
23
|
+
"@memberjunction/ai-provider-bundle": "6.1.0-edge.7",
|
|
24
|
+
"@memberjunction/ai-vector-dupe": "6.1.0-edge.7",
|
|
25
|
+
"@memberjunction/ai-vectordb": "6.1.0-edge.7",
|
|
26
|
+
"@memberjunction/ai-vectors-memory": "6.1.0-edge.7",
|
|
27
|
+
"@memberjunction/aiengine": "6.1.0-edge.7",
|
|
28
|
+
"@memberjunction/core": "6.1.0-edge.7",
|
|
29
|
+
"@memberjunction/core-entities": "6.1.0-edge.7",
|
|
30
|
+
"@memberjunction/predictive-studio-core": "6.1.0-edge.7",
|
|
31
|
+
"@memberjunction/doc-utils": "6.1.0-edge.7",
|
|
32
|
+
"@memberjunction/generic-database-provider": "6.1.0-edge.7",
|
|
33
|
+
"@memberjunction/global": "6.1.0-edge.7",
|
|
34
|
+
"@memberjunction/integration-engine": "6.1.0-edge.7",
|
|
35
|
+
"@memberjunction/integration-pk-classifier": "6.1.0-edge.7",
|
|
36
|
+
"@memberjunction/scheduling-engine": "6.1.0-edge.7",
|
|
37
|
+
"@memberjunction/sql-converter": "6.1.0-edge.7",
|
|
38
|
+
"@memberjunction/sql-dialect": "6.1.0-edge.7",
|
|
39
|
+
"@memberjunction/sql-parser": "6.1.0-edge.7",
|
|
40
|
+
"@memberjunction/sqlserver-dataprovider": "6.1.0-edge.7",
|
|
41
|
+
"@memberjunction/tag-engine": "6.1.0-edge.7",
|
|
42
|
+
"@memberjunction/communication-engine": "6.1.0-edge.7",
|
|
43
|
+
"@memberjunction/communication-types": "6.1.0-edge.7",
|
|
44
|
+
"@memberjunction/templates": "6.1.0-edge.7",
|
|
45
45
|
"nunjucks": "3.2.4",
|
|
46
46
|
"rxjs": "~7.8.1",
|
|
47
47
|
"zod": "^3.25.0"
|