@memberjunction/core-entities-server 6.2.0-edge.4 → 6.2.0-edge.6
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/MJAIAgentSessionEntityServer.server.d.ts +9 -3
- package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentSessionEntityServer.server.js +21 -6
- package/dist/custom/MJAIAgentSessionEntityServer.server.js.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.d.ts +9 -0
- package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.js +25 -1
- package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
- package/dist/custom/MJConversationEntityServer.server.d.ts +13 -0
- package/dist/custom/MJConversationEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJConversationEntityServer.server.js +33 -0
- package/dist/custom/MJConversationEntityServer.server.js.map +1 -0
- package/dist/custom/MJDashboardEntityServer.server.d.ts +14 -0
- package/dist/custom/MJDashboardEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJDashboardEntityServer.server.js +38 -0
- package/dist/custom/MJDashboardEntityServer.server.js.map +1 -0
- package/dist/custom/MJDataContextItemEntityServer.server.d.ts +33 -0
- package/dist/custom/MJDataContextItemEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJDataContextItemEntityServer.server.js +84 -0
- package/dist/custom/MJDataContextItemEntityServer.server.js.map +1 -0
- package/dist/custom/MJDuplicateRunEntityServer.server.d.ts +34 -2
- package/dist/custom/MJDuplicateRunEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJDuplicateRunEntityServer.server.js +103 -23
- package/dist/custom/MJDuplicateRunEntityServer.server.js.map +1 -1
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts +73 -0
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js +391 -0
- package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js.map +1 -0
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts +96 -22
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.js +239 -55
- package/dist/custom/MJEntityFieldPermissionEntityServer.server.js.map +1 -1
- package/dist/custom/MJFileEntityServer.server.d.ts +45 -0
- package/dist/custom/MJFileEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJFileEntityServer.server.js +101 -0
- package/dist/custom/MJFileEntityServer.server.js.map +1 -0
- package/dist/custom/MJQueryEntityServer.server.d.ts +13 -1
- package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJQueryEntityServer.server.js +56 -8
- package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
- package/dist/custom/MJQuerySQLEntityServer.server.js +3 -3
- package/dist/custom/MJQuerySQLEntityServer.server.js.map +1 -1
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.d.ts +26 -14
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.js +57 -32
- package/dist/custom/MJRowLevelSecurityFilterEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserRoleEntityServer.server.d.ts +74 -7
- package/dist/custom/MJUserRoleEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserRoleEntityServer.server.js +206 -20
- package/dist/custom/MJUserRoleEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.js +12 -3
- package/dist/custom/MJUserRoutineEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserViewEntityServer.server.d.ts +43 -1
- package/dist/custom/MJUserViewEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserViewEntityServer.server.js +169 -11
- package/dist/custom/MJUserViewEntityServer.server.js.map +1 -1
- package/dist/custom/MJVectorIndexEntityServer.server.d.ts +83 -11
- package/dist/custom/MJVectorIndexEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJVectorIndexEntityServer.server.js +285 -42
- package/dist/custom/MJVectorIndexEntityServer.server.js.map +1 -1
- package/dist/custom/anonymousOwnershipKeyGuard.d.ts +42 -0
- package/dist/custom/anonymousOwnershipKeyGuard.d.ts.map +1 -0
- package/dist/custom/anonymousOwnershipKeyGuard.js +36 -0
- package/dist/custom/anonymousOwnershipKeyGuard.js.map +1 -0
- package/dist/custom/approvalStamp.d.ts +37 -0
- package/dist/custom/approvalStamp.d.ts.map +1 -0
- package/dist/custom/approvalStamp.js +67 -0
- package/dist/custom/approvalStamp.js.map +1 -0
- package/dist/custom/fieldPermissionAccess.d.ts +31 -0
- package/dist/custom/fieldPermissionAccess.d.ts.map +1 -0
- package/dist/custom/fieldPermissionAccess.js +38 -0
- package/dist/custom/fieldPermissionAccess.js.map +1 -0
- package/dist/custom/fieldPermissionReconciler.d.ts.map +1 -1
- package/dist/custom/fieldPermissionReconciler.js +12 -2
- package/dist/custom/fieldPermissionReconciler.js.map +1 -1
- package/dist/custom/query-extraction/pipeline.d.ts.map +1 -1
- package/dist/custom/query-extraction/pipeline.js +56 -5
- package/dist/custom/query-extraction/pipeline.js.map +1 -1
- package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
- package/dist/custom/query-extraction/resolve.js +25 -7
- package/dist/custom/query-extraction/resolve.js.map +1 -1
- package/dist/custom/query-extraction/sync.d.ts +1 -1
- package/dist/custom/query-extraction/sync.d.ts.map +1 -1
- package/dist/custom/query-extraction/sync.js +84 -21
- package/dist/custom/query-extraction/sync.js.map +1 -1
- package/dist/custom/query-extraction/types.d.ts +7 -0
- package/dist/custom/query-extraction/types.d.ts.map +1 -1
- package/dist/custom/rowFilterValidation.d.ts +47 -2
- package/dist/custom/rowFilterValidation.d.ts.map +1 -1
- package/dist/custom/rowFilterValidation.js +122 -11
- package/dist/custom/rowFilterValidation.js.map +1 -1
- package/dist/custom/systemUserGuardState.d.ts +73 -0
- package/dist/custom/systemUserGuardState.d.ts.map +1 -0
- package/dist/custom/systemUserGuardState.js +161 -0
- package/dist/custom/systemUserGuardState.js.map +1 -0
- package/dist/custom/template-extraction/parser.js +5 -2
- package/dist/custom/template-extraction/parser.js.map +1 -1
- package/dist/custom/template-extraction/pipeline.d.ts +6 -1
- package/dist/custom/template-extraction/pipeline.d.ts.map +1 -1
- package/dist/custom/template-extraction/pipeline.js +15 -6
- package/dist/custom/template-extraction/pipeline.js.map +1 -1
- package/dist/custom/template-extraction/types.d.ts +2 -2
- package/dist/custom/template-extraction/types.d.ts.map +1 -1
- 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 +30 -30
|
@@ -3,11 +3,17 @@ import { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
|
|
|
3
3
|
/**
|
|
4
4
|
* Server-side `MJ: AI Agent Sessions` entity.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
* `maxSessionDeadlineIso`, the `identityVerification` state) out of the session owner's reach
|
|
6
|
+
* It keeps the **server-authoritative keys** inside `Config` (the janitor's
|
|
7
|
+
* `maxSessionDeadlineIso`, the `identityVerification` state) out of the session owner's reach, and keeps an
|
|
8
|
+
* anonymous visitor from re-pointing an existing session's `ConversationID` (the anonymous ownership key —
|
|
9
|
+
* see `CheckAnonymousOwnershipKeyChange`). The
|
|
8
10
|
* owner can legitimately write the row — the `UI` and `Widget Guest` roles hold `CanUpdate` on their
|
|
9
11
|
* own sessions — so the protection has to live at the entity, where the generated CRUD mutations,
|
|
10
|
-
* `StartAgentSession(configJson)` and every other path converge on `Save
|
|
12
|
+
* `StartAgentSession(configJson)` and every other path converge on `Save`.
|
|
13
|
+
*
|
|
14
|
+
* The recording ledger's columns need no subclass: they are protected in metadata
|
|
15
|
+
* (`AllowUpdateAPI=false`, #6010), so an entity save cannot write them and only the ledger's stored
|
|
16
|
+
* procedures do.
|
|
11
17
|
*
|
|
12
18
|
* See {@link FindProtectedSessionConfigChanges} for what is protected and why, and
|
|
13
19
|
* `RunWithTrustedSessionConfigWrites` for how server code opts in.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentSessionEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentSessionEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwD,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE9G,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"MJAIAgentSessionEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentSessionEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwD,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE9G,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAIvE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBACa,4BAA6B,SAAQ,sBAAsB;IACpD,QAAQ,IAAI,gBAAgB;IAa5C,4FAA4F;IAC5F,OAAO,CAAC,wBAAwB;CAmCnC"}
|
|
@@ -8,14 +8,21 @@ import { BaseEntity, ValidationErrorInfo, ValidationErrorType } from '@memberjun
|
|
|
8
8
|
import { RegisterClass } from '@memberjunction/global';
|
|
9
9
|
import { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
|
|
10
10
|
import { FindProtectedSessionConfigChanges, IsTrustedSessionConfigWriteActive } from './sessionConfigGuard.js';
|
|
11
|
+
import { CheckAnonymousOwnershipKeyChange, IsSetByTransactionVariable } from './anonymousOwnershipKeyGuard.js';
|
|
11
12
|
/**
|
|
12
13
|
* Server-side `MJ: AI Agent Sessions` entity.
|
|
13
14
|
*
|
|
14
|
-
*
|
|
15
|
-
* `maxSessionDeadlineIso`, the `identityVerification` state) out of the session owner's reach
|
|
15
|
+
* It keeps the **server-authoritative keys** inside `Config` (the janitor's
|
|
16
|
+
* `maxSessionDeadlineIso`, the `identityVerification` state) out of the session owner's reach, and keeps an
|
|
17
|
+
* anonymous visitor from re-pointing an existing session's `ConversationID` (the anonymous ownership key —
|
|
18
|
+
* see `CheckAnonymousOwnershipKeyChange`). The
|
|
16
19
|
* owner can legitimately write the row — the `UI` and `Widget Guest` roles hold `CanUpdate` on their
|
|
17
20
|
* own sessions — so the protection has to live at the entity, where the generated CRUD mutations,
|
|
18
|
-
* `StartAgentSession(configJson)` and every other path converge on `Save
|
|
21
|
+
* `StartAgentSession(configJson)` and every other path converge on `Save`.
|
|
22
|
+
*
|
|
23
|
+
* The recording ledger's columns need no subclass: they are protected in metadata
|
|
24
|
+
* (`AllowUpdateAPI=false`, #6010), so an entity save cannot write them and only the ledger's stored
|
|
25
|
+
* procedures do.
|
|
19
26
|
*
|
|
20
27
|
* See {@link FindProtectedSessionConfigChanges} for what is protected and why, and
|
|
21
28
|
* `RunWithTrustedSessionConfigWrites` for how server code opts in.
|
|
@@ -27,9 +34,12 @@ import { FindProtectedSessionConfigChanges, IsTrustedSessionConfigWriteActive }
|
|
|
27
34
|
let MJAIAgentSessionEntityServer = class MJAIAgentSessionEntityServer extends MJAIAgentSessionEntity {
|
|
28
35
|
Validate() {
|
|
29
36
|
const result = super.Validate();
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
const violations = [
|
|
38
|
+
this.checkProtectedConfigKeys(),
|
|
39
|
+
CheckAnonymousOwnershipKeyChange(this, 'ConversationID'),
|
|
40
|
+
].filter((v) => v !== null);
|
|
41
|
+
if (violations.length > 0) {
|
|
42
|
+
result.Errors.push(...violations);
|
|
33
43
|
result.Success = false;
|
|
34
44
|
}
|
|
35
45
|
return result;
|
|
@@ -43,6 +53,11 @@ let MJAIAgentSessionEntityServer = class MJAIAgentSessionEntityServer extends MJ
|
|
|
43
53
|
if (!configField) {
|
|
44
54
|
return null;
|
|
45
55
|
}
|
|
56
|
+
// A 'Use' transaction variable writes its field at submit, after this comparison: on Config its value is unknown
|
|
57
|
+
// here, and on ID the update (and this Config) lands on another session than the one compared against.
|
|
58
|
+
if (IsSetByTransactionVariable(this, ['Config', 'ID'])) {
|
|
59
|
+
return new ValidationErrorInfo('Config', 'Config is server-managed in part, so neither it nor the row it is written to can come from a transaction variable.', null, ValidationErrorType.Failure);
|
|
60
|
+
}
|
|
46
61
|
// A saved record is compared against what was loaded; a new record against nothing. For a
|
|
47
62
|
// saved record whose Config was not touched there is nothing to compare.
|
|
48
63
|
if (this.IsSaved && !configField.Dirty) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentSessionEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentSessionEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,EAAoB,MAAM,sBAAsB,CAAC;AAC9G,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,iCAAiC,EAAE,iCAAiC,EAAE,MAAM,sBAAsB,CAAC;AAE5G
|
|
1
|
+
{"version":3,"file":"MJAIAgentSessionEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentSessionEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,mBAAmB,EAAE,mBAAmB,EAAoB,MAAM,sBAAsB,CAAC;AAC9G,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,iCAAiC,EAAE,iCAAiC,EAAE,MAAM,sBAAsB,CAAC;AAC5G,OAAO,EAAE,gCAAgC,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAE5G;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEI,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,sBAAsB;IACpD,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG;YACf,IAAI,CAAC,wBAAwB,EAAE;YAC/B,gCAAgC,CAAC,IAAI,EAAE,gBAAgB,CAAC;SAC3D,CAAC,MAAM,CAAC,CAAC,CAAC,EAA4B,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACtD,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,CAAC;YAClC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,4FAA4F;IACpF,wBAAwB;QAC5B,IAAI,iCAAiC,EAAE,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,WAAW,GAAG,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClD,IAAI,CAAC,WAAW,EAAE,CAAC;YACf,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,iHAAiH;QACjH,uGAAuG;QACvG,IAAI,0BAA0B,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,mBAAmB,CAC1B,QAAQ,EACR,oHAAoH,EACpH,IAAI,EACJ,mBAAmB,CAAC,OAAO,CAC9B,CAAC;QACN,CAAC;QACD,0FAA0F;QAC1F,yEAAyE;QACzE,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,IAAI,OAAO,WAAW,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;QACxG,MAAM,OAAO,GAAG,iCAAiC,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,IAAI,mBAAmB,CAC1B,QAAQ,EACR,gBAAgB,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,8DAA8D,EAChG,IAAI,EACJ,mBAAmB,CAAC,OAAO,CAC9B,CAAC;IACN,CAAC;CACJ,CAAA;AAlDY,4BAA4B;IADxC,aAAa,CAAC,UAAU,EAAE,uBAAuB,CAAC;GACtC,4BAA4B,CAkDxC"}
|
|
@@ -24,9 +24,18 @@ import { MJComponentEntityExtended } from "@memberjunction/core-entities";
|
|
|
24
24
|
* found by comparing with the stored row, not with the values as loaded. When a read fails, the
|
|
25
25
|
* write is refused. The check needs a query and `Validate()` is synchronous, so it runs in `Save()`
|
|
26
26
|
* (an ordinary save and a `ReplayOnly` save alike) and in `Delete()`, before the write.
|
|
27
|
+
*
|
|
28
|
+
* Approval (`ApprovalStatus`) is a server act: a save that moves it to Approved records the context
|
|
29
|
+
* user, the time and the fingerprint of this version's specification (`ApplyApprovalRulesAsync`).
|
|
27
30
|
*/
|
|
28
31
|
export declare class MJComponentEntityServer extends MJComponentEntityExtended {
|
|
29
32
|
Save(options?: EntitySaveOptions): Promise<boolean>;
|
|
33
|
+
/**
|
|
34
|
+
* Applies the approval rules. Nothing in this save derives the specification or version, so an
|
|
35
|
+
* approving save stamps the fingerprint now and writes it with the row.
|
|
36
|
+
* @returns false when the save was refused (the reason is in `LatestResult`)
|
|
37
|
+
*/
|
|
38
|
+
private applyApprovalAsync;
|
|
30
39
|
Delete(options?: EntityDeleteOptions): Promise<boolean>;
|
|
31
40
|
/**
|
|
32
41
|
* Simple proxy to local helper method for embeddings. Needed for BaseEntity sub-classes that want to use embeddings built into BaseEntity
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJComponentEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJComponentEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EAExB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,
|
|
1
|
+
{"version":3,"file":"MJComponentEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJComponentEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EAExB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAoC,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAM5G;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBACa,uBAAwB,SAAQ,yBAAyB;IAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BzE;;;;OAIG;YACW,kBAAkB;IAYV,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7E;;;;OAIG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5F,0GAA0G;IAC1G,OAAO,KAAK,UAAU,GAcrB;CACJ"}
|
|
@@ -6,10 +6,11 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
6
6
|
};
|
|
7
7
|
import { BaseEntity, } from "@memberjunction/core";
|
|
8
8
|
import { RegisterClass } from "@memberjunction/global";
|
|
9
|
-
import { MJComponentEntityExtended } from "@memberjunction/core-entities";
|
|
9
|
+
import { ComputeComponentFingerprintAsync, MJComponentEntityExtended } from "@memberjunction/core-entities";
|
|
10
10
|
import { EmbedTextLocalHelper } from "./util.js";
|
|
11
11
|
import { FormScopeRefusalResult } from "./FormScopeGuard.js";
|
|
12
12
|
import { ComponentGuardRefusal } from "./FormComponentGuard.js";
|
|
13
|
+
import { ApplyApprovalRulesAsync, ApprovalRefusalResult } from "./approvalStamp.js";
|
|
13
14
|
/**
|
|
14
15
|
* Server-side `MJ: Components` entity.
|
|
15
16
|
*
|
|
@@ -34,6 +35,9 @@ import { ComponentGuardRefusal } from "./FormComponentGuard.js";
|
|
|
34
35
|
* found by comparing with the stored row, not with the values as loaded. When a read fails, the
|
|
35
36
|
* write is refused. The check needs a query and `Validate()` is synchronous, so it runs in `Save()`
|
|
36
37
|
* (an ordinary save and a `ReplayOnly` save alike) and in `Delete()`, before the write.
|
|
38
|
+
*
|
|
39
|
+
* Approval (`ApprovalStatus`) is a server act: a save that moves it to Approved records the context
|
|
40
|
+
* user, the time and the fingerprint of this version's specification (`ApplyApprovalRulesAsync`).
|
|
37
41
|
*/
|
|
38
42
|
let MJComponentEntityServer = class MJComponentEntityServer extends MJComponentEntityExtended {
|
|
39
43
|
async Save(options) {
|
|
@@ -43,6 +47,9 @@ let MJComponentEntityServer = class MJComponentEntityServer extends MJComponentE
|
|
|
43
47
|
this.RegisterResultHistoryEntry(FormScopeRefusalResult(operation, refusal));
|
|
44
48
|
return false;
|
|
45
49
|
}
|
|
50
|
+
if (!await this.applyApprovalAsync(options)) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
46
53
|
await this.GenerateEmbeddingsByFieldName([
|
|
47
54
|
{
|
|
48
55
|
fieldName: "FunctionalRequirements",
|
|
@@ -60,6 +67,23 @@ let MJComponentEntityServer = class MJComponentEntityServer extends MJComponentE
|
|
|
60
67
|
const saveResult = await super.Save(options);
|
|
61
68
|
return saveResult;
|
|
62
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Applies the approval rules. Nothing in this save derives the specification or version, so an
|
|
72
|
+
* approving save stamps the fingerprint now and writes it with the row.
|
|
73
|
+
* @returns false when the save was refused (the reason is in `LatestResult`)
|
|
74
|
+
*/
|
|
75
|
+
async applyApprovalAsync(options) {
|
|
76
|
+
try {
|
|
77
|
+
if (!options?.ReplayOnly && await ApplyApprovalRulesAsync(this, 'ApprovalStatus', this.ApprovalStatus)) {
|
|
78
|
+
this.ApprovedFingerprint = await ComputeComponentFingerprintAsync(this);
|
|
79
|
+
}
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
catch (e) {
|
|
83
|
+
this.RegisterResultHistoryEntry(ApprovalRefusalResult(this, e));
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
63
87
|
async Delete(options) {
|
|
64
88
|
const refusal = await ComponentGuardRefusal(this.guardedRow, 'delete');
|
|
65
89
|
if (refusal) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJComponentEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJComponentEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACH,UAAU,GAKb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"MJComponentEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJComponentEntityServer.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ValidationResult } from '@memberjunction/core';
|
|
2
|
+
import { MJConversationEntity } from '@memberjunction/core-entities';
|
|
3
|
+
/**
|
|
4
|
+
* Server-side `MJ: Conversations` entity.
|
|
5
|
+
*
|
|
6
|
+
* Keeps `ExternalID` — the scope identity an anonymous visitor's realtime session is owned through — out
|
|
7
|
+
* of an anonymous visitor's reach once the conversation exists. See {@link CheckAnonymousOwnershipKeyChange}.
|
|
8
|
+
* Uses the synchronous `Validate()` so the rule runs on every save, like `MJAIAgentSessionEntityServer`.
|
|
9
|
+
*/
|
|
10
|
+
export declare class MJConversationEntityServer extends MJConversationEntity {
|
|
11
|
+
Validate(): ValidationResult;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=MJConversationEntityServer.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJConversationEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJConversationEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAGrE;;;;;;GAMG;AACH,qBACa,0BAA2B,SAAQ,oBAAoB;IAChD,QAAQ,IAAI,gBAAgB;CAS/C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
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 } from '@memberjunction/core';
|
|
8
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
9
|
+
import { MJConversationEntity } from '@memberjunction/core-entities';
|
|
10
|
+
import { CheckAnonymousOwnershipKeyChange } from './anonymousOwnershipKeyGuard.js';
|
|
11
|
+
/**
|
|
12
|
+
* Server-side `MJ: Conversations` entity.
|
|
13
|
+
*
|
|
14
|
+
* Keeps `ExternalID` — the scope identity an anonymous visitor's realtime session is owned through — out
|
|
15
|
+
* of an anonymous visitor's reach once the conversation exists. See {@link CheckAnonymousOwnershipKeyChange}.
|
|
16
|
+
* Uses the synchronous `Validate()` so the rule runs on every save, like `MJAIAgentSessionEntityServer`.
|
|
17
|
+
*/
|
|
18
|
+
let MJConversationEntityServer = class MJConversationEntityServer extends MJConversationEntity {
|
|
19
|
+
Validate() {
|
|
20
|
+
const result = super.Validate();
|
|
21
|
+
const violation = CheckAnonymousOwnershipKeyChange(this, 'ExternalID');
|
|
22
|
+
if (violation) {
|
|
23
|
+
result.Errors.push(violation);
|
|
24
|
+
result.Success = false;
|
|
25
|
+
}
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
MJConversationEntityServer = __decorate([
|
|
30
|
+
RegisterClass(BaseEntity, 'MJ: Conversations')
|
|
31
|
+
], MJConversationEntityServer);
|
|
32
|
+
export { MJConversationEntityServer };
|
|
33
|
+
//# sourceMappingURL=MJConversationEntityServer.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJConversationEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJConversationEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAoB,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AACrE,OAAO,EAAE,gCAAgC,EAAE,MAAM,8BAA8B,CAAC;AAEhF;;;;;;GAMG;AAEI,IAAM,0BAA0B,GAAhC,MAAM,0BAA2B,SAAQ,oBAAoB;IAChD,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,gCAAgC,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QACvE,IAAI,SAAS,EAAE,CAAC;YACZ,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YAC9B,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QAC3B,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ,CAAA;AAVY,0BAA0B;IADtC,aAAa,CAAC,UAAU,EAAE,mBAAmB,CAAC;GAClC,0BAA0B,CAUtC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { EntitySaveOptions } from "@memberjunction/core";
|
|
2
|
+
import { MJDashboardEntityExtended } from "@memberjunction/core-entities";
|
|
3
|
+
/**
|
|
4
|
+
* Server-side `MJ: Dashboards` entity.
|
|
5
|
+
*
|
|
6
|
+
* Approval (`ApprovalStatus`) is a server act: a save that moves it to Approved records the context
|
|
7
|
+
* user, the time and the fingerprint of the dashboard's definition (type, configuration, code and
|
|
8
|
+
* driver class); values a client sends for those columns are ignored (`ApplyApprovalRulesAsync`).
|
|
9
|
+
* Who may approve is whoever may edit the dashboard.
|
|
10
|
+
*/
|
|
11
|
+
export declare class MJDashboardEntityServer extends MJDashboardEntityExtended {
|
|
12
|
+
Save(options?: EntitySaveOptions): Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=MJDashboardEntityServer.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJDashboardEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJDashboardEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAErE,OAAO,EAAoC,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAG5G;;;;;;;GAOG;AACH,qBACa,uBAAwB,SAAQ,yBAAyB;IAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;CAY5E"}
|
|
@@ -0,0 +1,38 @@
|
|
|
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 } from "@memberjunction/core";
|
|
8
|
+
import { RegisterClass } from "@memberjunction/global";
|
|
9
|
+
import { ComputeDashboardFingerprintAsync, MJDashboardEntityExtended } from "@memberjunction/core-entities";
|
|
10
|
+
import { ApplyApprovalRulesAsync, ApprovalRefusalResult } from "./approvalStamp.js";
|
|
11
|
+
/**
|
|
12
|
+
* Server-side `MJ: Dashboards` entity.
|
|
13
|
+
*
|
|
14
|
+
* Approval (`ApprovalStatus`) is a server act: a save that moves it to Approved records the context
|
|
15
|
+
* user, the time and the fingerprint of the dashboard's definition (type, configuration, code and
|
|
16
|
+
* driver class); values a client sends for those columns are ignored (`ApplyApprovalRulesAsync`).
|
|
17
|
+
* Who may approve is whoever may edit the dashboard.
|
|
18
|
+
*/
|
|
19
|
+
let MJDashboardEntityServer = class MJDashboardEntityServer extends MJDashboardEntityExtended {
|
|
20
|
+
async Save(options) {
|
|
21
|
+
try {
|
|
22
|
+
// Nothing in this save derives the definition, so the fingerprint is stamped now and written with the row.
|
|
23
|
+
if (!options?.ReplayOnly && await ApplyApprovalRulesAsync(this, 'ApprovalStatus', this.ApprovalStatus)) {
|
|
24
|
+
this.ApprovedFingerprint = await ComputeDashboardFingerprintAsync(this);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (e) {
|
|
28
|
+
this.RegisterResultHistoryEntry(ApprovalRefusalResult(this, e));
|
|
29
|
+
return false;
|
|
30
|
+
}
|
|
31
|
+
return super.Save(options);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
MJDashboardEntityServer = __decorate([
|
|
35
|
+
RegisterClass(BaseEntity, 'MJ: Dashboards')
|
|
36
|
+
], MJDashboardEntityServer);
|
|
37
|
+
export { MJDashboardEntityServer };
|
|
38
|
+
//# sourceMappingURL=MJDashboardEntityServer.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJDashboardEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJDashboardEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAAqB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,gCAAgC,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC5G,OAAO,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAEjF;;;;;;;GAOG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,yBAAyB;IAClD,KAAK,CAAC,IAAI,CAAC,OAA2B;QAClD,IAAI,CAAC;YACD,2GAA2G;YAC3G,IAAI,CAAC,OAAO,EAAE,UAAU,IAAI,MAAM,uBAAuB,CAAC,IAAI,EAAE,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC;gBACrG,IAAI,CAAC,mBAAmB,GAAG,MAAM,gCAAgC,CAAC,IAAI,CAAC,CAAC;YAC5E,CAAC;QACL,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,IAAI,CAAC,0BAA0B,CAAC,qBAAqB,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAChE,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;CACJ,CAAA;AAbY,uBAAuB;IADnC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC;GAC/B,uBAAuB,CAanC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { EntitySaveOptions, ValidationResult } from '@memberjunction/core';
|
|
2
|
+
import { MJDataContextItemEntity } from '@memberjunction/core-entities';
|
|
3
|
+
/**
|
|
4
|
+
* Server-side `MJ: Data Context Items` entity. The SQL of a `sql` item runs when its data context is
|
|
5
|
+
* loaded, so only an administrator (Owner-type user) may save an item that is a SQL item or holds SQL
|
|
6
|
+
* text: creating it, changing any of its fields, or moving it to another data context. Other items
|
|
7
|
+
* stay writable as before.
|
|
8
|
+
*
|
|
9
|
+
* The rule reads the item's values, not which fields changed, because this entity does not track
|
|
10
|
+
* record changes and a client's `OldValues___` can decide what looks changed. A non-Owner's save of an
|
|
11
|
+
* existing item whose `Type` or `SQL` was not loaded is refused as well: those columns keep their
|
|
12
|
+
* stored values on save, and the stored item may be a SQL item.
|
|
13
|
+
*/
|
|
14
|
+
export declare class MJDataContextItemEntityServer extends MJDataContextItemEntity {
|
|
15
|
+
private static readonly SQL_WRITE_REFUSED;
|
|
16
|
+
private static readonly SQL_NOT_LOADED_REFUSED;
|
|
17
|
+
/** The columns that decide whether an item holds SQL. */
|
|
18
|
+
private static readonly SQL_COLUMNS;
|
|
19
|
+
Validate(): ValidationResult;
|
|
20
|
+
/** Applies the same rule to a `ReplayOnly` save, which skips `Validate()`. */
|
|
21
|
+
Save(options?: EntitySaveOptions): Promise<boolean>;
|
|
22
|
+
/** Returns why the acting user may not save this item, or null when they may. */
|
|
23
|
+
private saveRefusal;
|
|
24
|
+
/** True when this is an existing item whose `Type` or `SQL` was not loaded. */
|
|
25
|
+
private sqlColumnsNotLoaded;
|
|
26
|
+
/** True when the item, as loaded and changed, is a SQL item or holds SQL text. */
|
|
27
|
+
private holdsSQL;
|
|
28
|
+
/** True when the acting user is an Owner-type user. */
|
|
29
|
+
private callerIsOwner;
|
|
30
|
+
/** Records the refusal so `LatestResult.CompleteMessage` carries it, and returns false. */
|
|
31
|
+
private refuseSave;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=MJDataContextItemEntityServer.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJDataContextItemEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJDataContextItemEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgC,iBAAiB,EAAsD,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAE7J,OAAO,EAAE,uBAAuB,EAA+B,MAAM,+BAA+B,CAAC;AAErG;;;;;;;;;;GAUG;AACH,qBACa,6BAA8B,SAAQ,uBAAuB;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAC8F;IAEvI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CACuG;IAErJ,yDAAyD;IACzD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAqE;IAExF,QAAQ,IAAI,gBAAgB;IAU5C,8EAA8E;IACxD,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAQzE,iFAAiF;IACjF,OAAO,CAAC,WAAW;IAUnB,+EAA+E;IAC/E,OAAO,CAAC,mBAAmB;IAI3B,kFAAkF;IAClF,OAAO,CAAC,QAAQ;IAIhB,uDAAuD;IACvD,OAAO,CAAC,aAAa;IAKrB,2FAA2F;IAC3F,OAAO,CAAC,UAAU;CAUrB"}
|
|
@@ -0,0 +1,84 @@
|
|
|
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
|
+
var MJDataContextItemEntityServer_1;
|
|
8
|
+
import { BaseEntity, BaseEntityResult, ValidationErrorInfo, ValidationErrorType } from '@memberjunction/core';
|
|
9
|
+
import { RegisterClass } from '@memberjunction/global';
|
|
10
|
+
import { MJDataContextItemEntity } from '@memberjunction/core-entities';
|
|
11
|
+
/**
|
|
12
|
+
* Server-side `MJ: Data Context Items` entity. The SQL of a `sql` item runs when its data context is
|
|
13
|
+
* loaded, so only an administrator (Owner-type user) may save an item that is a SQL item or holds SQL
|
|
14
|
+
* text: creating it, changing any of its fields, or moving it to another data context. Other items
|
|
15
|
+
* stay writable as before.
|
|
16
|
+
*
|
|
17
|
+
* The rule reads the item's values, not which fields changed, because this entity does not track
|
|
18
|
+
* record changes and a client's `OldValues___` can decide what looks changed. A non-Owner's save of an
|
|
19
|
+
* existing item whose `Type` or `SQL` was not loaded is refused as well: those columns keep their
|
|
20
|
+
* stored values on save, and the stored item may be a SQL item.
|
|
21
|
+
*/
|
|
22
|
+
let MJDataContextItemEntityServer = class MJDataContextItemEntityServer extends MJDataContextItemEntity {
|
|
23
|
+
static { MJDataContextItemEntityServer_1 = this; }
|
|
24
|
+
static { this.SQL_WRITE_REFUSED = 'Only an administrator (Owner-type user) may save a data context item that holds SQL, because that SQL runs against the database.'; }
|
|
25
|
+
static { this.SQL_NOT_LOADED_REFUSED = 'Only an administrator (Owner-type user) may save a data context item whose Type and SQL were not loaded, because the stored item may hold SQL.'; }
|
|
26
|
+
/** The columns that decide whether an item holds SQL. */
|
|
27
|
+
static { this.SQL_COLUMNS = ['Type', 'SQL']; }
|
|
28
|
+
Validate() {
|
|
29
|
+
const result = super.Validate();
|
|
30
|
+
const refusal = this.saveRefusal();
|
|
31
|
+
if (refusal) {
|
|
32
|
+
result.Errors.push(new ValidationErrorInfo('SQL', refusal, this.SQL, ValidationErrorType.Failure));
|
|
33
|
+
}
|
|
34
|
+
result.Success = result.Success && result.Errors.length === 0;
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
/** Applies the same rule to a `ReplayOnly` save, which skips `Validate()`. */
|
|
38
|
+
async Save(options) {
|
|
39
|
+
const refusal = options?.ReplayOnly ? this.saveRefusal() : null;
|
|
40
|
+
if (refusal) {
|
|
41
|
+
return this.refuseSave(refusal);
|
|
42
|
+
}
|
|
43
|
+
return super.Save(options);
|
|
44
|
+
}
|
|
45
|
+
/** Returns why the acting user may not save this item, or null when they may. */
|
|
46
|
+
saveRefusal() {
|
|
47
|
+
if (this.callerIsOwner()) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (this.sqlColumnsNotLoaded()) {
|
|
51
|
+
return MJDataContextItemEntityServer_1.SQL_NOT_LOADED_REFUSED;
|
|
52
|
+
}
|
|
53
|
+
return this.holdsSQL() ? MJDataContextItemEntityServer_1.SQL_WRITE_REFUSED : null;
|
|
54
|
+
}
|
|
55
|
+
/** True when this is an existing item whose `Type` or `SQL` was not loaded. */
|
|
56
|
+
sqlColumnsNotLoaded() {
|
|
57
|
+
return this.IsSaved && MJDataContextItemEntityServer_1.SQL_COLUMNS.some((name) => this.GetFieldByName(name)?.NotLoaded === true);
|
|
58
|
+
}
|
|
59
|
+
/** True when the item, as loaded and changed, is a SQL item or holds SQL text. */
|
|
60
|
+
holdsSQL() {
|
|
61
|
+
return this.Type === 'sql' || !!this.SQL?.trim();
|
|
62
|
+
}
|
|
63
|
+
/** True when the acting user is an Owner-type user. */
|
|
64
|
+
callerIsOwner() {
|
|
65
|
+
const caller = this.ActiveUser;
|
|
66
|
+
return caller?.Type?.trim().toLowerCase() === 'owner';
|
|
67
|
+
}
|
|
68
|
+
/** Records the refusal so `LatestResult.CompleteMessage` carries it, and returns false. */
|
|
69
|
+
refuseSave(message) {
|
|
70
|
+
const result = new BaseEntityResult();
|
|
71
|
+
result.Success = false;
|
|
72
|
+
result.Type = this.IsSaved ? 'update' : 'create';
|
|
73
|
+
result.Message = message;
|
|
74
|
+
result.StartedAt = new Date();
|
|
75
|
+
result.EndedAt = new Date();
|
|
76
|
+
this.RegisterResultHistoryEntry(result);
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
MJDataContextItemEntityServer = MJDataContextItemEntityServer_1 = __decorate([
|
|
81
|
+
RegisterClass(BaseEntity, 'MJ: Data Context Items')
|
|
82
|
+
], MJDataContextItemEntityServer);
|
|
83
|
+
export { MJDataContextItemEntityServer };
|
|
84
|
+
//# sourceMappingURL=MJDataContextItemEntityServer.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJDataContextItemEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJDataContextItemEntityServer.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,44 @@
|
|
|
1
1
|
import { EntitySaveOptions } from "@memberjunction/core";
|
|
2
|
-
import { MJDuplicateRunEntity } from "@memberjunction/core-entities";
|
|
2
|
+
import { MJDuplicateRunEntity, MJEntityDocumentEntity } from "@memberjunction/core-entities";
|
|
3
|
+
/**
|
|
4
|
+
* Chooses the default entity document for a new duplicate run that was created without one, from
|
|
5
|
+
* the entity's active documents ordered newest-updated first. A 'Record Duplicate' document wins
|
|
6
|
+
* over any other type: an entity can also have a Search document (MJ ships one for several core
|
|
7
|
+
* entities), whose template and vectors are built for search, not for matching records. Without a
|
|
8
|
+
* 'Record Duplicate' document, the newest active document is used.
|
|
9
|
+
*
|
|
10
|
+
* Only callers that name no document get this default; the Duplicates tab always names the one
|
|
11
|
+
* the user picked.
|
|
12
|
+
*
|
|
13
|
+
* @param activeDocuments the entity's active documents, newest `__mj_UpdatedAt` first
|
|
14
|
+
* @returns the document to use, or null when there is none
|
|
15
|
+
*/
|
|
16
|
+
export declare function PickDuplicateDetectionDocument<T extends Pick<MJEntityDocumentEntity, 'Type'>>(activeDocuments: T[]): T | null;
|
|
17
|
+
/**
|
|
18
|
+
* Checks that the entity document a run names belongs to the run's entity.
|
|
19
|
+
*
|
|
20
|
+
* @param entityDocument the run's document
|
|
21
|
+
* @param entityID the run's EntityID
|
|
22
|
+
* @returns why the document cannot be used, or null when it can
|
|
23
|
+
*/
|
|
24
|
+
export declare function CheckRunEntityDocument(entityDocument: Pick<MJEntityDocumentEntity, 'EntityID' | 'Name'>, entityID: string): string | null;
|
|
3
25
|
export declare class MJDuplicateRunEntityServer extends MJDuplicateRunEntity {
|
|
4
26
|
Save(options?: EntitySaveOptions): Promise<boolean>;
|
|
5
27
|
/**
|
|
6
28
|
* Run duplicate detection asynchronously. On failure, updates the run's
|
|
7
|
-
* ProcessingStatus to '
|
|
29
|
+
* ProcessingStatus to 'Failed' with ProcessingErrorMessage so the UI can surface the problem.
|
|
8
30
|
*/
|
|
9
31
|
private runDetectionAsync;
|
|
32
|
+
/**
|
|
33
|
+
* The entity's default duplicate-detection document (see {@link PickDuplicateDetectionDocument}),
|
|
34
|
+
* or null when the entity has no active document.
|
|
35
|
+
*/
|
|
36
|
+
private findDefaultEntityDocument;
|
|
37
|
+
/**
|
|
38
|
+
* Loads the entity document this run names. Throws when it is missing or belongs to another
|
|
39
|
+
* entity, which fails the run with that message.
|
|
40
|
+
*/
|
|
41
|
+
private loadRunEntityDocument;
|
|
10
42
|
/**
|
|
11
43
|
* Convert a DuplicateDetectionProgress callback into a PipelineProgress notification.
|
|
12
44
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJDuplicateRunEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJDuplicateRunEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqE,iBAAiB,EAA8E,MAAM,sBAAsB,CAAC;AAExM,OAAO,EAAE,oBAAoB,
|
|
1
|
+
{"version":3,"file":"MJDuplicateRunEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJDuplicateRunEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqE,iBAAiB,EAA8E,MAAM,sBAAsB,CAAC;AAExM,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAQ7F;;;;;;;;;;;;GAYG;AACH,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,IAAI,CAAC,sBAAsB,EAAE,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,IAAI,CAG7H;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAClC,cAAc,EAAE,IAAI,CAAC,sBAAsB,EAAE,UAAU,GAAG,MAAM,CAAC,EACjE,QAAQ,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,CAKf;AAyCD,qBACa,0BAA2B,SAAQ,oBAAoB;IAC1C,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgCzE;;;OAGG;YACW,iBAAiB;IAqE/B;;;OAGG;YACW,yBAAyB;IAevC;;;OAGG;YACW,qBAAqB;IAqBnC;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;OAIG;IACH;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,2BAA2B;CA8BtC"}
|