@memberjunction/core-entities-server 6.2.0-edge.5 → 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.
Files changed (81) hide show
  1. package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts +9 -26
  2. package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts.map +1 -1
  3. package/dist/custom/MJAIAgentSessionEntityServer.server.js +21 -44
  4. package/dist/custom/MJAIAgentSessionEntityServer.server.js.map +1 -1
  5. package/dist/custom/MJComponentEntityServer.server.d.ts +9 -0
  6. package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
  7. package/dist/custom/MJComponentEntityServer.server.js +25 -1
  8. package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
  9. package/dist/custom/MJConversationEntityServer.server.d.ts +13 -0
  10. package/dist/custom/MJConversationEntityServer.server.d.ts.map +1 -0
  11. package/dist/custom/MJConversationEntityServer.server.js +33 -0
  12. package/dist/custom/MJConversationEntityServer.server.js.map +1 -0
  13. package/dist/custom/MJDashboardEntityServer.server.d.ts +14 -0
  14. package/dist/custom/MJDashboardEntityServer.server.d.ts.map +1 -0
  15. package/dist/custom/MJDashboardEntityServer.server.js +38 -0
  16. package/dist/custom/MJDashboardEntityServer.server.js.map +1 -0
  17. package/dist/custom/MJDuplicateRunEntityServer.server.d.ts +34 -2
  18. package/dist/custom/MJDuplicateRunEntityServer.server.d.ts.map +1 -1
  19. package/dist/custom/MJDuplicateRunEntityServer.server.js +103 -23
  20. package/dist/custom/MJDuplicateRunEntityServer.server.js.map +1 -1
  21. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts +73 -0
  22. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.d.ts.map +1 -0
  23. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js +391 -0
  24. package/dist/custom/MJEntityAlternateBaseViewEntityServer.server.js.map +1 -0
  25. package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts +96 -22
  26. package/dist/custom/MJEntityFieldPermissionEntityServer.server.d.ts.map +1 -1
  27. package/dist/custom/MJEntityFieldPermissionEntityServer.server.js +239 -55
  28. package/dist/custom/MJEntityFieldPermissionEntityServer.server.js.map +1 -1
  29. package/dist/custom/MJQueryEntityServer.server.d.ts +8 -0
  30. package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
  31. package/dist/custom/MJQueryEntityServer.server.js +45 -2
  32. package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
  33. package/dist/custom/MJUserRoleEntityServer.server.d.ts +74 -7
  34. package/dist/custom/MJUserRoleEntityServer.server.d.ts.map +1 -1
  35. package/dist/custom/MJUserRoleEntityServer.server.js +206 -20
  36. package/dist/custom/MJUserRoleEntityServer.server.js.map +1 -1
  37. package/dist/custom/MJUserViewEntityServer.server.d.ts +17 -1
  38. package/dist/custom/MJUserViewEntityServer.server.d.ts.map +1 -1
  39. package/dist/custom/MJUserViewEntityServer.server.js +95 -7
  40. package/dist/custom/MJUserViewEntityServer.server.js.map +1 -1
  41. package/dist/custom/MJVectorIndexEntityServer.server.d.ts +2 -0
  42. package/dist/custom/MJVectorIndexEntityServer.server.d.ts.map +1 -1
  43. package/dist/custom/MJVectorIndexEntityServer.server.js +33 -0
  44. package/dist/custom/MJVectorIndexEntityServer.server.js.map +1 -1
  45. package/dist/custom/anonymousOwnershipKeyGuard.d.ts +42 -0
  46. package/dist/custom/anonymousOwnershipKeyGuard.d.ts.map +1 -0
  47. package/dist/custom/anonymousOwnershipKeyGuard.js +36 -0
  48. package/dist/custom/anonymousOwnershipKeyGuard.js.map +1 -0
  49. package/dist/custom/approvalStamp.d.ts +37 -0
  50. package/dist/custom/approvalStamp.d.ts.map +1 -0
  51. package/dist/custom/approvalStamp.js +67 -0
  52. package/dist/custom/approvalStamp.js.map +1 -0
  53. package/dist/custom/fieldPermissionAccess.d.ts +31 -0
  54. package/dist/custom/fieldPermissionAccess.d.ts.map +1 -0
  55. package/dist/custom/fieldPermissionAccess.js +38 -0
  56. package/dist/custom/fieldPermissionAccess.js.map +1 -0
  57. package/dist/custom/fieldPermissionReconciler.d.ts.map +1 -1
  58. package/dist/custom/fieldPermissionReconciler.js +12 -2
  59. package/dist/custom/fieldPermissionReconciler.js.map +1 -1
  60. package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
  61. package/dist/custom/query-extraction/resolve.js +25 -7
  62. package/dist/custom/query-extraction/resolve.js.map +1 -1
  63. package/dist/custom/query-extraction/sync.d.ts +1 -1
  64. package/dist/custom/query-extraction/sync.d.ts.map +1 -1
  65. package/dist/custom/query-extraction/sync.js +84 -21
  66. package/dist/custom/query-extraction/sync.js.map +1 -1
  67. package/dist/custom/query-extraction/types.d.ts +4 -0
  68. package/dist/custom/query-extraction/types.d.ts.map +1 -1
  69. package/dist/custom/systemUserGuardState.d.ts +73 -0
  70. package/dist/custom/systemUserGuardState.d.ts.map +1 -0
  71. package/dist/custom/systemUserGuardState.js +161 -0
  72. package/dist/custom/systemUserGuardState.js.map +1 -0
  73. package/dist/custom/template-extraction/parser.js +5 -2
  74. package/dist/custom/template-extraction/parser.js.map +1 -1
  75. package/dist/custom/template-extraction/types.d.ts +1 -1
  76. package/dist/custom/template-extraction/types.d.ts.map +1 -1
  77. package/dist/index.d.ts +5 -0
  78. package/dist/index.d.ts.map +1 -1
  79. package/dist/index.js +5 -0
  80. package/dist/index.js.map +1 -1
  81. package/package.json +30 -30
