@memberjunction/core-entities-server 6.2.0-edge.2 → 6.2.0-edge.3

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 (64) hide show
  1. package/README.md +7 -3
  2. package/dist/custom/FormComponentGuard.d.ts +48 -0
  3. package/dist/custom/FormComponentGuard.d.ts.map +1 -0
  4. package/dist/custom/FormComponentGuard.js +236 -0
  5. package/dist/custom/FormComponentGuard.js.map +1 -0
  6. package/dist/custom/FormScopeGuard.d.ts +52 -0
  7. package/dist/custom/FormScopeGuard.d.ts.map +1 -0
  8. package/dist/custom/FormScopeGuard.js +111 -0
  9. package/dist/custom/FormScopeGuard.js.map +1 -0
  10. package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts.map +1 -1
  11. package/dist/custom/MJAIAgentExampleEntityServer.server.js +3 -2
  12. package/dist/custom/MJAIAgentExampleEntityServer.server.js.map +1 -1
  13. package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts.map +1 -1
  14. package/dist/custom/MJAIAgentNoteEntityServer.server.js +3 -2
  15. package/dist/custom/MJAIAgentNoteEntityServer.server.js.map +1 -1
  16. package/dist/custom/MJComponentEntityServer.server.d.ts +29 -1
  17. package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
  18. package/dist/custom/MJComponentEntityServer.server.js +62 -3
  19. package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
  20. package/dist/custom/MJEntityFormContributionEntityServer.server.d.ts +37 -0
  21. package/dist/custom/MJEntityFormContributionEntityServer.server.d.ts.map +1 -0
  22. package/dist/custom/MJEntityFormContributionEntityServer.server.js +89 -0
  23. package/dist/custom/MJEntityFormContributionEntityServer.server.js.map +1 -0
  24. package/dist/custom/MJEntityFormOverrideEntityServer.server.d.ts +37 -0
  25. package/dist/custom/MJEntityFormOverrideEntityServer.server.d.ts.map +1 -0
  26. package/dist/custom/MJEntityFormOverrideEntityServer.server.js +89 -0
  27. package/dist/custom/MJEntityFormOverrideEntityServer.server.js.map +1 -0
  28. package/dist/custom/MJInteractionEventEntityServer.server.d.ts +23 -0
  29. package/dist/custom/MJInteractionEventEntityServer.server.d.ts.map +1 -0
  30. package/dist/custom/MJInteractionEventEntityServer.server.js +70 -0
  31. package/dist/custom/MJInteractionEventEntityServer.server.js.map +1 -0
  32. package/dist/custom/MJQueryEntityServer.server.d.ts +9 -1
  33. package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
  34. package/dist/custom/MJQueryEntityServer.server.js +28 -8
  35. package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
  36. package/dist/custom/MJRecordChangeEntityServer.server.d.ts +5 -0
  37. package/dist/custom/MJRecordChangeEntityServer.server.d.ts.map +1 -1
  38. package/dist/custom/MJRecordChangeEntityServer.server.js +30 -1
  39. package/dist/custom/MJRecordChangeEntityServer.server.js.map +1 -1
  40. package/dist/custom/MJTagEntityServer.server.d.ts +1 -1
  41. package/dist/custom/MJTagEntityServer.server.d.ts.map +1 -1
  42. package/dist/custom/MJTagEntityServer.server.js +7 -3
  43. package/dist/custom/MJTagEntityServer.server.js.map +1 -1
  44. package/dist/custom/query-extraction/pipeline.js +1 -1
  45. package/dist/custom/query-extraction/pipeline.js.map +1 -1
  46. package/dist/custom/query-extraction/resolve.d.ts +5 -2
  47. package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
  48. package/dist/custom/query-extraction/resolve.js +6 -3
  49. package/dist/custom/query-extraction/resolve.js.map +1 -1
  50. package/dist/custom/query-extraction/sync.d.ts.map +1 -1
  51. package/dist/custom/query-extraction/sync.js +4 -2
  52. package/dist/custom/query-extraction/sync.js.map +1 -1
  53. package/dist/engines/IdentityClaimEngineServer.d.ts +9 -0
  54. package/dist/engines/IdentityClaimEngineServer.d.ts.map +1 -1
  55. package/dist/engines/IdentityClaimEngineServer.js +38 -8
  56. package/dist/engines/IdentityClaimEngineServer.js.map +1 -1
  57. package/dist/engines/QueryEngineServer.d.ts.map +1 -1
  58. package/dist/engines/QueryEngineServer.js +15 -16
  59. package/dist/engines/QueryEngineServer.js.map +1 -1
  60. package/dist/index.d.ts +4 -0
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +4 -0
  63. package/dist/index.js.map +1 -1
  64. package/package.json +30 -30
@@ -1,12 +1,40 @@
1
- import { EntitySaveOptions, SimpleEmbeddingResult } from "@memberjunction/core";
1
+ import { EntityDeleteOptions, EntitySaveOptions, SimpleEmbeddingResult } from "@memberjunction/core";
2
2
  import { MJComponentEntityExtended } from "@memberjunction/core-entities";
