@memberjunction/core-entities 6.2.0-edge.3 → 6.2.0-edge.5
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/.tsbuildinfo +1 -1
- package/dist/custom/ConversationForkAccess.d.ts +15 -0
- package/dist/custom/ConversationForkAccess.d.ts.map +1 -0
- package/dist/custom/ConversationForkAccess.js +28 -0
- package/dist/custom/ConversationForkAccess.js.map +1 -0
- package/dist/custom/ConversationWriteAccess.d.ts +21 -0
- package/dist/custom/ConversationWriteAccess.d.ts.map +1 -0
- package/dist/custom/ConversationWriteAccess.js +34 -0
- package/dist/custom/ConversationWriteAccess.js.map +1 -0
- package/dist/custom/MJConversationBranchEntityExtended.d.ts +30 -0
- package/dist/custom/MJConversationBranchEntityExtended.d.ts.map +1 -0
- package/dist/custom/MJConversationBranchEntityExtended.js +120 -0
- package/dist/custom/MJConversationBranchEntityExtended.js.map +1 -0
- package/dist/custom/MJConversationDetailEntityExtended.d.ts +46 -4
- package/dist/custom/MJConversationDetailEntityExtended.d.ts.map +1 -1
- package/dist/custom/MJConversationDetailEntityExtended.js +194 -47
- package/dist/custom/MJConversationDetailEntityExtended.js.map +1 -1
- package/dist/custom/MJDashboardEntityExtended.d.ts.map +1 -1
- package/dist/custom/MJDashboardEntityExtended.js +3 -0
- package/dist/custom/MJDashboardEntityExtended.js.map +1 -1
- package/dist/custom/MJThemeEntityExtended.d.ts +13 -0
- package/dist/custom/MJThemeEntityExtended.d.ts.map +1 -0
- package/dist/custom/MJThemeEntityExtended.js +37 -0
- package/dist/custom/MJThemeEntityExtended.js.map +1 -0
- package/dist/custom/ResourcePermissions/ResourcePermissionEngine.d.ts.map +1 -1
- package/dist/custom/ResourcePermissions/ResourcePermissionEngine.js +14 -13
- package/dist/custom/ResourcePermissions/ResourcePermissionEngine.js.map +1 -1
- package/dist/engines/FileStorageEngine.d.ts +40 -0
- package/dist/engines/FileStorageEngine.d.ts.map +1 -1
- package/dist/engines/FileStorageEngine.js +49 -0
- package/dist/engines/FileStorageEngine.js.map +1 -1
- package/dist/engines/InstanceConfigEngine.d.ts.map +1 -1
- package/dist/engines/InstanceConfigEngine.js +13 -3
- package/dist/engines/InstanceConfigEngine.js.map +1 -1
- package/dist/engines/PermissionEngine.d.ts +5 -4
- package/dist/engines/PermissionEngine.d.ts.map +1 -1
- package/dist/engines/PermissionEngine.js +7 -5
- package/dist/engines/PermissionEngine.js.map +1 -1
- package/dist/engines/QueryEngine.d.ts +81 -6
- package/dist/engines/QueryEngine.d.ts.map +1 -1
- package/dist/engines/QueryEngine.js +283 -4
- package/dist/engines/QueryEngine.js.map +1 -1
- package/dist/engines/UserInfoEngine.d.ts +64 -12
- package/dist/engines/UserInfoEngine.d.ts.map +1 -1
- package/dist/engines/UserInfoEngine.js +100 -33
- package/dist/engines/UserInfoEngine.js.map +1 -1
- package/dist/engines/artifacts.d.ts.map +1 -1
- package/dist/engines/artifacts.js +1 -0
- package/dist/engines/artifacts.js.map +1 -1
- package/dist/engines/conversations.d.ts +378 -35
- package/dist/engines/conversations.d.ts.map +1 -1
- package/dist/engines/conversations.js +736 -79
- package/dist/engines/conversations.js.map +1 -1
- package/dist/generated/entities/__mj.d.ts +3488 -230
- package/dist/generated/entities/__mj.d.ts.map +1 -1
- package/dist/generated/entities/__mj.js +2927 -18
- package/dist/generated/entities/__mj.js.map +1 -1
- package/dist/generated/remote_operations.d.ts +17 -5
- package/dist/generated/remote_operations.d.ts.map +1 -1
- package/dist/generated/remote_operations.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +6 -5
- package/readme.md +1 -1
|
@@ -4,12 +4,10 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { BaseEntity, BaseEntityResult, LogError } from '@memberjunction/core';
|
|
7
|
+
import { BaseEntity, BaseEntityResult, EntityFieldInfo, LogError, WellKnownUserSource } from '@memberjunction/core';
|
|
8
8
|
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
9
9
|
import { MJConversationDetailEntity } from '../generated/entity_subclasses.js';
|
|
10
|
-
import {
|
|
11
|
-
/** `MJ: Resource Types.ID` for Conversations — seeded in the resource type catalog. */
|
|
12
|
-
const CONVERSATIONS_RESOURCE_TYPE_ID = '81D4BC3D-9FEB-EF11-B01A-286B35C04427';
|
|
10
|
+
import { UserMayWriteConversation } from './ConversationWriteAccess.js';
|
|
13
11
|
/**
|
|
14
12
|
* Fields that represent the conversation owner's evaluation of an AI message.
|
|
15
13
|
* Storage is a single value per message (no per-user rating column), so only
|
|
@@ -17,6 +15,34 @@ const CONVERSATIONS_RESOURCE_TYPE_ID = '81D4BC3D-9FEB-EF11-B01A-286B35C04427';
|
|
|
17
15
|
* the parent conversation cannot retroactively rewrite the owner's rating.
|
|
18
16
|
*/
|
|
19
17
|
const OWNER_ONLY_RATING_FIELDS = ['UserRating', 'UserFeedback'];
|
|
18
|
+
/**
|
|
19
|
+
* The fields of a person's (`Role='User'`) message that say who wrote it and what it says: its author, its role, its
|
|
20
|
+
* text, its attachment, its media type and where it sits in a thread. Only its author may change them, except
|
|
21
|
+
* `Role`, which no one may change. Other fields (pinning, hiding, bookkeeping the server writes) keep the
|
|
22
|
+
* conversation-level rules.
|
|
23
|
+
*/
|
|
24
|
+
const AUTHORED_FIELDS = ['UserID', 'Role', 'Message', 'ArtifactID', 'ArtifactVersionID', 'MediaType', 'ParentID'];
|
|
25
|
+
/**
|
|
26
|
+
* Where a message sits: its conversation and its fork (`BranchID`, null is Main). No one moves a person's message,
|
|
27
|
+
* its author included: moving it takes it out of the thread it was written in.
|
|
28
|
+
*/
|
|
29
|
+
const PLACEMENT_FIELDS = ['ConversationID', 'BranchID'];
|
|
30
|
+
/**
|
|
31
|
+
* The fields the access rule, which holds for everyone, decides on: which row is written (`ID`; an update's SQL is
|
|
32
|
+
* rebuilt with the variable's value at submit, so it would write another row), its conversation, and the owner's
|
|
33
|
+
* rating. A transaction variable sets its field at submit, after the gate has run, so none of these may take its
|
|
34
|
+
* value from one.
|
|
35
|
+
*/
|
|
36
|
+
const ACCESS_GATED_FIELDS = ['ID', 'ConversationID', ...OWNER_ONLY_RATING_FIELDS];
|
|
37
|
+
/** {@link ACCESS_GATED_FIELDS} plus the fields the authorship rules decide on, which the system user skips. */
|
|
38
|
+
const GATED_FIELDS = [...ACCESS_GATED_FIELDS, 'BranchID', ...AUTHORED_FIELDS];
|
|
39
|
+
/**
|
|
40
|
+
* Whether a `Role` value is a person's message. Compared the way validation and the database's CHECK constraint
|
|
41
|
+
* compare it (trimmed, any case), so `'user'` or `'User '`, which both store, cannot slip past these rules.
|
|
42
|
+
*/
|
|
43
|
+
function isPersonRole(role) {
|
|
44
|
+
return role != null && EntityFieldInfo.NormalizeValueListValue(role) === 'user';
|
|
45
|
+
}
|
|
20
46
|
/**
|
|
21
47
|
* Server-side defense-in-depth for conversation sharing. The Angular chat UI
|
|
22
48
|
* disables the message input when the current user only holds `View` access,
|
|
@@ -32,6 +58,22 @@ const OWNER_ONLY_RATING_FIELDS = ['UserRating', 'UserFeedback'];
|
|
|
32
58
|
* owner-only — even users with `Edit`-level grants on the conversation are
|
|
33
59
|
* blocked from changing them, because the storage is a single value per
|
|
34
60
|
* message (it represents the owner's evaluation, not per-grantee opinions).
|
|
61
|
+
*
|
|
62
|
+
* **Who a message is from** (A19, the rules for people's messages). For a `Role='User'` message, the owner and
|
|
63
|
+
* grantees alike:
|
|
64
|
+
* - post only as themselves: a new message naming another person's `UserID` is refused, and a grantee's message
|
|
65
|
+
* with no `UserID` gets the grantee's (an empty one reads as the conversation's owner). The owner's stays empty,
|
|
66
|
+
* since it already means them;
|
|
67
|
+
* - change who wrote it and what it says ({@link AUTHORED_FIELDS}) only when they wrote it, and never its role;
|
|
68
|
+
* - never move it to another conversation or fork ({@link PLACEMENT_FIELDS});
|
|
69
|
+
* - delete it only when they wrote it, or own the conversation.
|
|
70
|
+
*
|
|
71
|
+
* The system user is exempt from these authorship rules, since server code writes on people's behalf, but it still
|
|
72
|
+
* needs to own the conversation or hold a grant on it, as before: some server paths elevate an anonymous visitor to
|
|
73
|
+
* the system user (MJ#4791), and this gate keeps those paths out of other people's conversations, so no transaction
|
|
74
|
+
* variable may set the row or conversation it writes ({@link ACCESS_GATED_FIELDS}) for it either. The plan's "the
|
|
75
|
+
* system user may write any message" lands with A19's second half, which must design that boundary. Agent replies
|
|
76
|
+
* (`Role='AI'`/`'Error'`) keep today's rules until MJ's chat stops writing them from the browser.
|
|
35
77
|
* MJ's permissions engine has no native primitive for per-field row-conditional
|
|
36
78
|
* write rules, so this gate lives here rather than in `MJ: Entity Permissions`.
|
|
37
79
|
*
|
|
@@ -42,10 +84,15 @@ const OWNER_ONLY_RATING_FIELDS = ['UserRating', 'UserFeedback'];
|
|
|
42
84
|
*/
|
|
43
85
|
let MJConversationDetailEntityExtended = class MJConversationDetailEntityExtended extends MJConversationDetailEntity {
|
|
44
86
|
async Save(options) {
|
|
87
|
+
const callerUserID = this.UserID; // the gate may fill in a grantee's; a save that fails keeps the caller's
|
|
45
88
|
if (!(await this.currentUserMayWrite('save'))) {
|
|
46
89
|
return false;
|
|
47
90
|
}
|
|
48
|
-
|
|
91
|
+
const saved = await super.Save(options);
|
|
92
|
+
if (!saved) {
|
|
93
|
+
this.UserID = callerUserID;
|
|
94
|
+
}
|
|
95
|
+
return saved;
|
|
49
96
|
}
|
|
50
97
|
async Delete(options) {
|
|
51
98
|
if (!(await this.currentUserMayWrite('delete'))) {
|
|
@@ -65,40 +112,34 @@ let MJConversationDetailEntityExtended = class MJConversationDetailEntityExtende
|
|
|
65
112
|
// No user context on a server save = system operation; allow.
|
|
66
113
|
return true;
|
|
67
114
|
}
|
|
115
|
+
// The system user skips the authorship rules (server code writes on people's behalf) but, like anyone, must own
|
|
116
|
+
// the conversation or hold a grant on it: some server paths elevate an anonymous visitor to the system user
|
|
117
|
+
// (MJ#4791), and this gate is what keeps those paths out of other people's conversations.
|
|
118
|
+
const isSystemUser = WellKnownUserSource.Instance.IsSystemUser(user);
|
|
119
|
+
if (operation === 'save' && this.fieldSetByTransactionVariable(isSystemUser ? ACCESS_GATED_FIELDS : GATED_FIELDS)) {
|
|
120
|
+
// A transaction variable sets its field after this check has passed, at submit, to any value an earlier
|
|
121
|
+
// item in the group produced: a message would be checked as one row, author or conversation and saved as
|
|
122
|
+
// another.
|
|
123
|
+
this.recordDenied('A conversation message cannot take its values from a transaction variable.', resultType);
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
// A message created by the record-cloning engine, as part of copying a conversation into a
|
|
127
|
+
// new user's account. The engine has already authorized that copy (Owner-only, the clone
|
|
128
|
+
// authorization, and conversations are copyable only from a template user), and the
|
|
129
|
+
// conversation it lands in belongs to the new user, not to whoever runs the clone. Only
|
|
130
|
+
// creates qualify: updating or deleting an existing message keeps the checks below.
|
|
131
|
+
if (resultType === 'create' && this.CloneContext) {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
68
134
|
try {
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
const isOwner = !!conversation.UserID && UUIDsEqual(conversation.UserID, user.ID);
|
|
76
|
-
if (isOwner) {
|
|
77
|
-
return true;
|
|
78
|
-
}
|
|
79
|
-
// Non-owners are *never* allowed to touch the rating fields, even
|
|
80
|
-
// when they hold Edit/Owner grants on the conversation. UserRating
|
|
81
|
-
// and UserFeedback represent the owner's evaluation of an AI
|
|
82
|
-
// message and there is no per-user storage to overwrite.
|
|
83
|
-
if (this.dirtyRatingFieldNames().length > 0) {
|
|
84
|
-
this.recordDenied('Only the conversation owner can set or change the rating and feedback on this message.', resultType);
|
|
135
|
+
const access = await UserMayWriteConversation(provider, user, this.ConversationID);
|
|
136
|
+
const refusal = (await this.accessRefusal(provider, access))
|
|
137
|
+
?? (isSystemUser ? null : this.authorshipRefusal(operation, user, access.IsOwner));
|
|
138
|
+
if (refusal) {
|
|
139
|
+
this.recordDenied(refusal, resultType);
|
|
85
140
|
return false;
|
|
86
141
|
}
|
|
87
|
-
|
|
88
|
-
await engine.Config(false, user);
|
|
89
|
-
const grant = engine
|
|
90
|
-
.GetUserAvailableResources(user, CONVERSATIONS_RESOURCE_TYPE_ID)
|
|
91
|
-
.find((p) => UUIDsEqual(p.ResourceRecordID, this.ConversationID));
|
|
92
|
-
if (!grant) {
|
|
93
|
-
this.recordDenied('You do not have access to this conversation.', resultType);
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
96
|
-
if (grant.PermissionLevel === 'Edit' || grant.PermissionLevel === 'Owner') {
|
|
97
|
-
return true;
|
|
98
|
-
}
|
|
99
|
-
// Only View — block writes.
|
|
100
|
-
this.recordDenied('You have view-only access to this conversation.', resultType);
|
|
101
|
-
return false;
|
|
142
|
+
return true;
|
|
102
143
|
}
|
|
103
144
|
catch (error) {
|
|
104
145
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -110,18 +151,124 @@ let MJConversationDetailEntityExtended = class MJConversationDetailEntityExtende
|
|
|
110
151
|
}
|
|
111
152
|
}
|
|
112
153
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
154
|
+
* Why the user may not write to this message's conversation at all, or `null` when they may. The owner may. Anyone
|
|
155
|
+
* else may not change the rating fields, which are the owner's alone, and needs an `Edit` or `Owner` grant. A
|
|
156
|
+
* conversation that does not load for the user is hidden from them when it exists (a row filter), and they may not
|
|
157
|
+
* write to it; when no one can find it, it is missing or being created in this same transaction, and the foreign
|
|
158
|
+
* key and the base save decide, as before.
|
|
159
|
+
*/
|
|
160
|
+
async accessRefusal(provider, access) {
|
|
161
|
+
if (access.IsOwner) {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
// Non-owners are *never* allowed to touch the rating fields, even
|
|
165
|
+
// when they hold Edit/Owner grants on the conversation. UserRating
|
|
166
|
+
// and UserFeedback represent the owner's evaluation of an AI
|
|
167
|
+
// message and there is no per-user storage to overwrite.
|
|
168
|
+
if (OWNER_ONLY_RATING_FIELDS.some((name) => this.isFieldDirty(name))) {
|
|
169
|
+
return 'Only the conversation owner can set or change the rating and feedback on this message.';
|
|
170
|
+
}
|
|
171
|
+
if (!access.Allowed) {
|
|
172
|
+
return access.Reason ?? 'Permission denied.';
|
|
173
|
+
}
|
|
174
|
+
if (!access.Loaded && (await this.conversationExists(provider))) {
|
|
175
|
+
return 'You do not have access to this conversation.';
|
|
176
|
+
}
|
|
177
|
+
return null;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Why this write breaks the rules for people's messages (see the class doc), or `null` when it does not. On a new
|
|
181
|
+
* message from a grantee with no `UserID`, fills in the grantee's.
|
|
182
|
+
*/
|
|
183
|
+
authorshipRefusal(operation, user, isOwner) {
|
|
184
|
+
if (operation === 'delete') {
|
|
185
|
+
return this.deleteRefusal(user, isOwner);
|
|
186
|
+
}
|
|
187
|
+
return this.IsSaved ? this.changeRefusal(user, isOwner) : this.postRefusal(user, isOwner);
|
|
188
|
+
}
|
|
189
|
+
/** A new person's message names its author as the poster, or names no one (filled in for a grantee). */
|
|
190
|
+
postRefusal(user, isOwner) {
|
|
191
|
+
if (!isPersonRole(this.Role)) {
|
|
192
|
+
return null;
|
|
193
|
+
}
|
|
194
|
+
if (!this.UserID) {
|
|
195
|
+
// An empty UserID reads as the conversation's owner. A grantee's message gets the grantee's ID; the
|
|
196
|
+
// owner's stays empty, so server code writing as the owner (a room transcript of what other people said)
|
|
197
|
+
// is not stamped with the owner's ID.
|
|
198
|
+
if (!isOwner) {
|
|
199
|
+
this.UserID = user.ID;
|
|
200
|
+
}
|
|
201
|
+
return null;
|
|
202
|
+
}
|
|
203
|
+
return UUIDsEqual(this.UserID, user.ID) ? null : 'You can post a message only as yourself.';
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* An existing person's message: only its author changes who wrote it and what it says, no one its role (to or
|
|
207
|
+
* from `User`), and no one moves it to another conversation or fork. A message with no `UserID` is the owner's.
|
|
208
|
+
*/
|
|
209
|
+
changeRefusal(user, isOwner) {
|
|
210
|
+
const wasPerson = isPersonRole(this.originalFieldText('Role'));
|
|
211
|
+
if (this.isFieldDirty('Role') && (wasPerson || isPersonRole(this.Role))) {
|
|
212
|
+
return "A message's role cannot be changed.";
|
|
213
|
+
}
|
|
214
|
+
if (!wasPerson) {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
if (PLACEMENT_FIELDS.some((name) => this.isFieldDirty(name))) {
|
|
218
|
+
// Moving it would take it out of the thread it was written in (a delete) and put it in one its author never
|
|
219
|
+
// wrote in, and, with no UserID, make it read as another conversation's owner's.
|
|
220
|
+
return 'A message cannot be moved to another conversation or fork.';
|
|
221
|
+
}
|
|
222
|
+
const changed = AUTHORED_FIELDS.filter((name) => this.isFieldDirty(name));
|
|
223
|
+
if (changed.length === 0) {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
const author = this.originalFieldText('UserID') ?? (isOwner ? user.ID : null);
|
|
227
|
+
if (!author || !UUIDsEqual(author, user.ID)) {
|
|
228
|
+
return 'Only the person who wrote this message can change it.';
|
|
229
|
+
}
|
|
230
|
+
if (changed.includes('UserID') && !(this.UserID && UUIDsEqual(this.UserID, user.ID))) {
|
|
231
|
+
return 'You can post a message only as yourself.';
|
|
232
|
+
}
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
/** A person's message is deleted by its author or by the conversation's owner (whose it is with no `UserID`). */
|
|
236
|
+
deleteRefusal(user, isOwner) {
|
|
237
|
+
if (!isPersonRole(this.Role) || isOwner) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
return this.UserID && UUIDsEqual(this.UserID, user.ID)
|
|
241
|
+
? null
|
|
242
|
+
: "Only the message's author or the conversation's owner can delete it.";
|
|
243
|
+
}
|
|
244
|
+
/** Whether the conversation exists, read as the system user; false when there is no system user to ask. */
|
|
245
|
+
async conversationExists(provider) {
|
|
246
|
+
const systemUser = await WellKnownUserSource.Instance.GetSystemUser(provider);
|
|
247
|
+
if (!systemUser) {
|
|
248
|
+
LogError(`MJConversationDetailEntityExtended: no system user to check whether conversation ${this.ConversationID} ` +
|
|
249
|
+
'exists; treating it as missing.');
|
|
250
|
+
return false;
|
|
251
|
+
}
|
|
252
|
+
const conversation = await provider.GetEntityObject('MJ: Conversations', systemUser);
|
|
253
|
+
return conversation.Load(this.ConversationID);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Whether a transaction variable of this message's group sets one of `fields` on it. The field is resolved the way
|
|
257
|
+
* `Set` resolves it at submit (trimmed, any case).
|
|
116
258
|
*/
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return
|
|
259
|
+
fieldSetByTransactionVariable(fields) {
|
|
260
|
+
return !!this.TransactionGroup?.Variables.some((v) => {
|
|
261
|
+
const name = v.EntityObject === this && v.Type === 'Use' ? this.GetFieldByName(v.FieldName)?.Name : null;
|
|
262
|
+
return !!name && fields.includes(name);
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
isFieldDirty(name) {
|
|
266
|
+
return !!this.GetFieldByName(name)?.Dirty;
|
|
267
|
+
}
|
|
268
|
+
/** A field's value as loaded, before this save's changes; `null` when it was empty or is not text. */
|
|
269
|
+
originalFieldText(name) {
|
|
270
|
+
const original = this.GetFieldByName(name)?.OldValue;
|
|
271
|
+
return typeof original === 'string' && original.length > 0 ? original : null;
|
|
125
272
|
}
|
|
126
273
|
/**
|
|
127
274
|
* Records WHY the write was refused as a NEW `ResultHistory` entry, so callers that read
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJConversationDetailEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJConversationDetailEntityExtended.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACH,UAAU,EACV,gBAAgB,
|
|
1
|
+
{"version":3,"file":"MJConversationDetailEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJConversationDetailEntityExtended.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJDashboardEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJDashboardEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,mBAAmB,EAA+B,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAkD,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AA+CnE,qBACa,yBAA0B,SAAQ,iBAAiB;IACrD,SAAS,IAAI,OAAO;
|
|
1
|
+
{"version":3,"file":"MJDashboardEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJDashboardEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,mBAAmB,EAA+B,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAkD,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AA+CnE,qBACa,yBAA0B,SAAQ,iBAAiB;IACrD,SAAS,IAAI,OAAO;IA+B3B;;;;OAIG;IACa,QAAQ,IAAI,gBAAgB;IA8G5C;;;OAGG;IACmB,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;CAiDhF"}
|
|
@@ -64,9 +64,12 @@ let MJDashboardEntityExtended = class MJDashboardEntityExtended extends MJDashbo
|
|
|
64
64
|
};
|
|
65
65
|
const configJSON = JSON.stringify(defaultConfigDetails);
|
|
66
66
|
this.Set("UIConfigDetails", configJSON);
|
|
67
|
+
// Re-arm the first set, so a later load sets both the value and the old value
|
|
68
|
+
this.GetFieldByName("UIConfigDetails")?.ResetNeverSetFlag();
|
|
67
69
|
const md = this.ProviderToUse;
|
|
68
70
|
if (md.CurrentUser) {
|
|
69
71
|
this.Set("UserID", md.CurrentUser.ID);
|
|
72
|
+
this.GetFieldByName("UserID")?.ResetNeverSetFlag();
|
|
70
73
|
}
|
|
71
74
|
return true;
|
|
72
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJDashboardEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJDashboardEntityExtended.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAA0C,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACpG,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,mBAAmB,EAAoB,MAAM,wBAAwB,CAAC;AAC1G,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,SAAS,eAAe,CAAC,MAAyB;IAC9C,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,kBAAkB,EAAE,CAAC;QACzC,mFAAmF;QACnF,iFAAiF;QACjF,qDAAqD;QACrD,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,KAAK,EAAE,QAAQ,CAAC;IAClC,OAAO,OAAO,SAAS,KAAK,QAAQ,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;AAC7F,CAAC;AAGM,IAAM,yBAAyB,GAA/B,MAAM,yBAA0B,SAAQ,iBAAiB;IACrD,SAAS;QACZ,IAAG,CAAC;YACA,KAAK,CAAC,SAAS,EAAE,CAAC;YAClB,MAAM,oBAAoB,GAAG;gBACzB,OAAO,EAAE,CAAC;gBACV,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,IAAI;gBACf,WAAW,EAAE,IAAI;gBACjB,KAAK,EAAE,EAAE;aACZ,CAAA;YAED,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;YACxD,IAAI,CAAC,GAAG,CAAC,iBAAiB,EAAE,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"MJDashboardEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJDashboardEntityExtended.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type ValidationResult } from '@memberjunction/core';
|
|
2
|
+
import { MJThemeEntity } from '../generated/entity_subclasses.js';
|
|
3
|
+
/**
|
|
4
|
+
* `MJ: Themes`: refuses a sign-in page design (`LoginScreen`, `LoginScreenDraft`) the login screen cannot
|
|
5
|
+
* draw safely. Runs on both tiers, so Login Studio hears the reason before the request leaves the browser.
|
|
6
|
+
* Only a column this save changes is checked, so a theme whose stored design predates a stricter contract
|
|
7
|
+
* can still be renamed or recolored.
|
|
8
|
+
*/
|
|
9
|
+
export declare class MJThemeEntityExtended extends MJThemeEntity {
|
|
10
|
+
Validate(): ValidationResult;
|
|
11
|
+
private checkLoginDesign;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=MJThemeEntityExtended.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJThemeEntityExtended.d.ts","sourceRoot":"","sources":["../../src/custom/MJThemeEntityExtended.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwD,KAAK,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAGnH,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D;;;;;GAKG;AACH,qBACa,qBAAsB,SAAQ,aAAa;IACpC,QAAQ,IAAI,gBAAgB;IAQ5C,OAAO,CAAC,gBAAgB;CAM3B"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { BaseEntity, ValidationErrorInfo, ValidationErrorType } from '@memberjunction/core';
|
|
8
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
+
import { StoredLoginDesignProblems } from '@memberjunction/theme-engine';
|
|
10
|
+
import { MJThemeEntity } from '../generated/entity_subclasses.js';
|
|
11
|
+
/**
|
|
12
|
+
* `MJ: Themes`: refuses a sign-in page design (`LoginScreen`, `LoginScreenDraft`) the login screen cannot
|
|
13
|
+
* draw safely. Runs on both tiers, so Login Studio hears the reason before the request leaves the browser.
|
|
14
|
+
* Only a column this save changes is checked, so a theme whose stored design predates a stricter contract
|
|
15
|
+
* can still be renamed or recolored.
|
|
16
|
+
*/
|
|
17
|
+
let MJThemeEntityExtended = class MJThemeEntityExtended extends MJThemeEntity {
|
|
18
|
+
Validate() {
|
|
19
|
+
const result = super.Validate();
|
|
20
|
+
this.checkLoginDesign(result, 'LoginScreen', this.LoginScreen);
|
|
21
|
+
this.checkLoginDesign(result, 'LoginScreenDraft', this.LoginScreenDraft);
|
|
22
|
+
result.Success = result.Errors.every((e) => e.Type !== ValidationErrorType.Failure);
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
checkLoginDesign(result, field, value) {
|
|
26
|
+
if (!this.GetFieldByName(field)?.Dirty)
|
|
27
|
+
return;
|
|
28
|
+
for (const problem of StoredLoginDesignProblems(value)) {
|
|
29
|
+
result.Errors.push(new ValidationErrorInfo(field, problem, null, ValidationErrorType.Failure));
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
MJThemeEntityExtended = __decorate([
|
|
34
|
+
RegisterClass(BaseEntity, 'MJ: Themes')
|
|
35
|
+
], MJThemeEntityExtended);
|
|
36
|
+
export { MJThemeEntityExtended };
|
|
37
|
+
//# sourceMappingURL=MJThemeEntityExtended.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJThemeEntityExtended.js","sourceRoot":"","sources":["../../src/custom/MJThemeEntityExtended.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,EAAyB,MAAM,sBAAsB,CAAC;AACnH,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAE/D;;;;;GAKG;AAEI,IAAM,qBAAqB,GAA3B,MAAM,qBAAsB,SAAQ,aAAa;IACpC,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAC/D,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,kBAAkB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC;QACzE,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,mBAAmB,CAAC,OAAO,CAAC,CAAC;QACpF,OAAO,MAAM,CAAC;IAClB,CAAC;IAEO,gBAAgB,CAAC,MAAwB,EAAE,KAAyC,EAAE,KAAoB;QAC9G,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK;YAAE,OAAO;QAC/C,KAAK,MAAM,OAAO,IAAI,yBAAyB,CAAC,KAAK,CAAC,EAAE,CAAC;YACrD,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QACnG,CAAC;IACL,CAAC;CACJ,CAAA;AAfY,qBAAqB;IADjC,aAAa,CAAC,UAAU,EAAE,YAAY,CAAC;GAC3B,qBAAqB,CAejC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResourcePermissionEngine.d.ts","sourceRoot":"","sources":["../../../src/custom/ResourcePermissions/ResourcePermissionEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,EAAoC,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE3I,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAErG;;GAEG;AACH,qBACa,wBAAyB,SAAQ,UAAU,CAAC,wBAAwB,CAAC;IAC9E;;OAEG;IACH,WAAkB,QAAQ,IAAI,wBAAwB,CAErD;IAED,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,cAAc,CAEpB;IAEW,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB;IAkBhG,IAAW,aAAa,IAAI,oBAAoB,EAAE,CAEjD;IAED,IAAW,WAAW,IAAI,0BAA0B,EAAE,CAErD;IAED;;;;;OAKG;IACI,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI;IAQ3E;;;;;;OAMG;IACI,sBAAsB,CAAC,cAAc,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,0BAA0B,EAAE;IAI7G;;;;;;;;;;;;;;;;;;OAkBG;IACI,8BAA8B,CACjC,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,QAAQ,GACf,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI;IAiCnC;;;;;;OAMG;IACI,yBAAyB,CAAC,IAAI,EAAE,QAAQ,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,0BAA0B,EAAE;
|
|
1
|
+
{"version":3,"file":"ResourcePermissionEngine.d.ts","sourceRoot":"","sources":["../../../src/custom/ResourcePermissions/ResourcePermissionEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,EAAoC,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE3I,OAAO,EAAE,0BAA0B,EAAE,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AAErG;;GAEG;AACH,qBACa,wBAAyB,SAAQ,UAAU,CAAC,wBAAwB,CAAC;IAC9E;;OAEG;IACH,WAAkB,QAAQ,IAAI,wBAAwB,CAErD;IAED,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,cAAc,CAEpB;IAEW,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB;IAkBhG,IAAW,aAAa,IAAI,oBAAoB,EAAE,CAEjD;IAED,IAAW,WAAW,IAAI,0BAA0B,EAAE,CAErD;IAED;;;;;OAKG;IACI,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI;IAQ3E;;;;;;OAMG;IACI,sBAAsB,CAAC,cAAc,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,0BAA0B,EAAE;IAI7G;;;;;;;;;;;;;;;;;;OAkBG;IACI,8BAA8B,CACjC,cAAc,EAAE,MAAM,EACtB,gBAAgB,EAAE,MAAM,EACxB,IAAI,EAAE,QAAQ,GACf,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI;IAiCnC;;;;;;OAMG;IACI,yBAAyB,CAAC,IAAI,EAAE,QAAQ,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,0BAA0B,EAAE;IAwCvG;;;;OAIG;IACI,yBAAyB,CAAC,cAAc,EAAE,MAAM,GAAG;QAAC,gBAAgB,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,mBAAmB,EAAE,MAAM,CAAA;KAAC;CAoB3I"}
|
|
@@ -5,7 +5,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { BaseEngine, RegisterForStartup } from "@memberjunction/core";
|
|
8
|
-
import { UUIDsEqual } from "@memberjunction/global";
|
|
8
|
+
import { NormalizeUUID, UUIDsEqual } from "@memberjunction/global";
|
|
9
9
|
/**
|
|
10
10
|
* Resource Permission Engine is used for accessing metadata about permissions for resources and also determining if a user has access to a resource and at what level.
|
|
11
11
|
*/
|
|
@@ -128,15 +128,18 @@ let ResourcePermissionEngine = class ResourcePermissionEngine extends BaseEngine
|
|
|
128
128
|
permissions = permissions.concat(rolePermissions);
|
|
129
129
|
// now filter to ONLY approved permissions
|
|
130
130
|
permissions = permissions.filter((r) => r.Status === 'Approved');
|
|
131
|
-
// now, we reduce the array so that we only have the highest permission level for each resourcetypeid/resourcerecordid combination
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
131
|
+
// now, we reduce the array so that we only have the highest permission level for each resourcetypeid/resourcerecordid combination.
|
|
132
|
+
// Keyed by the normalized pair so this stays linear; a swap deletes and re-adds the key, which moves the
|
|
133
|
+
// winner to the end exactly as removing it from an array and pushing the new one did.
|
|
134
|
+
const reducedPermissions = new Map();
|
|
135
|
+
for (const p of permissions) {
|
|
136
|
+
const key = `${NormalizeUUID(p.ResourceTypeID)}|${NormalizeUUID(p.ResourceRecordID)}`;
|
|
137
|
+
const existing = reducedPermissions.get(key);
|
|
135
138
|
if (!existing) {
|
|
136
|
-
reducedPermissions.
|
|
139
|
+
reducedPermissions.set(key, p);
|
|
137
140
|
}
|
|
138
141
|
else {
|
|
139
|
-
// existing permission and see if this one is higher, if so, replace it
|
|
142
|
+
// existing permission and see if this one is higher, if so, replace it with the new one
|
|
140
143
|
let bSwap = false;
|
|
141
144
|
if (p.PermissionLevel === 'Owner' && existing.PermissionLevel !== 'Owner') {
|
|
142
145
|
bSwap = true;
|
|
@@ -145,14 +148,12 @@ let ResourcePermissionEngine = class ResourcePermissionEngine extends BaseEngine
|
|
|
145
148
|
bSwap = true;
|
|
146
149
|
}
|
|
147
150
|
if (bSwap) {
|
|
148
|
-
|
|
149
|
-
reducedPermissions
|
|
150
|
-
// add the new permission
|
|
151
|
-
reducedPermissions.push(p);
|
|
151
|
+
reducedPermissions.delete(key);
|
|
152
|
+
reducedPermissions.set(key, p);
|
|
152
153
|
}
|
|
153
154
|
}
|
|
154
|
-
}
|
|
155
|
-
return reducedPermissions;
|
|
155
|
+
}
|
|
156
|
+
return [...reducedPermissions.values()];
|
|
156
157
|
}
|
|
157
158
|
/**
|
|
158
159
|
* This method will use the MJ metadata to find the fields names for the fields that represent the OwnerID and the Name of the resource in the given resource type.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResourcePermissionEngine.js","sourceRoot":"","sources":["../../../src/custom/ResourcePermissions/ResourcePermissionEngine.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAA6D,kBAAkB,EAAY,MAAM,sBAAsB,CAAC;AAC3I,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"ResourcePermissionEngine.js","sourceRoot":"","sources":["../../../src/custom/ResourcePermissions/ResourcePermissionEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,18 @@ export interface StorageAccountWithProvider {
|
|
|
7
7
|
account: MJFileStorageAccountEntity;
|
|
8
8
|
provider: MJFileStorageProviderEntity;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Outcome of {@link FileStorageEngineBase.ResolveDefaultAccount}: which account the system-wide
|
|
12
|
+
* fallback chose, and whether the choice was ambiguous (so callers can warn in their own terms).
|
|
13
|
+
*/
|
|
14
|
+
export interface DefaultStorageAccountResolution {
|
|
15
|
+
/** The chosen account, or `null` when there were no candidates. */
|
|
16
|
+
Chosen: StorageAccountWithProvider | null;
|
|
17
|
+
/** Every candidate considered, ordered newest `__mj_UpdatedAt` first (ties by ID). */
|
|
18
|
+
Candidates: StorageAccountWithProvider[];
|
|
19
|
+
/** `true` when two or more candidates existed, so the choice fell to the tie-breaker. */
|
|
20
|
+
Ambiguous: boolean;
|
|
21
|
+
}
|
|
10
22
|
/**
|
|
11
23
|
* FileStorageEngineBase provides centralized, cached access to file storage accounts and providers.
|
|
12
24
|
* This engine eliminates redundant database calls by caching the data and making it available
|
|
@@ -53,6 +65,34 @@ export declare class FileStorageEngineBase extends BaseEngine<FileStorageEngineB
|
|
|
53
65
|
* Consumers should filter/sort as needed (e.g., by provider.IsActive).
|
|
54
66
|
*/
|
|
55
67
|
get AccountsWithProviders(): StorageAccountWithProvider[];
|
|
68
|
+
/**
|
|
69
|
+
* Gets storage accounts whose provider is active — the accounts files can actually be written to.
|
|
70
|
+
*/
|
|
71
|
+
get ActiveAccounts(): StorageAccountWithProvider[];
|
|
72
|
+
/**
|
|
73
|
+
* Picks the storage account to use when no caller-specific default is configured. This is the
|
|
74
|
+
* single golden path for "which account, if nobody said?" — agents, actions and UI should all use it
|
|
75
|
+
* so they agree.
|
|
76
|
+
*
|
|
77
|
+
* - No candidates → `Chosen` is `null`.
|
|
78
|
+
* - One candidate → that account.
|
|
79
|
+
* - Two or more → the account with the most recent `__mj_UpdatedAt`, exact ties broken by ID
|
|
80
|
+
* (case-insensitive) so the choice is stable across processes; `Ambiguous` is `true`.
|
|
81
|
+
*
|
|
82
|
+
* Works only on cached metadata (no database calls) and does not log — callers decide how to
|
|
83
|
+
* surface an ambiguous choice.
|
|
84
|
+
*
|
|
85
|
+
* @param candidates - Accounts to choose among; defaults to {@link ActiveAccounts}.
|
|
86
|
+
*/
|
|
87
|
+
ResolveDefaultAccount(candidates?: StorageAccountWithProvider[]): DefaultStorageAccountResolution;
|
|
88
|
+
/**
|
|
89
|
+
* Convenience form of {@link ResolveDefaultAccount} that returns just the chosen account's ID.
|
|
90
|
+
* @param candidates - Accounts to choose among; defaults to {@link ActiveAccounts}.
|
|
91
|
+
* @returns The chosen account ID, or `null` when there are no candidates.
|
|
92
|
+
*/
|
|
93
|
+
ResolveDefaultAccountID(candidates?: StorageAccountWithProvider[]): string | null;
|
|
94
|
+
/** Orders newest `__mj_UpdatedAt` first, breaking exact ties by ID (case-insensitive). */
|
|
95
|
+
private static compareNewestFirst;
|
|
56
96
|
/**
|
|
57
97
|
* Gets a file storage account by its ID
|
|
58
98
|
* @param accountId - The ID of the account to find
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileStorageEngine.d.ts","sourceRoot":"","sources":["../../src/engines/FileStorageEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEzG,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAEzG;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,0BAA0B,CAAC;IACpC,QAAQ,EAAE,2BAA2B,CAAC;CACzC;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,qBAAsB,SAAQ,UAAU,CAAC,qBAAqB,CAAC;IACxE;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,qBAAqB,CAElD;IAED,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;;OAKG;IACU,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhH;;OAEG;IACH,IAAW,QAAQ,IAAI,0BAA0B,EAAE,CAElD;IAED;;;OAGG;IACH,IAAW,SAAS,IAAI,2BAA2B,EAAE,CAEpD;IAED;;;OAGG;IACH,IAAW,qBAAqB,IAAI,0BAA0B,EAAE,CAQ/D;IAMD;;;;OAIG;IACI,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAIhF;;;;OAIG;IACI,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,2BAA2B,GAAG,SAAS;IAInF;;;;OAIG;IACI,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAI7E;;;;OAIG;IACI,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,EAAE;IAIhF;;;;OAIG;IACI,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI;CAOtF"}
|
|
1
|
+
{"version":3,"file":"FileStorageEngine.d.ts","sourceRoot":"","sources":["../../src/engines/FileStorageEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA4B,iBAAiB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAEzG,OAAO,EAAE,0BAA0B,EAAE,2BAA2B,EAAE,MAAM,gCAAgC,CAAC;AAEzG;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACvC,OAAO,EAAE,0BAA0B,CAAC;IACpC,QAAQ,EAAE,2BAA2B,CAAC;CACzC;AAED;;;GAGG;AACH,MAAM,WAAW,+BAA+B;IAC5C,mEAAmE;IACnE,MAAM,EAAE,0BAA0B,GAAG,IAAI,CAAC;IAC1C,sFAAsF;IACtF,UAAU,EAAE,0BAA0B,EAAE,CAAC;IACzC,yFAAyF;IACzF,SAAS,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,qBAAsB,SAAQ,UAAU,CAAC,qBAAqB,CAAC;IACxE;;;;OAIG;IACH,WAAkB,QAAQ,IAAI,qBAAqB,CAElD;IAED,OAAO,CAAC,SAAS,CAAoC;IACrD,OAAO,CAAC,UAAU,CAAqC;IAEvD;;;;;OAKG;IACU,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,WAAW,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsBhH;;OAEG;IACH,IAAW,QAAQ,IAAI,0BAA0B,EAAE,CAElD;IAED;;;OAGG;IACH,IAAW,SAAS,IAAI,2BAA2B,EAAE,CAEpD;IAED;;;OAGG;IACH,IAAW,qBAAqB,IAAI,0BAA0B,EAAE,CAQ/D;IAED;;OAEG;IACH,IAAW,cAAc,IAAI,0BAA0B,EAAE,CAExD;IAMD;;;;;;;;;;;;;;OAcG;IACI,qBAAqB,CAAC,UAAU,GAAE,0BAA0B,EAAwB,GAAG,+BAA+B;IAS7H;;;;OAIG;IACI,uBAAuB,CAAC,UAAU,CAAC,EAAE,0BAA0B,EAAE,GAAG,MAAM,GAAG,IAAI;IAIxF,0FAA0F;IAC1F,OAAO,CAAC,MAAM,CAAC,kBAAkB;IAYjC;;;;OAIG;IACI,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAIhF;;;;OAIG;IACI,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,2BAA2B,GAAG,SAAS;IAInF;;;;OAIG;IACI,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,0BAA0B,GAAG,SAAS;IAI7E;;;;OAIG;IACI,uBAAuB,CAAC,UAAU,EAAE,MAAM,GAAG,0BAA0B,EAAE;IAIhF;;;;OAIG;IACI,sBAAsB,CAAC,SAAS,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI;CAOtF"}
|