@@ -1,14 +1,19 @@
1
- import { EntitySaveOptions, ValidationResult } from '@memberjunction/core';
1
+ import { ValidationResult } from '@memberjunction/core';
2
2
  import { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
3
3
  /**
4
4
  * Server-side `MJ: AI Agent Sessions` entity.
5
5
  *
6
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 it
8
- * keeps every save from writing back the **recording ledger's columns** (see {@link Save}). The
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
9
10
  * owner can legitimately write the row — the `UI` and `Widget Guest` roles hold `CanUpdate` on their
10
11
  * own sessions — so the protection has to live at the entity, where the generated CRUD mutations,
11
- * `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.
12
17
  *
13
18
  * See {@link FindProtectedSessionConfigChanges} for what is protected and why, and
14
19
  * `RunWithTrustedSessionConfigWrites` for how server code opts in.
@@ -18,28 +23,6 @@ import { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
18
23
  * out of is not a guard.
19
24
  */
20
25
  export declare class MJAIAgentSessionEntityServer extends MJAIAgentSessionEntity {
21
- /**
22
- * Columns the client-direct recording ledger's stored procedures own (#5294). They change under a live
23
- * session (shard inserts, terminal stamps, assembly claims and finishes) without going through this
24
- * entity.
25
- */
26
- private static readonly recordingLedgerFields;
27
- /**
28
- * Saves without writing back the recording ledger's columns the caller did not change.
29
- *
30
- * An update writes every loaded column, so a session loaded before a ledger procedure ran and saved
31
- * after it (a heartbeat, the close, a delegated tool call that rolls `Config` forward, a verification
32
- * step) would put the stale recording state back: rewind the assembly version and status (a running
33
- * assembly then loses its fence and a superseded one can win it) or clear `RecordingFileID` (a later
34
- * re-assembly then has no file to reuse and writes silence over audio it can no longer recover).
35
- * Marking those fields not-loaded makes the save leave them out of the update procedure, whose
36
- * `ISNULL` keeps the stored values. A field the caller set explicitly (the legacy whole-call upload
37
- * stamps `RecordingFileID`) is dirty and is still saved; an insert takes every column.
38
- *
39
- * `MarkNotLoaded` is the hydration paths' tool; this entity uses it for the same meaning — "this copy
40
- * of the value is not the database's" — at the one place every server-side save converges.
41
- */
42
- Save(options?: EntitySaveOptions): Promise<boolean>;
43
26
  Validate(): ValidationResult;
44
27
  /** Returns a refusal when an untrusted save changes a protected `Config` key, else null. */
45
28
  private checkProtectedConfigKeys;
@@ -1 +1 @@
1
- {"version":3,"file":"MJAIAgentSessionEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentSessionEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,iBAAiB,EAA4C,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEjI,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAGvE;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,4BAA6B,SAAQ,sBAAsB;IACpE;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAG3C;IAEF;;;;;;;;;;;;;;OAcG;IACmB,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAYzD,QAAQ,IAAI,gBAAgB;IAU5C,4FAA4F;IAC5F,OAAO,CAAC,wBAAwB;CAyBnC"}
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"}
@@ -4,20 +4,25 @@ 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
- var MJAIAgentSessionEntityServer_1;
8
7
  import { BaseEntity, ValidationErrorInfo, ValidationErrorType } from '@memberjunction/core';
9
8
  import { RegisterClass } from '@memberjunction/global';
10
9
  import { MJAIAgentSessionEntity } from '@memberjunction/core-entities';
11
10
  import { FindProtectedSessionConfigChanges, IsTrustedSessionConfigWriteActive } from './sessionConfigGuard.js';
11
+ import { CheckAnonymousOwnershipKeyChange, IsSetByTransactionVariable } from './anonymousOwnershipKeyGuard.js';
12
12
  /**
13
13
  * Server-side `MJ: AI Agent Sessions` entity.
14
14
  *
15
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 it
17
- * keeps every save from writing back the **recording ledger's columns** (see {@link Save}). The
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
18
19
  * owner can legitimately write the row — the `UI` and `Widget Guest` roles hold `CanUpdate` on their
19
20
  * own sessions — so the protection has to live at the entity, where the generated CRUD mutations,
20
- * `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.
21
26
  *
22
27
  * See {@link FindProtectedSessionConfigChanges} for what is protected and why, and
23
28
  * `RunWithTrustedSessionConfigWrites` for how server code opts in.
@@ -27,47 +32,14 @@ import { FindProtectedSessionConfigChanges, IsTrustedSessionConfigWriteActive }
27
32
  * out of is not a guard.
28
33
  */
29
34
  let MJAIAgentSessionEntityServer = class MJAIAgentSessionEntityServer extends MJAIAgentSessionEntity {
30
- static { MJAIAgentSessionEntityServer_1 = this; }
31
- /**
32
- * Columns the client-direct recording ledger's stored procedures own (#5294). They change under a live
33
- * session (shard inserts, terminal stamps, assembly claims and finishes) without going through this
34
- * entity.
35
- */
36
- static { this.recordingLedgerFields = [
37
- 'RecordingStatus', 'RecordingExpectedShards', 'RecordingCapturedSamples', 'RecordingGaps',
38
- 'RecordingAssemblyVersion', 'RecordingFileID', 'RecordingMedia',
39
- ]; }
40
- /**
41
- * Saves without writing back the recording ledger's columns the caller did not change.
42
- *
43
- * An update writes every loaded column, so a session loaded before a ledger procedure ran and saved
44
- * after it (a heartbeat, the close, a delegated tool call that rolls `Config` forward, a verification
45
- * step) would put the stale recording state back: rewind the assembly version and status (a running
46
- * assembly then loses its fence and a superseded one can win it) or clear `RecordingFileID` (a later
47
- * re-assembly then has no file to reuse and writes silence over audio it can no longer recover).
48
- * Marking those fields not-loaded makes the save leave them out of the update procedure, whose
49
- * `ISNULL` keeps the stored values. A field the caller set explicitly (the legacy whole-call upload
50
- * stamps `RecordingFileID`) is dirty and is still saved; an insert takes every column.
51
- *
52
- * `MarkNotLoaded` is the hydration paths' tool; this entity uses it for the same meaning — "this copy
53
- * of the value is not the database's" — at the one place every server-side save converges.
54
- */
55
- async Save(options) {
56
- if (this.IsSaved) {
57
- for (const name of MJAIAgentSessionEntityServer_1.recordingLedgerFields) {
58
- const field = this.GetFieldByName(name);
59
- if (field && !field.Dirty) {
60
- field.MarkNotLoaded();
61
- }
62
- }
63
- }
64
- return super.Save(options);
65
- }
66
35
  Validate() {
67
36
  const result = super.Validate();
68
- const violation = this.checkProtectedConfigKeys();
69
- if (violation) {
70
- result.Errors.push(violation);
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);
71
43
  result.Success = false;
72
44
  }
73
45
  return result;
@@ -81,6 +53,11 @@ let MJAIAgentSessionEntityServer = class MJAIAgentSessionEntityServer extends MJ
81
53
  if (!configField) {
82
54
  return null;
83
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
+ }
84
61
  // A saved record is compared against what was loaded; a new record against nothing. For a
85
62
  // saved record whose Config was not touched there is nothing to compare.
86
63
  if (this.IsSaved && !configField.Dirty) {
@@ -94,7 +71,7 @@ let MJAIAgentSessionEntityServer = class MJAIAgentSessionEntityServer extends MJ
94
71
  return new ValidationErrorInfo('Config', `Config keys [${changed.join(', ')}] are server-managed and cannot be set by the session owner.`, null, ValidationErrorType.Failure);
95
72
  }
96
73
  };
97
- MJAIAgentSessionEntityServer = MJAIAgentSessionEntityServer_1 = __decorate([
74
+ MJAIAgentSessionEntityServer = __decorate([
98
75
  RegisterClass(BaseEntity, 'MJ: AI Agent Sessions')
99
76
  ], MJAIAgentSessionEntityServer);
100
77
  export { MJAIAgentSessionEntityServer };
@@ -1 +1 @@
1
- {"version":3,"file":"MJAIAgentSessionEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentSessionEntityServer.server.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAE,UAAU,EAAqB,mBAAmB,EAAE,mBAAmB,EAAoB,MAAM,sBAAsB,CAAC;AACjI,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;;;;;;;;;;;;;;;;GAgBG;AAEI,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,sBAAsB;;IACpE;;;;OAIG;aACqB,0BAAqB,GAA8C;QACvF,iBAAiB,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,eAAe;QACzF,0BAA0B,EAAE,iBAAiB,EAAE,gBAAgB;KAClE,AAH4C,CAG3C;IAEF;;;;;;;;;;;;;;OAcG;IACa,KAAK,CAAC,IAAI,CAAC,OAA2B;QAClD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,KAAK,MAAM,IAAI,IAAI,8BAA4B,CAAC,qBAAqB,EAAE,CAAC;gBACpE,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC;gBACxC,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;oBACxB,KAAK,CAAC,aAAa,EAAE,CAAC;gBAC1B,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAEe,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,wBAAwB,EAAE,CAAC;QAClD,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;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,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;;AAzEQ,4BAA4B;IADxC,aAAa,CAAC,UAAU,EAAE,uBAAuB,CAAC;GACtC,4BAA4B,CA0ExC"}
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,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAK1E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBACa,uBAAwB,SAAQ,yBAAyB;IAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBnD,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"}
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;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAA4B,MAAM,sBAAsB,CAAC;AAEvF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEI,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,yBAAyB;IAClD,KAAK,CAAC,IAAI,CAAC,OAA2B;QAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;QACrD,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QACxE,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,0BAA0B,CAAC,sBAAsB,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;YAC5E,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,IAAI,CAAC,6BAA6B,CAAC;YACrC;gBACI,SAAS,EAAE,wBAAwB;gBACnC,eAAe,EAAE,8BAA8B;gBAC/C,cAAc,EAAE,8CAA8C;gBAC9D,qBAAqB,EAAE,oCAAoC;aAC9D;YACD;gBACI,SAAS,EAAE,iBAAiB;gBAC5B,eAAe,EAAE,uBAAuB;gBACxC,cAAc,EAAE,uCAAuC;gBACvD,qBAAqB,EAAE,6BAA6B;aACvD;SACJ,CAAC,CAAC;QACH,MAAM,UAAU,GAAY,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtD,OAAO,UAAU,CAAC;IACtB,CAAC;IAEe,KAAK,CAAC,MAAM,CAAC,OAA6B;QACtD,MAAM,OAAO,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACvE,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,0BAA0B,CAAC,sBAAsB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YAC3E,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;IAED;;;;OAIG;IACgB,KAAK,CAAC,cAAc,CAAC,WAAmB;QACvD,OAAO,oBAAoB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAED,0GAA0G;IAC1G,IAAY,UAAU;QAClB,OAAO;YACH,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,MAAM,EAAE;gBACJ,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,MAAM,EAAE,IAAI,CAAC,MAAM;gBACnB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,SAAS,EAAE,IAAI,CAAC,SAAS;aAC5B;YACD,eAAe,EAAE,IAAI,CAAC,oBAAoB;YAC1C,gBAAgB,EAAE,IAAI,CAAC,aAA6C;SACvE,CAAC;IACN,CAAC;CACJ,CAAA;AA5DY,uBAAuB;IADnC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC;GAC/B,uBAAuB,CA4DnC"}
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"}
@@ -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 'Error' so the UI can surface the problem.
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,EAA0B,MAAM,+BAA+B,CAAC;AA4C7F,qBACa,0BAA2B,SAAQ,oBAAoB;IAC1C,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAuBzE;;;OAGG;YACW,iBAAiB;IAuE/B;;OAEG;IACH,OAAO,CAAC,eAAe;IAgBvB;;;;OAIG;IACH;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,2BAA2B;CA8BtC"}
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"}