3
+ /**
4
+ * Server-side `MJ: Components` entity.
5
+ *
6
+ * Generates the `FunctionalRequirements` and `TechnicalDesign` embeddings on save.
7
+ *
8
+ * Also guards the component behind a full custom form or panel (`ComponentGuardRefusal`). A form
9
+ * or panel draws the component its row points at, and a form's spec can load a component by name,
10
+ * so a change to a component can change what other people's forms draw:
11
+ * - without the `Manage Form Defaults` grant, any update, whatever columns it changes, and a
12
+ * delete are allowed only for a component of the caller's own (`IsCallersOwnComponent`): used
13
+ * by at least one row and only by the caller's own personal rows, or used by no row and created
14
+ * by the caller;
15
+ * - with the grant, a delete, or an update that changes the specification, status, name,
16
+ * namespace or type, is allowed unless another user's personal row uses the component.
17
+ * Without the grant, a created or renamed component also may not share its name with another
18
+ * component that is not the caller's own. A save or delete with no caller (a trusted server
19
+ * context) is not checked.
20
+ *
21
+ * The rows, the stored columns and the creator are read in one batch as the caller. The creator is
22
+ * the component's `Create` record in `MJ: Record Changes` with `Source` 'Internal', which the
23
+ * platform writes with every insert and which a caller cannot create through the API. The changed columns are
24
+ * found by comparing with the stored row, not with the values as loaded. When a read fails, the
25
+ * write is refused. The check needs a query and `Validate()` is synchronous, so it runs in `Save()`
26
+ * (an ordinary save and a `ReplayOnly` save alike) and in `Delete()`, before the write.
27
+ */
3
28
  export declare class MJComponentEntityServer extends MJComponentEntityExtended {
4
29
  Save(options?: EntitySaveOptions): Promise<boolean>;
30
+ Delete(options?: EntityDeleteOptions): Promise<boolean>;
5
31
  /**
6
32
  * Simple proxy to local helper method for embeddings. Needed for BaseEntity sub-classes that want to use embeddings built into BaseEntity
7
33
  * @param textToEmbed
8
34
  * @returns
9
35
  */
10
36
  protected EmbedTextLocal(textToEmbed: string): Promise<SimpleEmbeddingResult>;
37
+ /** This component as the guard reads it. Built here because `ActiveUser` is protected on `BaseEntity`. */
38
+ private get guardedRow();
11
39
  }
12
40
  //# sourceMappingURL=MJComponentEntityServer.server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MJComponentEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJComponentEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAc,iBAAiB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAE5F,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAG1E,qBACa,uBAAwB,SAAQ,yBAAyB;IAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiBzE;;;;OAIG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;CAG/F"}
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"}
@@ -4,27 +4,70 @@ 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 } from "@memberjunction/core";
7
+ import { BaseEntity, } from "@memberjunction/core";
8
8
  import { RegisterClass } from "@memberjunction/global";
9
9
  import { MJComponentEntityExtended } from "@memberjunction/core-entities";
10
10
  import { EmbedTextLocalHelper } from "./util.js";
11
+ import { FormScopeRefusalResult } from "./FormScopeGuard.js";
12
+ import { ComponentGuardRefusal } from "./FormComponentGuard.js";
13
+ /**
14
+ * Server-side `MJ: Components` entity.
15
+ *
16
+ * Generates the `FunctionalRequirements` and `TechnicalDesign` embeddings on save.
17
+ *
18
+ * Also guards the component behind a full custom form or panel (`ComponentGuardRefusal`). A form
19
+ * or panel draws the component its row points at, and a form's spec can load a component by name,
20
+ * so a change to a component can change what other people's forms draw:
21
+ * - without the `Manage Form Defaults` grant, any update, whatever columns it changes, and a
22
+ * delete are allowed only for a component of the caller's own (`IsCallersOwnComponent`): used
23
+ * by at least one row and only by the caller's own personal rows, or used by no row and created
24
+ * by the caller;
25
+ * - with the grant, a delete, or an update that changes the specification, status, name,
26
+ * namespace or type, is allowed unless another user's personal row uses the component.
27
+ * Without the grant, a created or renamed component also may not share its name with another
28
+ * component that is not the caller's own. A save or delete with no caller (a trusted server
29
+ * context) is not checked.
30
+ *
31
+ * The rows, the stored columns and the creator are read in one batch as the caller. The creator is
32
+ * the component's `Create` record in `MJ: Record Changes` with `Source` 'Internal', which the
33
+ * platform writes with every insert and which a caller cannot create through the API. The changed columns are
34
+ * found by comparing with the stored row, not with the values as loaded. When a read fails, the
35
+ * write is refused. The check needs a query and `Validate()` is synchronous, so it runs in `Save()`
36
+ * (an ordinary save and a `ReplayOnly` save alike) and in `Delete()`, before the write.
37
+ */
11
38
  let MJComponentEntityServer = class MJComponentEntityServer extends MJComponentEntityExtended {
12
39
  async Save(options) {
40
+ const operation = this.IsSaved ? 'update' : 'create';
41
+ const refusal = await ComponentGuardRefusal(this.guardedRow, operation);
42
+ if (refusal) {
43
+ this.RegisterResultHistoryEntry(FormScopeRefusalResult(operation, refusal));
44
+ return false;
45
+ }
13
46
  await this.GenerateEmbeddingsByFieldName([
14
47
  {
15
48
  fieldName: "FunctionalRequirements",
16
49
  vectorFieldName: "FunctionalRequirementsVector",
17
- modelFieldName: "FunctionalRequirementsVectorEmbeddingModelID"
50
+ modelFieldName: "FunctionalRequirementsVectorEmbeddingModelID",
51
+ binaryVectorFieldName: "FunctionalRequirementsVectorBinary"
18
52
  },
19
53
  {
20
54
  fieldName: "TechnicalDesign",
21
55
  vectorFieldName: "TechnicalDesignVector",
22
- modelFieldName: "TechnicalDesignVectorEmbeddingModelID"
56
+ modelFieldName: "TechnicalDesignVectorEmbeddingModelID",
57
+ binaryVectorFieldName: "TechnicalDesignVectorBinary"
23
58
  }
24
59
  ]);
25
60
  const saveResult = await super.Save(options);
26
61
  return saveResult;
27
62
  }
63
+ async Delete(options) {
64
+ const refusal = await ComponentGuardRefusal(this.guardedRow, 'delete');
65
+ if (refusal) {
66
+ this.RegisterResultHistoryEntry(FormScopeRefusalResult('delete', refusal));
67
+ return false;
68
+ }
69
+ return super.Delete(options);
70
+ }
28
71
  /**
29
72
  * Simple proxy to local helper method for embeddings. Needed for BaseEntity sub-classes that want to use embeddings built into BaseEntity
30
73
  * @param textToEmbed
@@ -33,6 +76,22 @@ let MJComponentEntityServer = class MJComponentEntityServer extends MJComponentE
33
76
  async EmbedTextLocal(textToEmbed) {
34
77
  return EmbedTextLocalHelper(this, textToEmbed);
35
78
  }
79
+ /** This component as the guard reads it. Built here because `ActiveUser` is protected on `BaseEntity`. */
80
+ get guardedRow() {
81
+ return {
82
+ ActiveUser: this.ActiveUser,
83
+ ID: this.ID,
84
+ Values: {
85
+ Specification: this.Specification,
86
+ Status: this.Status,
87
+ Name: this.Name,
88
+ Type: this.Type,
89
+ Namespace: this.Namespace,
90
+ },
91
+ RunViewProvider: this.RunViewProviderToUse,
92
+ MetadataProvider: this.ProviderToUse,
93
+ };
94
+ }
36
95
  };
37
96
  MJComponentEntityServer = __decorate([
38
97
  RegisterClass(BaseEntity, 'MJ: Components')
@@ -1 +1 @@
1
- {"version":3,"file":"MJComponentEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJComponentEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,UAAU,EAA4C,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;AAGvC,IAAM,uBAAuB,GAA7B,MAAM,uBAAwB,SAAQ,yBAAyB;IAClD,KAAK,CAAC,IAAI,CAAC,OAA2B;QAClD,MAAM,IAAI,CAAC,6BAA6B,CAAC;YACrC;gBACI,SAAS,EAAE,wBAAwB;gBACnC,eAAe,EAAE,8BAA8B;gBAC/C,cAAc,EAAE,8CAA8C;aACjE;YACD;gBACI,SAAS,EAAE,iBAAiB;gBAC5B,eAAe,EAAE,uBAAuB;gBACxC,cAAc,EAAE,uCAAuC;aAC1D;SACJ,CAAC,CAAC;QACH,MAAM,UAAU,GAAY,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACtD,OAAO,UAAU,CAAC;IACtB,CAAC;IAED;;;;OAIG;IACgB,KAAK,CAAC,cAAc,CAAC,WAAmB;QACvD,OAAO,oBAAoB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;CACJ,CAAA;AA1BY,uBAAuB;IADnC,aAAa,CAAC,UAAU,EAAE,gBAAgB,CAAC;GAC/B,uBAAuB,CA0BnC"}
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"}
@@ -0,0 +1,37 @@
1
+ import { type EntityDeleteOptions, type EntitySaveOptions, type ValidationResult } from '@memberjunction/core';
2
+ import { MJEntityFormContributionEntity } from '@memberjunction/core-entities';
3
+ /**
4
+ * Server-side `MJ: Entity Form Contributions` entity, enforcing who may write a panel at which scope.
5
+ *
6
+ * Anyone may manage their own personal panels. Creating, changing or removing one for a role
7
+ * or for everyone — and moving one between scopes in either direction — needs the
8
+ * `Manage Form Defaults` authorization. The rule lives in `@memberjunction/core-entities`
9
+ * (`FormScopeWriteRefusal`), shared with the browser, so this class only feeds it.
10
+ *
11
+ * All three write entry points are overridden, following `MJUserRoleEntityServer`:
12
+ * `Validate()` runs inside every normal `Save()`; `Save()` is overridden because a `ReplayOnly`
13
+ * save skips `Validate()` while still writing; and `Delete()` never calls `Validate()` at all.
14
+ * Anything less leaves a path around the rule.
15
+ *
16
+ * `Save()` also checks the component the row points at, on create or when `ComponentID` changes
17
+ * (`FormRowComponentGuardRefusal`). Without the grant the component must be the caller's own: used
18
+ * by at least one row and only by the caller's own personal rows, or used by no row and created by
19
+ * the caller, read from its Internal `Create` record change. With the grant, a component another
20
+ * user's personal row uses is refused for everyone, an Owner included, and any other is allowed.
21
+ * That check needs a query, so it runs in `Save()` rather than `Validate()`.
22
+ */
23
+ export declare class MJEntityFormContributionEntityServer extends MJEntityFormContributionEntity {
24
+ Validate(): ValidationResult;
25
+ Save(options?: EntitySaveOptions): Promise<boolean>;
26
+ Delete(options?: EntityDeleteOptions): Promise<boolean>;
27
+ /**
28
+ * This row as the scope guard reads it. Built here because `ActiveUser` is protected on
29
+ * `BaseEntity`, so only the subclass itself can hand it over.
30
+ */
31
+ private get scopeRow();
32
+ /** This row as the component check reads it. */
33
+ private get componentRow();
34
+ /** The provider the caller's authorizations are read from. */
35
+ private get scopeProvider();
36
+ }
37
+ //# sourceMappingURL=MJEntityFormContributionEntityServer.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJEntityFormContributionEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJEntityFormContributionEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAU/E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,oCAAqC,SAAQ,8BAA8B;IACpE,QAAQ,IAAI,gBAAgB;IAMtB,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAUnD,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7E;;;OAGG;IACH,OAAO,KAAK,QAAQ,GAQnB;IAED,gDAAgD;IAChD,OAAO,KAAK,YAAY,GAUvB;IAED,8DAA8D;IAC9D,OAAO,KAAK,aAAa,GAExB;CACJ"}
@@ -0,0 +1,89 @@
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 { MJEntityFormContributionEntity } from '@memberjunction/core-entities';
10
+ import { ApplyFormScopeValidation, FormScopeDeleteRefusal, FormScopeRefusalResult, FormScopeReplayRefusal, } from './FormScopeGuard.js';
11
+ import { FormRowComponentGuardRefusal } from './FormComponentGuard.js';
12
+ /**
13
+ * Server-side `MJ: Entity Form Contributions` entity, enforcing who may write a panel at which scope.
14
+ *
15
+ * Anyone may manage their own personal panels. Creating, changing or removing one for a role
16
+ * or for everyone — and moving one between scopes in either direction — needs the
17
+ * `Manage Form Defaults` authorization. The rule lives in `@memberjunction/core-entities`
18
+ * (`FormScopeWriteRefusal`), shared with the browser, so this class only feeds it.
19
+ *
20
+ * All three write entry points are overridden, following `MJUserRoleEntityServer`:
21
+ * `Validate()` runs inside every normal `Save()`; `Save()` is overridden because a `ReplayOnly`
22
+ * save skips `Validate()` while still writing; and `Delete()` never calls `Validate()` at all.
23
+ * Anything less leaves a path around the rule.
24
+ *
25
+ * `Save()` also checks the component the row points at, on create or when `ComponentID` changes
26
+ * (`FormRowComponentGuardRefusal`). Without the grant the component must be the caller's own: used
27
+ * by at least one row and only by the caller's own personal rows, or used by no row and created by
28
+ * the caller, read from its Internal `Create` record change. With the grant, a component another
29
+ * user's personal row uses is refused for everyone, an Owner included, and any other is allowed.
30
+ * That check needs a query, so it runs in `Save()` rather than `Validate()`.
31
+ */
32
+ let MJEntityFormContributionEntityServer = class MJEntityFormContributionEntityServer extends MJEntityFormContributionEntity {
33
+ Validate() {
34
+ const result = super.Validate();
35
+ ApplyFormScopeValidation(this.scopeRow, this.scopeProvider, result);
36
+ return result;
37
+ }
38
+ async Save(options) {
39
+ const refusal = FormScopeReplayRefusal(this.scopeRow, this.scopeProvider, options)
40
+ ?? await FormRowComponentGuardRefusal(this.componentRow);
41
+ if (refusal) {
42
+ this.RegisterResultHistoryEntry(FormScopeRefusalResult(this.IsSaved ? 'update' : 'create', refusal));
43
+ return false;
44
+ }
45
+ return super.Save(options);
46
+ }
47
+ async Delete(options) {
48
+ const refusal = FormScopeDeleteRefusal(this.scopeRow, this.scopeProvider);
49
+ if (refusal) {
50
+ this.RegisterResultHistoryEntry(FormScopeRefusalResult('delete', refusal));
51
+ return false;
52
+ }
53
+ return super.Delete(options);
54
+ }
55
+ /**
56
+ * This row as the scope guard reads it. Built here because `ActiveUser` is protected on
57
+ * `BaseEntity`, so only the subclass itself can hand it over.
58
+ */
59
+ get scopeRow() {
60
+ return {
61
+ IsSaved: this.IsSaved,
62
+ ActiveUser: this.ActiveUser,
63
+ Scope: this.Scope,
64
+ UserID: this.UserID,
65
+ GetFieldByName: (name) => this.GetFieldByName(name),
66
+ };
67
+ }
68
+ /** This row as the component check reads it. */
69
+ get componentRow() {
70
+ return {
71
+ IsSaved: this.IsSaved,
72
+ ActiveUser: this.ActiveUser,
73
+ ID: this.ID,
74
+ ComponentID: this.ComponentID,
75
+ GetFieldByName: (name) => this.GetFieldByName(name),
76
+ RunViewProvider: this.RunViewProviderToUse,
77
+ MetadataProvider: this.scopeProvider,
78
+ };
79
+ }
80
+ /** The provider the caller's authorizations are read from. */
81
+ get scopeProvider() {
82
+ return this.ProviderToUse;
83
+ }
84
+ };
85
+ MJEntityFormContributionEntityServer = __decorate([
86
+ RegisterClass(BaseEntity, 'MJ: Entity Form Contributions')
87
+ ], MJEntityFormContributionEntityServer);
88
+ export { MJEntityFormContributionEntityServer };
89
+ //# sourceMappingURL=MJEntityFormContributionEntityServer.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJEntityFormContributionEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJEntityFormContributionEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACH,UAAU,GAKb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,8BAA8B,EAAE,MAAM,+BAA+B,CAAC;AAC/E,OAAO,EACH,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,GAEzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,4BAA4B,EAAgC,MAAM,sBAAsB,CAAC;AAElG;;;;;;;;;;;;;;;;;;;GAmBG;AAEI,IAAM,oCAAoC,GAA1C,MAAM,oCAAqC,SAAQ,8BAA8B;IACpE,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC;IAClB,CAAC;IAEe,KAAK,CAAC,IAAI,CAAC,OAA2B;QAClD,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC;eAC3E,MAAM,4BAA4B,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7D,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,0BAA0B,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YACrG,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAEe,KAAK,CAAC,MAAM,CAAC,OAA6B;QACtD,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1E,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;;;OAGG;IACH,IAAY,QAAQ;QAChB,OAAO;YACH,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;SAC9D,CAAC;IACN,CAAC;IAED,gDAAgD;IAChD,IAAY,YAAY;QACpB,OAAO;YACH,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YAC3D,eAAe,EAAE,IAAI,CAAC,oBAAoB;YAC1C,gBAAgB,EAAE,IAAI,CAAC,aAAa;SACvC,CAAC;IACN,CAAC;IAED,8DAA8D;IAC9D,IAAY,aAAa;QACrB,OAAO,IAAI,CAAC,aAA6C,CAAC;IAC9D,CAAC;CACJ,CAAA;AAzDY,oCAAoC;IADhD,aAAa,CAAC,UAAU,EAAE,+BAA+B,CAAC;GAC9C,oCAAoC,CAyDhD"}
@@ -0,0 +1,37 @@
1
+ import { type EntityDeleteOptions, type EntitySaveOptions, type ValidationResult } from '@memberjunction/core';
2
+ import { MJEntityFormOverrideEntity } from '@memberjunction/core-entities';
3
+ /**
4
+ * Server-side `MJ: Entity Form Overrides` entity, enforcing who may write a full custom form at which scope.
5
+ *
6
+ * Anyone may manage their own personal forms. Creating, changing or removing one for a role
7
+ * or for everyone — and moving one between scopes in either direction — needs the
8
+ * `Manage Form Defaults` authorization. The rule lives in `@memberjunction/core-entities`
9
+ * (`FormScopeWriteRefusal`), shared with the browser, so this class only feeds it.
10
+ *
11
+ * All three write entry points are overridden, following `MJUserRoleEntityServer`:
12
+ * `Validate()` runs inside every normal `Save()`; `Save()` is overridden because a `ReplayOnly`
13
+ * save skips `Validate()` while still writing; and `Delete()` never calls `Validate()` at all.
14
+ * Anything less leaves a path around the rule.
15
+ *
16
+ * `Save()` also checks the component the row points at, on create or when `ComponentID` changes
17
+ * (`FormRowComponentGuardRefusal`). Without the grant the component must be the caller's own: used
18
+ * by at least one row and only by the caller's own personal rows, or used by no row and created by
19
+ * the caller, read from its Internal `Create` record change. With the grant, a component another
20
+ * user's personal row uses is refused for everyone, an Owner included, and any other is allowed.
21
+ * That check needs a query, so it runs in `Save()` rather than `Validate()`.
22
+ */
23
+ export declare class MJEntityFormOverrideEntityServer extends MJEntityFormOverrideEntity {
24
+ Validate(): ValidationResult;
25
+ Save(options?: EntitySaveOptions): Promise<boolean>;
26
+ Delete(options?: EntityDeleteOptions): Promise<boolean>;
27
+ /**
28
+ * This row as the scope guard reads it. Built here because `ActiveUser` is protected on
29
+ * `BaseEntity`, so only the subclass itself can hand it over.
30
+ */
31
+ private get scopeRow();
32
+ /** This row as the component check reads it. */
33
+ private get componentRow();
34
+ /** The provider the caller's authorizations are read from. */
35
+ private get scopeProvider();
36
+ }
37
+ //# sourceMappingURL=MJEntityFormOverrideEntityServer.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJEntityFormOverrideEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJEntityFormOverrideEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EAEtB,KAAK,gBAAgB,EACxB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAU3E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBACa,gCAAiC,SAAQ,0BAA0B;IAC5D,QAAQ,IAAI,gBAAgB;IAMtB,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAUnD,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAS7E;;;OAGG;IACH,OAAO,KAAK,QAAQ,GAQnB;IAED,gDAAgD;IAChD,OAAO,KAAK,YAAY,GAUvB;IAED,8DAA8D;IAC9D,OAAO,KAAK,aAAa,GAExB;CACJ"}
@@ -0,0 +1,89 @@
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 { MJEntityFormOverrideEntity } from '@memberjunction/core-entities';
10
+ import { ApplyFormScopeValidation, FormScopeDeleteRefusal, FormScopeRefusalResult, FormScopeReplayRefusal, } from './FormScopeGuard.js';
11
+ import { FormRowComponentGuardRefusal } from './FormComponentGuard.js';
12
+ /**
13
+ * Server-side `MJ: Entity Form Overrides` entity, enforcing who may write a full custom form at which scope.
14
+ *
15
+ * Anyone may manage their own personal forms. Creating, changing or removing one for a role
16
+ * or for everyone — and moving one between scopes in either direction — needs the
17
+ * `Manage Form Defaults` authorization. The rule lives in `@memberjunction/core-entities`
18
+ * (`FormScopeWriteRefusal`), shared with the browser, so this class only feeds it.
19
+ *
20
+ * All three write entry points are overridden, following `MJUserRoleEntityServer`:
21
+ * `Validate()` runs inside every normal `Save()`; `Save()` is overridden because a `ReplayOnly`
22
+ * save skips `Validate()` while still writing; and `Delete()` never calls `Validate()` at all.
23
+ * Anything less leaves a path around the rule.
24
+ *
25
+ * `Save()` also checks the component the row points at, on create or when `ComponentID` changes
26
+ * (`FormRowComponentGuardRefusal`). Without the grant the component must be the caller's own: used
27
+ * by at least one row and only by the caller's own personal rows, or used by no row and created by
28
+ * the caller, read from its Internal `Create` record change. With the grant, a component another
29
+ * user's personal row uses is refused for everyone, an Owner included, and any other is allowed.
30
+ * That check needs a query, so it runs in `Save()` rather than `Validate()`.
31
+ */
32
+ let MJEntityFormOverrideEntityServer = class MJEntityFormOverrideEntityServer extends MJEntityFormOverrideEntity {
33
+ Validate() {
34
+ const result = super.Validate();
35
+ ApplyFormScopeValidation(this.scopeRow, this.scopeProvider, result);
36
+ return result;
37
+ }
38
+ async Save(options) {
39
+ const refusal = FormScopeReplayRefusal(this.scopeRow, this.scopeProvider, options)
40
+ ?? await FormRowComponentGuardRefusal(this.componentRow);
41
+ if (refusal) {
42
+ this.RegisterResultHistoryEntry(FormScopeRefusalResult(this.IsSaved ? 'update' : 'create', refusal));
43
+ return false;
44
+ }
45
+ return super.Save(options);
46
+ }
47
+ async Delete(options) {
48
+ const refusal = FormScopeDeleteRefusal(this.scopeRow, this.scopeProvider);
49
+ if (refusal) {
50
+ this.RegisterResultHistoryEntry(FormScopeRefusalResult('delete', refusal));
51
+ return false;
52
+ }
53
+ return super.Delete(options);
54
+ }
55
+ /**
56
+ * This row as the scope guard reads it. Built here because `ActiveUser` is protected on
57
+ * `BaseEntity`, so only the subclass itself can hand it over.
58
+ */
59
+ get scopeRow() {
60
+ return {
61
+ IsSaved: this.IsSaved,
62
+ ActiveUser: this.ActiveUser,
63
+ Scope: this.Scope,
64
+ UserID: this.UserID,
65
+ GetFieldByName: (name) => this.GetFieldByName(name),
66
+ };
67
+ }
68
+ /** This row as the component check reads it. */
69
+ get componentRow() {
70
+ return {
71
+ IsSaved: this.IsSaved,
72
+ ActiveUser: this.ActiveUser,
73
+ ID: this.ID,
74
+ ComponentID: this.ComponentID,
75
+ GetFieldByName: (name) => this.GetFieldByName(name),
76
+ RunViewProvider: this.RunViewProviderToUse,
77
+ MetadataProvider: this.scopeProvider,
78
+ };
79
+ }
80
+ /** The provider the caller's authorizations are read from. */
81
+ get scopeProvider() {
82
+ return this.ProviderToUse;
83
+ }
84
+ };
85
+ MJEntityFormOverrideEntityServer = __decorate([
86
+ RegisterClass(BaseEntity, 'MJ: Entity Form Overrides')
87
+ ], MJEntityFormOverrideEntityServer);
88
+ export { MJEntityFormOverrideEntityServer };
89
+ //# sourceMappingURL=MJEntityFormOverrideEntityServer.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJEntityFormOverrideEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJEntityFormOverrideEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EACH,UAAU,GAKb,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EACH,wBAAwB,EACxB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,GAEzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,4BAA4B,EAAgC,MAAM,sBAAsB,CAAC;AAElG;;;;;;;;;;;;;;;;;;;GAmBG;AAEI,IAAM,gCAAgC,GAAtC,MAAM,gCAAiC,SAAQ,0BAA0B;IAC5D,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;QACpE,OAAO,MAAM,CAAC;IAClB,CAAC;IAEe,KAAK,CAAC,IAAI,CAAC,OAA2B;QAClD,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,CAAC;eAC3E,MAAM,4BAA4B,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC7D,IAAI,OAAO,EAAE,CAAC;YACV,IAAI,CAAC,0BAA0B,CAAC,sBAAsB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YACrG,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAEe,KAAK,CAAC,MAAM,CAAC,OAA6B;QACtD,MAAM,OAAO,GAAG,sBAAsB,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1E,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;;;OAGG;IACH,IAAY,QAAQ;QAChB,OAAO;YACH,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;SAC9D,CAAC;IACN,CAAC;IAED,gDAAgD;IAChD,IAAY,YAAY;QACpB,OAAO;YACH,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,UAAU,EAAE,IAAI,CAAC,UAAU;YAC3B,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,cAAc,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC;YAC3D,eAAe,EAAE,IAAI,CAAC,oBAAoB;YAC1C,gBAAgB,EAAE,IAAI,CAAC,aAAa;SACvC,CAAC;IACN,CAAC;IAED,8DAA8D;IAC9D,IAAY,aAAa;QACrB,OAAO,IAAI,CAAC,aAA6C,CAAC;IAC9D,CAAC;CACJ,CAAA;AAzDY,gCAAgC;IAD5C,aAAa,CAAC,UAAU,EAAE,2BAA2B,CAAC;GAC1C,gCAAgC,CAyD5C"}
@@ -0,0 +1,23 @@
1
+ import { EntityDeleteOptions, EntityPermissionType, EntitySaveOptions, ValidationResult } from '@memberjunction/core';
2
+ import { MJInteractionEventEntity } from '@memberjunction/core-entities';
3
+ /**
4
+ * Server subclass for `MJ: Interaction Events`.
5
+ *
6
+ * Implements the append-only lifecycle log invariant:
7
+ * Interaction events are strictly append-only. Once an event is inserted,
8
+ * any update or deletion attempt is prohibited to ensure audit trail integrity.
9
+ */
10
+ export declare class MJInteractionEventEntityServer extends MJInteractionEventEntity {
11
+ static readonly APPEND_ONLY_UPDATE_MESSAGE = "Interaction Events are append-only: updates are prohibited.";
12
+ static readonly APPEND_ONLY_DELETE_MESSAGE = "Interaction Events are append-only: deletes are prohibited.";
13
+ CheckPermissions(type: EntityPermissionType, throwError: boolean): boolean;
14
+ Validate(): ValidationResult;
15
+ Save(options?: EntitySaveOptions): Promise<boolean>;
16
+ Delete(_options?: EntityDeleteOptions): Promise<boolean>;
17
+ private refuse;
18
+ }
19
+ /**
20
+ * Loader stub — prevents the class from being tree-shaken out of the bundle.
21
+ */
22
+ export declare function LoadMJInteractionEventEntityServer(): void;
23
+ //# sourceMappingURL=MJInteractionEventEntityServer.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJInteractionEventEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJInteractionEventEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAGH,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EAGjB,gBAAgB,EACnB,MAAM,sBAAsB,CAAC;AAE9B,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE;;;;;;GAMG;AACH,qBACa,8BAA+B,SAAQ,wBAAwB;IACxE,gBAAuB,0BAA0B,iEAAiE;IAClH,gBAAuB,0BAA0B,iEAAiE;IAElG,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO;IAW1E,QAAQ,IAAI,gBAAgB;IAgBtB,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAOnD,MAAM,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAI9E,OAAO,CAAC,MAAM;CAUjB;AAED;;GAEG;AACH,wBAAgB,kCAAkC,IAAI,IAAI,CAEzD"}
@@ -0,0 +1,70 @@
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 MJInteractionEventEntityServer_1;
8
+ import { BaseEntity, BaseEntityResult, EntityPermissionType, ValidationErrorInfo, ValidationErrorType, } from '@memberjunction/core';
9
+ import { RegisterClass } from '@memberjunction/global';
10
+ import { MJInteractionEventEntity } from '@memberjunction/core-entities';
11
+ /**
12
+ * Server subclass for `MJ: Interaction Events`.
13
+ *
14
+ * Implements the append-only lifecycle log invariant:
15
+ * Interaction events are strictly append-only. Once an event is inserted,
16
+ * any update or deletion attempt is prohibited to ensure audit trail integrity.
17
+ */
18
+ let MJInteractionEventEntityServer = class MJInteractionEventEntityServer extends MJInteractionEventEntity {
19
+ static { MJInteractionEventEntityServer_1 = this; }
20
+ static { this.APPEND_ONLY_UPDATE_MESSAGE = 'Interaction Events are append-only: updates are prohibited.'; }
21
+ static { this.APPEND_ONLY_DELETE_MESSAGE = 'Interaction Events are append-only: deletes are prohibited.'; }
22
+ CheckPermissions(type, throwError) {
23
+ if (type === EntityPermissionType.Update || type === EntityPermissionType.Delete) {
24
+ const msg = `Interaction Events are append-only: updates and deletes are prohibited.`;
25
+ if (throwError) {
26
+ throw new Error(msg);
27
+ }
28
+ return false;
29
+ }
30
+ return super.CheckPermissions(type, throwError);
31
+ }
32
+ Validate() {
33
+ const result = super.Validate();
34
+ if (this.IsSaved) {
35
+ result.Success = false;
36
+ result.Errors.push(new ValidationErrorInfo('ID', MJInteractionEventEntityServer_1.APPEND_ONLY_UPDATE_MESSAGE, this.ID, ValidationErrorType.Failure));
37
+ }
38
+ return result;
39
+ }
40
+ async Save(options) {
41
+ if (this.IsSaved) {
42
+ return this.refuse('update', MJInteractionEventEntityServer_1.APPEND_ONLY_UPDATE_MESSAGE);
43
+ }
44
+ return super.Save(options);
45
+ }
46
+ async Delete(_options) {
47
+ return this.refuse('delete', MJInteractionEventEntityServer_1.APPEND_ONLY_DELETE_MESSAGE);
48
+ }
49
+ refuse(type, message) {
50
+ const result = new BaseEntityResult();
51
+ result.Success = false;
52
+ result.Type = type;
53
+ result.Message = message;
54
+ result.StartedAt = new Date();
55
+ result.EndedAt = new Date();
56
+ this.RegisterResultHistoryEntry(result);
57
+ return false;
58
+ }
59
+ };
60
+ MJInteractionEventEntityServer = MJInteractionEventEntityServer_1 = __decorate([
61
+ RegisterClass(BaseEntity, 'MJ: Interaction Events')
62
+ ], MJInteractionEventEntityServer);
63
+ export { MJInteractionEventEntityServer };
64
+ /**
65
+ * Loader stub — prevents the class from being tree-shaken out of the bundle.
66
+ */
67
+ export function LoadMJInteractionEventEntityServer() {
68
+ void MJInteractionEventEntityServer;
69
+ }
70
+ //# sourceMappingURL=MJInteractionEventEntityServer.server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MJInteractionEventEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJInteractionEventEntityServer.server.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EACH,UAAU,EACV,gBAAgB,EAEhB,oBAAoB,EAEpB,mBAAmB,EACnB,mBAAmB,GAEtB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE;;;;;;GAMG;AAEI,IAAM,8BAA8B,GAApC,MAAM,8BAA+B,SAAQ,wBAAwB;;aACjD,+BAA0B,GAAG,6DAA6D,AAAhE,CAAiE;aAC3F,+BAA0B,GAAG,6DAA6D,AAAhE,CAAiE;IAElG,gBAAgB,CAAC,IAA0B,EAAE,UAAmB;QAC5E,IAAI,IAAI,KAAK,oBAAoB,CAAC,MAAM,IAAI,IAAI,KAAK,oBAAoB,CAAC,MAAM,EAAE,CAAC;YAC/E,MAAM,GAAG,GAAG,yEAAyE,CAAC;YACtF,IAAI,UAAU,EAAE,CAAC;gBACb,MAAM,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,KAAK,CAAC,gBAAgB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;IAEe,QAAQ;QACpB,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;YACvB,MAAM,CAAC,MAAM,CAAC,IAAI,CACd,IAAI,mBAAmB,CACnB,IAAI,EACJ,gCAA8B,CAAC,0BAA0B,EACzD,IAAI,CAAC,EAAE,EACP,mBAAmB,CAAC,OAAO,CAC9B,CACJ,CAAC;QACN,CAAC;QACD,OAAO,MAAM,CAAC;IAClB,CAAC;IAEe,KAAK,CAAC,IAAI,CAAC,OAA2B;QAClD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,gCAA8B,CAAC,0BAA0B,CAAC,CAAC;QAC5F,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAEe,KAAK,CAAC,MAAM,CAAC,QAA8B;QACvD,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,gCAA8B,CAAC,0BAA0B,CAAC,CAAC;IAC5F,CAAC;IAEO,MAAM,CAAC,IAAoC,EAAE,OAAe;QAChE,MAAM,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACtC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC;QACzB,MAAM,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;QAC9B,MAAM,CAAC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,0BAA0B,CAAC,MAAM,CAAC,CAAC;QACxC,OAAO,KAAK,CAAC;IACjB,CAAC;;AAnDQ,8BAA8B;IAD1C,aAAa,CAAC,UAAU,EAAE,wBAAwB,CAAC;GACvC,8BAA8B,CAoD1C;;AAED;;GAEG;AACH,MAAM,UAAU,kCAAkC;IAC9C,KAAK,8BAA8B,CAAC;AACxC,CAAC"}
@@ -17,9 +17,17 @@ export declare class MJQueryEntityServer extends MJQueryEntityExtended {
17
17
  protected EmbedTextLocal(textToEmbed: string): Promise<SimpleEmbeddingResult>;
18
18
  /**
19
19
  * Generates an embedding from composite text (Name + UserQuestion + Description) for richer semantic search.
20
- * Stores the vector in EmbeddingVector and the model reference in EmbeddingModelID.
20
+ * Stores the vector in EmbeddingVector (JSON) and EmbeddingVectorBinary (float32 bytes, base64), and the
21
+ * model reference in EmbeddingModelID.
22
+ *
23
+ * Same contract as `MJTagEntityServer`: when no vector comes back — empty text, an empty result or an
24
+ * embedder error — all three columns are cleared, so a query whose text changed never keeps a vector
25
+ * computed from its old text. An embedder error is logged and does not fail the save; the query simply
26
+ * has no semantic match until its next successful embedding.
21
27
  */
22
28
  protected GenerateCompositeEmbedding(): Promise<void>;
29
+ /** Clears the stored vector (both forms) and the model it was computed with. */
30
+ private clearEmbedding;
23
31
  Save(options?: EntitySaveOptions): Promise<boolean>;
24
32
  Delete(options?: EntitySaveOptions): Promise<boolean>;
25
33
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"MJQueryEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJQueryEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,iBAAiB,EAGjB,qBAAqB,EAExB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAoB,qBAAqB,EAAmC,MAAM,+BAA+B,CAAC;AAazH;;;;GAIG;AACH,qBACa,mBAAoB,SAAQ,qBAAqB;IAC1D;;;yEAGqE;IAC9D,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI5C;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5F;;;OAGG;cACa,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IAuB5C,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAwCnD,MAAM,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpE;;;OAGG;IACH,OAAO,KAAK,eAAe,GAE1B;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;;;;;;;OAQG;IACH,OAAO,CAAC,4BAA4B;IAgBpC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;;;;OAKG;IACU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7C;;;OAGG;YACW,uBAAuB;IAsBrC;;OAEG;YACW,sBAAsB;IAmBpC;;;OAGG;YACW,wBAAwB;IAiCtC;;OAEG;YACW,sBAAsB;IA4BpC;;OAEG;YACW,oBAAoB;IA4BlC;;OAEG;YACW,6BAA6B;CAgB9C"}
1
+ {"version":3,"file":"MJQueryEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJQueryEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAEH,iBAAiB,EAGjB,qBAAqB,EAExB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAoB,qBAAqB,EAAmC,MAAM,+BAA+B,CAAC;AAazH;;;;GAIG;AACH,qBACa,mBAAoB,SAAQ,qBAAqB;IAC1D;;;yEAGqE;IAC9D,cAAc,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAI5C;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5F;;;;;;;;;OASG;cACa,0BAA0B,IAAI,OAAO,CAAC,IAAI,CAAC;IA2B3D,gFAAgF;IAChF,OAAO,CAAC,cAAc;IAQP,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAyCnD,MAAM,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAgBpE;;;OAGG;IACH,OAAO,KAAK,eAAe,GAE1B;IAED;;;;;;;;;;OAUG;IACH,OAAO,CAAC,oBAAoB;IAmB5B;;;;;;;;OAQG;IACH,OAAO,CAAC,4BAA4B;IAgBpC;;;OAGG;IACH,OAAO,CAAC,gBAAgB;IAcxB;;;;;OAKG;IACU,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC;IAI7C;;;OAGG;YACW,uBAAuB;IAsBrC;;OAEG;YACW,sBAAsB;IAmBpC;;;OAGG;YACW,wBAAwB;IAiCtC;;OAEG;YACW,sBAAsB;IA4BpC;;OAEG;YACW,oBAAoB;IA4BlC;;OAEG;YACW,6BAA6B;CAgB9C"}
@@ -6,7 +6,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { BaseEntity, LogError, } from "@memberjunction/core";
8
8
  import { MJQueryEntityExtended, QueryEngine } from "@memberjunction/core-entities";
9
- import { RegisterClass, MJGlobal, UUIDsEqual } from "@memberjunction/global";
9
+ import { Float32VectorToBase64, RegisterClass, MJGlobal, UUIDsEqual } from "@memberjunction/global";
10
10
  import { EmbedTextLocalHelper } from "./util.js";
11
11
  import { RunExtractionPipeline, CleanupQueryData, ConvertTSQLToPostgreSQL, } from "./query-extraction/index.js";
12
12
  import { SQLParser } from "@memberjunction/sql-parser";
@@ -27,7 +27,13 @@ let MJQueryEntityServer = class MJQueryEntityServer extends MJQueryEntityExtende
27
27
  }
28
28
  /**
29
29
  * Generates an embedding from composite text (Name + UserQuestion + Description) for richer semantic search.
30
- * Stores the vector in EmbeddingVector and the model reference in EmbeddingModelID.
30
+ * Stores the vector in EmbeddingVector (JSON) and EmbeddingVectorBinary (float32 bytes, base64), and the
31
+ * model reference in EmbeddingModelID.
32
+ *
33
+ * Same contract as `MJTagEntityServer`: when no vector comes back — empty text, an empty result or an
34
+ * embedder error — all three columns are cleared, so a query whose text changed never keeps a vector
35
+ * computed from its old text. An embedder error is logged and does not fail the save; the query simply
36
+ * has no semantic match until its next successful embedding.
31
37
  */
32
38
  async GenerateCompositeEmbedding() {
33
39
  const parts = [
@@ -36,16 +42,29 @@ let MJQueryEntityServer = class MJQueryEntityServer extends MJQueryEntityExtende
36
42
  this.Description || ''
37
43
  ].filter(p => p.trim().length > 0);
38
44
  if (parts.length === 0) {
39
- this.EmbeddingVector = null;
40
- this.EmbeddingModelID = null;
45
+ this.clearEmbedding();
41
46
  return;
42
47
  }
43
48
  const compositeText = parts.join(' | ');
44
- const result = await this.EmbedTextLocal(compositeText);
45
- if (result && result.vector && result.vector.length > 0) {
46
- this.EmbeddingVector = JSON.stringify(result.vector);
47
- this.EmbeddingModelID = result.modelID;
49
+ try {
50
+ const result = await this.EmbedTextLocal(compositeText);
51
+ if (result?.vector && result.vector.length > 0) {
52
+ this.EmbeddingVector = JSON.stringify(result.vector);
53
+ this.EmbeddingVectorBinary = Float32VectorToBase64(result.vector);
54
+ this.EmbeddingModelID = result.modelID;
55
+ return;
56
+ }
57
+ }
58
+ catch (error) {
59
+ LogError(`[MJQueryEntityServer] Embedding refresh failed for query "${this.Name}": ${error instanceof Error ? error.message : String(error)}`);
48
60
  }
61
+ this.clearEmbedding();
62
+ }
63
+ /** Clears the stored vector (both forms) and the model it was computed with. */
64
+ clearEmbedding() {
65
+ this.EmbeddingVector = null;
66
+ this.EmbeddingVectorBinary = null;
67
+ this.EmbeddingModelID = null;
49
68
  }
50
69
  // ─── Save / Delete Overrides ─────────────────────────────────────────────────
51
70
  async Save(options) {
@@ -62,6 +81,7 @@ let MJQueryEntityServer = class MJQueryEntityServer extends MJQueryEntityExtende
62
81
  }
63
82
  else if (!this.Description || this.Description.trim().length === 0) {
64
83
  this.EmbeddingVector = null;
84
+ this.EmbeddingVectorBinary = null;
65
85
  this.EmbeddingModelID = null;
66
86
  }
67
87
  // Save the query first without AI processing