@memberjunction/core-entities-server 6.2.0-edge.6 → 6.2.0-edge.8

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 (179) hide show
  1. package/README.md +155 -100
  2. package/dist/custom/AnchoredConversationReadSecurityHook.d.ts +22 -0
  3. package/dist/custom/AnchoredConversationReadSecurityHook.d.ts.map +1 -0
  4. package/dist/custom/AnchoredConversationReadSecurityHook.js +293 -0
  5. package/dist/custom/AnchoredConversationReadSecurityHook.js.map +1 -0
  6. package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts +2 -0
  7. package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts.map +1 -1
  8. package/dist/custom/MJAIAgentExampleEntityServer.server.js +8 -5
  9. package/dist/custom/MJAIAgentExampleEntityServer.server.js.map +1 -1
  10. package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts +2 -0
  11. package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts.map +1 -1
  12. package/dist/custom/MJAIAgentNoteEntityServer.server.js +8 -5
  13. package/dist/custom/MJAIAgentNoteEntityServer.server.js.map +1 -1
  14. package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts +17 -0
  15. package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts.map +1 -0
  16. package/dist/custom/MJAIAgentRelationshipEntityServer.server.js +71 -0
  17. package/dist/custom/MJAIAgentRelationshipEntityServer.server.js.map +1 -0
  18. package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts +8 -22
  19. package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts.map +1 -1
  20. package/dist/custom/MJAIAgentSessionEntityServer.server.js +24 -1
  21. package/dist/custom/MJAIAgentSessionEntityServer.server.js.map +1 -1
  22. package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts +23 -0
  23. package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts.map +1 -0
  24. package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js +53 -0
  25. package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js.map +1 -0
  26. package/dist/custom/MJAIPromptEntityServer.server.d.ts.map +1 -1
  27. package/dist/custom/MJAIPromptEntityServer.server.js +2 -1
  28. package/dist/custom/MJAIPromptEntityServer.server.js.map +1 -1
  29. package/dist/custom/MJBrandKitEntityServer.server.d.ts +14 -0
  30. package/dist/custom/MJBrandKitEntityServer.server.d.ts.map +1 -0
  31. package/dist/custom/MJBrandKitEntityServer.server.js +75 -0
  32. package/dist/custom/MJBrandKitEntityServer.server.js.map +1 -0
  33. package/dist/custom/MJCompanyIntegrationEntityServer.server.d.ts.map +1 -1
  34. package/dist/custom/MJCompanyIntegrationEntityServer.server.js +1 -0
  35. package/dist/custom/MJCompanyIntegrationEntityServer.server.js.map +1 -1
  36. package/dist/custom/MJComponentEntityServer.server.d.ts +2 -0
  37. package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
  38. package/dist/custom/MJComponentEntityServer.server.js +5 -1
  39. package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
  40. package/dist/custom/MJConversationDetailEntityServer.server.d.ts +20 -30
  41. package/dist/custom/MJConversationDetailEntityServer.server.d.ts.map +1 -1
  42. package/dist/custom/MJConversationDetailEntityServer.server.js +89 -35
  43. package/dist/custom/MJConversationDetailEntityServer.server.js.map +1 -1
  44. package/dist/custom/MJConversationEntityServer.server.d.ts +19 -4
  45. package/dist/custom/MJConversationEntityServer.server.d.ts.map +1 -1
  46. package/dist/custom/MJConversationEntityServer.server.js +169 -11
  47. package/dist/custom/MJConversationEntityServer.server.js.map +1 -1
  48. package/dist/custom/MJEntityDocumentEntityServer.server.d.ts.map +1 -1
  49. package/dist/custom/MJEntityDocumentEntityServer.server.js +1 -0
  50. package/dist/custom/MJEntityDocumentEntityServer.server.js.map +1 -1
  51. package/dist/custom/MJListDetailEntityServer.server.d.ts.map +1 -1
  52. package/dist/custom/MJListDetailEntityServer.server.js +1 -0
  53. package/dist/custom/MJListDetailEntityServer.server.js.map +1 -1
  54. package/dist/custom/MJProjectEntityServer.server.d.ts +21 -0
  55. package/dist/custom/MJProjectEntityServer.server.d.ts.map +1 -0
  56. package/dist/custom/MJProjectEntityServer.server.js +106 -0
  57. package/dist/custom/MJProjectEntityServer.server.js.map +1 -0
  58. package/dist/custom/MJQueryEntityServer.server.d.ts +177 -47
  59. package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
  60. package/dist/custom/MJQueryEntityServer.server.js +479 -164
  61. package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
  62. package/dist/custom/MJQuerySQLEntityServer.server.d.ts +15 -18
  63. package/dist/custom/MJQuerySQLEntityServer.server.d.ts.map +1 -1
  64. package/dist/custom/MJQuerySQLEntityServer.server.js +34 -42
  65. package/dist/custom/MJQuerySQLEntityServer.server.js.map +1 -1
  66. package/dist/custom/MJTagEntityServer.server.d.ts +2 -0
  67. package/dist/custom/MJTagEntityServer.server.d.ts.map +1 -1
  68. package/dist/custom/MJTagEntityServer.server.js +13 -7
  69. package/dist/custom/MJTagEntityServer.server.js.map +1 -1
  70. package/dist/custom/MJUserRoutineEntityServer.server.d.ts.map +1 -1
  71. package/dist/custom/MJUserRoutineEntityServer.server.js +8 -1
  72. package/dist/custom/MJUserRoutineEntityServer.server.js.map +1 -1
  73. package/dist/custom/RestrictedFieldCommentClassifier.d.ts +73 -0
  74. package/dist/custom/RestrictedFieldCommentClassifier.d.ts.map +1 -0
  75. package/dist/custom/RestrictedFieldCommentClassifier.js +240 -0
  76. package/dist/custom/RestrictedFieldCommentClassifier.js.map +1 -0
  77. package/dist/custom/query-extraction/childRowWriter.d.ts +77 -0
  78. package/dist/custom/query-extraction/childRowWriter.d.ts.map +1 -0
  79. package/dist/custom/query-extraction/childRowWriter.js +277 -0
  80. package/dist/custom/query-extraction/childRowWriter.js.map +1 -0
  81. package/dist/custom/query-extraction/compositionTargets.d.ts +40 -0
  82. package/dist/custom/query-extraction/compositionTargets.d.ts.map +1 -0
  83. package/dist/custom/query-extraction/compositionTargets.js +99 -0
  84. package/dist/custom/query-extraction/compositionTargets.js.map +1 -0
  85. package/dist/custom/query-extraction/declared.d.ts +79 -0
  86. package/dist/custom/query-extraction/declared.d.ts.map +1 -0
  87. package/dist/custom/query-extraction/declared.js +91 -0
  88. package/dist/custom/query-extraction/declared.js.map +1 -0
  89. package/dist/custom/query-extraction/describeFacts.d.ts +40 -0
  90. package/dist/custom/query-extraction/describeFacts.d.ts.map +1 -0
  91. package/dist/custom/query-extraction/describeFacts.js +225 -0
  92. package/dist/custom/query-extraction/describeFacts.js.map +1 -0
  93. package/dist/custom/query-extraction/descriptionPass.d.ts +23 -0
  94. package/dist/custom/query-extraction/descriptionPass.d.ts.map +1 -0
  95. package/dist/custom/query-extraction/descriptionPass.js +95 -0
  96. package/dist/custom/query-extraction/descriptionPass.js.map +1 -0
  97. package/dist/custom/query-extraction/extractQuery.d.ts +25 -0
  98. package/dist/custom/query-extraction/extractQuery.d.ts.map +1 -0
  99. package/dist/custom/query-extraction/extractQuery.js +146 -0
  100. package/dist/custom/query-extraction/extractQuery.js.map +1 -0
  101. package/dist/custom/query-extraction/extractionTypes.d.ts +133 -0
  102. package/dist/custom/query-extraction/extractionTypes.d.ts.map +1 -0
  103. package/dist/custom/query-extraction/extractionTypes.js +2 -0
  104. package/dist/custom/query-extraction/extractionTypes.js.map +1 -0
  105. package/dist/custom/query-extraction/index.d.ts +16 -0
  106. package/dist/custom/query-extraction/index.d.ts.map +1 -1
  107. package/dist/custom/query-extraction/index.js +11 -1
  108. package/dist/custom/query-extraction/index.js.map +1 -1
  109. package/dist/custom/query-extraction/pipeline.d.ts +6 -2
  110. package/dist/custom/query-extraction/pipeline.d.ts.map +1 -1
  111. package/dist/custom/query-extraction/pipeline.js +21 -14
  112. package/dist/custom/query-extraction/pipeline.js.map +1 -1
  113. package/dist/custom/query-extraction/resolve.d.ts +7 -2
  114. package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
  115. package/dist/custom/query-extraction/resolve.js +17 -14
  116. package/dist/custom/query-extraction/resolve.js.map +1 -1
  117. package/dist/custom/query-extraction/sourceBinding.d.ts +57 -0
  118. package/dist/custom/query-extraction/sourceBinding.d.ts.map +1 -0
  119. package/dist/custom/query-extraction/sourceBinding.js +104 -0
  120. package/dist/custom/query-extraction/sourceBinding.js.map +1 -0
  121. package/dist/custom/query-extraction/sync.d.ts +27 -3
  122. package/dist/custom/query-extraction/sync.d.ts.map +1 -1
  123. package/dist/custom/query-extraction/sync.js +69 -44
  124. package/dist/custom/query-extraction/sync.js.map +1 -1
  125. package/dist/custom/query-extraction/templateFacts.d.ts +62 -0
  126. package/dist/custom/query-extraction/templateFacts.d.ts.map +1 -0
  127. package/dist/custom/query-extraction/templateFacts.js +229 -0
  128. package/dist/custom/query-extraction/templateFacts.js.map +1 -0
  129. package/dist/custom/query-extraction/types.d.ts +4 -0
  130. package/dist/custom/query-extraction/types.d.ts.map +1 -1
  131. package/dist/custom/query-refresh/QueryExtractionService.d.ts +54 -0
  132. package/dist/custom/query-refresh/QueryExtractionService.d.ts.map +1 -0
  133. package/dist/custom/query-refresh/QueryExtractionService.js +207 -0
  134. package/dist/custom/query-refresh/QueryExtractionService.js.map +1 -0
  135. package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts +28 -0
  136. package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts.map +1 -0
  137. package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js +106 -0
  138. package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js.map +1 -0
  139. package/dist/custom/query-refresh/index.d.ts +14 -0
  140. package/dist/custom/query-refresh/index.d.ts.map +1 -0
  141. package/dist/custom/query-refresh/index.js +10 -0
  142. package/dist/custom/query-refresh/index.js.map +1 -0
  143. package/dist/custom/query-refresh/queryRebind.d.ts +33 -0
  144. package/dist/custom/query-refresh/queryRebind.d.ts.map +1 -0
  145. package/dist/custom/query-refresh/queryRebind.js +85 -0
  146. package/dist/custom/query-refresh/queryRebind.js.map +1 -0
  147. package/dist/custom/query-refresh/refreshAuthorization.d.ts +29 -0
  148. package/dist/custom/query-refresh/refreshAuthorization.d.ts.map +1 -0
  149. package/dist/custom/query-refresh/refreshAuthorization.js +66 -0
  150. package/dist/custom/query-refresh/refreshAuthorization.js.map +1 -0
  151. package/dist/custom/query-refresh/refreshFormat.d.ts +16 -0
  152. package/dist/custom/query-refresh/refreshFormat.d.ts.map +1 -0
  153. package/dist/custom/query-refresh/refreshFormat.js +67 -0
  154. package/dist/custom/query-refresh/refreshFormat.js.map +1 -0
  155. package/dist/custom/query-refresh/refreshOrder.d.ts +25 -0
  156. package/dist/custom/query-refresh/refreshOrder.d.ts.map +1 -0
  157. package/dist/custom/query-refresh/refreshOrder.js +95 -0
  158. package/dist/custom/query-refresh/refreshOrder.js.map +1 -0
  159. package/dist/custom/query-refresh/refreshSelection.d.ts +15 -0
  160. package/dist/custom/query-refresh/refreshSelection.d.ts.map +1 -0
  161. package/dist/custom/query-refresh/refreshSelection.js +99 -0
  162. package/dist/custom/query-refresh/refreshSelection.js.map +1 -0
  163. package/dist/custom/query-refresh/refreshTypes.d.ts +81 -0
  164. package/dist/custom/query-refresh/refreshTypes.d.ts.map +1 -0
  165. package/dist/custom/query-refresh/refreshTypes.js +5 -0
  166. package/dist/custom/query-refresh/refreshTypes.js.map +1 -0
  167. package/dist/custom/util.d.ts +8 -0
  168. package/dist/custom/util.d.ts.map +1 -1
  169. package/dist/custom/util.js +18 -1
  170. package/dist/custom/util.js.map +1 -1
  171. package/dist/engines/QueryEngineServer.d.ts +8 -5
  172. package/dist/engines/QueryEngineServer.d.ts.map +1 -1
  173. package/dist/engines/QueryEngineServer.js +16 -23
  174. package/dist/engines/QueryEngineServer.js.map +1 -1
  175. package/dist/index.d.ts +7 -0
  176. package/dist/index.d.ts.map +1 -1
  177. package/dist/index.js +7 -0
  178. package/dist/index.js.map +1 -1
  179. package/package.json +30 -30
@@ -0,0 +1,240 @@
1
+ import { LogError, LogStatus, RunView, WellKnownUserSource } from '@memberjunction/core';
2
+ import { AIPromptParams } from '@memberjunction/ai-core-plus';
3
+ import { AIPromptRunner } from '@memberjunction/ai-prompts';
4
+ import { AIEngine } from '@memberjunction/aiengine';
5
+ import { BuildLinkedRecordPrimaryKeyFilter, DetectReferencedRestrictedFieldsDeterministic, MergeRestrictedFieldsIntoAnchorMetadata, ParseConversationAnchorMetadata } from '@memberjunction/core-entities';
6
+ let customRestrictedFieldClassifier = null;
7
+ /**
8
+ * Registers (or clears with `null`) a custom semantic classifier callback for detecting
9
+ * references to FLS-restricted fields in record comments. Used by tests and custom
10
+ * enterprise classification policies; when `null`, the default `AIEngine` classifier runs.
11
+ */
12
+ export function RegisterRestrictedFieldLLMClassifier(callback) {
13
+ customRestrictedFieldClassifier = callback;
14
+ }
15
+ /**
16
+ * Returns the currently registered custom classifier callback, if any.
17
+ */
18
+ export function GetRegisteredRestrictedFieldLLMClassifier() {
19
+ return customRestrictedFieldClassifier;
20
+ }
21
+ /**
22
+ * Inspects a comment (`messageText`) posted on an anchored conversation to detect whether it
23
+ * references any FLS-governed fields on `entityInfo`, and stamps any newly detected field names
24
+ * into `conversation.AnchorMetadataObject.restrictedFields`.
25
+ *
26
+ * Two-stage detection:
27
+ * 1. **Stage 1 (Deterministic, 0ms)**: Checks direct field anchors (`AnchorType === 'Field'`),
28
+ * restricted field names/labels (`Name`, camelCase words, `DisplayName`), and actual restricted
29
+ * field values loaded from the linked record.
30
+ * 2. **Stage 2 (Semantic LLM Classifier)**: If `entityInfo` has remaining unmatched FLS fields and
31
+ * `messageText` is non-empty, invokes either the registered `RestrictedFieldLLMClassifierCallback`
32
+ * or a lightweight `AIEngine` language model to detect semantic/paraphrased references
33
+ * (for example `"making six figures"` → `Salary`).
34
+ */
35
+ export async function InspectAndStampRestrictedFieldsForComment(params) {
36
+ const { Provider, ContextUser, Conversation, EntityInfo: entityInfo, MessageText } = params;
37
+ // fls-guard: inspect and stamp restrictedFields on anchored conversation comments
38
+ if (!entityInfo.FieldLevelSecurityApplies) {
39
+ return {
40
+ Allowed: true,
41
+ Reason: null,
42
+ DetectedFields: [],
43
+ AuthorDeniedFields: []
44
+ };
45
+ }
46
+ const restrictedFields = entityInfo.Fields.filter((f) => f.HasFieldPermissions);
47
+ if (restrictedFields.length === 0) {
48
+ return {
49
+ Allowed: true,
50
+ Reason: null,
51
+ DetectedFields: [],
52
+ AuthorDeniedFields: []
53
+ };
54
+ }
55
+ // Security invariant: never value-match against fields the authoring user is denied Read access to.
56
+ // An author who cannot read a field cannot be disclosing its value from the record, and matching their
57
+ // comment text against hidden system-loaded values would create a yes/no guessing oracle.
58
+ // Only fields the author CAN read are eligible for record-value matching (to stamp restrictedFields
59
+ // so downstream readers who lack access to that field do not see the thread).
60
+ const deniedLower = entityInfo.GetDeniedReadFields(ContextUser);
61
+ const authorReadableRestrictedFields = restrictedFields.filter((f) => !deniedLower.has(f.Name.trim().toLowerCase()));
62
+ let readableRecordValues = null;
63
+ if (authorReadableRestrictedFields.length > 0 && (MessageText ?? '').trim().length > 0) {
64
+ const rawRecordValues = params.RecordValues ??
65
+ (Conversation.LinkedRecordID
66
+ ? await loadLinkedRecordRestrictedFieldValues(Provider, ContextUser, entityInfo, Conversation.LinkedRecordID, authorReadableRestrictedFields)
67
+ : null);
68
+ if (rawRecordValues) {
69
+ readableRecordValues = {};
70
+ for (const f of authorReadableRestrictedFields) {
71
+ if (Object.prototype.hasOwnProperty.call(rawRecordValues, f.Name)) {
72
+ readableRecordValues[f.Name] = rawRecordValues[f.Name];
73
+ }
74
+ }
75
+ }
76
+ }
77
+ // Stage 1: Deterministic detection (field anchor + field names/labels + author-readable record values)
78
+ const deterministicMatches = DetectReferencedRestrictedFieldsDeterministic(entityInfo, MessageText, Conversation.AnchorType, Conversation.AnchorKey, readableRecordValues);
79
+ const detectedSet = new Set(deterministicMatches);
80
+ // Stage 2: Semantic LLM classification for any remaining FLS-governed fields
81
+ const text = (MessageText ?? '').trim();
82
+ const unmatchedFields = restrictedFields.filter((f) => !detectedSet.has(f.Name));
83
+ if (!params.SkipLLMStage && text.length > 0 && unmatchedFields.length > 0) {
84
+ const llmMatches = await runSemanticRestrictedFieldClassifier(entityInfo, unmatchedFields, text, Conversation.AnchorType, Conversation.AnchorKey, ContextUser);
85
+ for (const fieldName of llmMatches) {
86
+ detectedSet.add(fieldName);
87
+ }
88
+ }
89
+ const detectedFields = [...detectedSet];
90
+ // Also include any previously stamped restrictedFields on the conversation when checking author access
91
+ const existingMeta = ParseConversationAnchorMetadata(Conversation.AnchorMetadataObject ?? Conversation.AnchorMetadata);
92
+ const allThreadRestrictedFields = new Set(detectedFields);
93
+ if (Array.isArray(existingMeta?.restrictedFields)) {
94
+ for (const f of existingMeta.restrictedFields) {
95
+ if (typeof f === 'string' && f.trim()) {
96
+ allThreadRestrictedFields.add(f.trim());
97
+ }
98
+ }
99
+ }
100
+ // Check whether the authoring user is denied Read access on any referenced restricted field.
101
+ // Return a generic message without naming which field matched.
102
+ const authorDeniedFields = [...allThreadRestrictedFields].filter((f) => deniedLower.has(f.trim().toLowerCase()));
103
+ if (authorDeniedFields.length > 0) {
104
+ return {
105
+ Allowed: false,
106
+ Reason: 'You do not have permission to comment on restricted fields.',
107
+ DetectedFields: detectedFields,
108
+ AuthorDeniedFields: authorDeniedFields
109
+ };
110
+ }
111
+ // Stamp newly detected restricted fields onto the parent conversation's AnchorMetadataObject
112
+ if (detectedFields.length > 0) {
113
+ const { Metadata, Changed } = MergeRestrictedFieldsIntoAnchorMetadata(existingMeta, detectedFields);
114
+ if (Changed) {
115
+ Conversation.AnchorMetadataObject = Metadata;
116
+ if (Conversation.IsSaved) {
117
+ const saved = await Conversation.Save();
118
+ if (!saved) {
119
+ LogError(`InspectAndStampRestrictedFieldsForComment: failed to update AnchorMetadata on conversation ${Conversation.ID}: ${Conversation.LatestResult?.CompleteMessage ?? 'unknown error'}`);
120
+ }
121
+ }
122
+ }
123
+ }
124
+ return {
125
+ Allowed: true,
126
+ Reason: null,
127
+ DetectedFields: detectedFields,
128
+ AuthorDeniedFields: []
129
+ };
130
+ }
131
+ async function loadLinkedRecordRestrictedFieldValues(provider, contextUser, entityInfo, linkedRecordId, restrictedFields) {
132
+ if (provider?.ProviderType !== 'Database' || restrictedFields.length === 0) {
133
+ return null;
134
+ }
135
+ const pkFilter = BuildLinkedRecordPrimaryKeyFilter(entityInfo, linkedRecordId, provider);
136
+ if (!pkFilter) {
137
+ return null;
138
+ }
139
+ try {
140
+ const systemUser = (await WellKnownUserSource.Instance.GetSystemUser(provider)) ?? contextUser;
141
+ const rv = RunView.FromMetadataProvider(provider);
142
+ const fieldNames = [
143
+ ...entityInfo.PrimaryKeys.map((pk) => pk.Name),
144
+ ...restrictedFields.map((f) => f.Name)
145
+ ];
146
+ const result = await rv.RunView({
147
+ EntityName: entityInfo.Name,
148
+ ExtraFilter: pkFilter,
149
+ Fields: fieldNames,
150
+ MaxRows: 1,
151
+ ResultType: 'simple'
152
+ }, systemUser);
153
+ if (result.Success && result.Results && result.Results.length > 0) {
154
+ return result.Results[0];
155
+ }
156
+ }
157
+ catch (error) {
158
+ LogError(`loadLinkedRecordRestrictedFieldValues failed on ${entityInfo.Name} (${linkedRecordId}): ${error instanceof Error ? error.message : String(error)}`);
159
+ }
160
+ return null;
161
+ }
162
+ async function runSemanticRestrictedFieldClassifier(entityInfo, candidateFields, messageText, anchorType, anchorKey, contextUser) {
163
+ const prompt = {
164
+ EntityName: entityInfo.Name,
165
+ EntityDisplayName: entityInfo.DisplayNameOrName,
166
+ MessageText: messageText,
167
+ AnchorType: anchorType,
168
+ AnchorKey: anchorKey,
169
+ CandidateFields: candidateFields.map((f) => ({
170
+ Name: f.Name,
171
+ DisplayName: f.DisplayNameOrName,
172
+ Description: f.Description ?? null
173
+ }))
174
+ };
175
+ const validByLower = new Map();
176
+ for (const f of candidateFields) {
177
+ validByLower.set(f.Name.toLowerCase(), f.Name);
178
+ }
179
+ if (customRestrictedFieldClassifier) {
180
+ try {
181
+ const rawMatches = await customRestrictedFieldClassifier(prompt, contextUser);
182
+ return normalizeMatchedFieldNames(rawMatches, validByLower);
183
+ }
184
+ catch (error) {
185
+ LogError(`Custom RestrictedFieldLLMClassifier threw: ${error instanceof Error ? error.message : String(error)}`);
186
+ return [];
187
+ }
188
+ }
189
+ return runDefaultAIEngineRestrictedFieldClassifier(prompt, contextUser, validByLower);
190
+ }
191
+ function normalizeMatchedFieldNames(rawNames, validByLower) {
192
+ if (!Array.isArray(rawNames)) {
193
+ return [];
194
+ }
195
+ const canonical = new Set();
196
+ for (const name of rawNames) {
197
+ if (typeof name === 'string') {
198
+ const found = validByLower.get(name.trim().toLowerCase());
199
+ if (found) {
200
+ canonical.add(found);
201
+ }
202
+ }
203
+ }
204
+ return [...canonical];
205
+ }
206
+ const RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME = 'Anchored Comment Restricted Field Classifier';
207
+ async function runDefaultAIEngineRestrictedFieldClassifier(prompt, contextUser, validByLower) {
208
+ try {
209
+ await AIEngine.Instance.Config(false, contextUser);
210
+ }
211
+ catch (error) {
212
+ LogStatus(`[RestrictedFieldCommentClassifier] AIEngine.Config unavailable; skipping Stage 2 semantic classification: ${error instanceof Error ? error.message : String(error)}`);
213
+ return [];
214
+ }
215
+ const aiPrompt = AIEngine.Instance.Prompts?.find((p) => p.Name === RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME && p.Status === 'Active');
216
+ if (!aiPrompt) {
217
+ return [];
218
+ }
219
+ try {
220
+ const runner = new AIPromptRunner();
221
+ const params = new AIPromptParams();
222
+ params.prompt = aiPrompt;
223
+ params.data = prompt;
224
+ params.contextUser = contextUser;
225
+ const execution = await runner.ExecutePrompt(params);
226
+ if (!execution.success || !execution.result) {
227
+ LogStatus(`[RestrictedFieldCommentClassifier] Governed prompt "${RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME}" returned unsuccessful result: ${execution.errorMessage ?? 'unknown'}`);
228
+ return [];
229
+ }
230
+ const list = execution.result.restrictedFields;
231
+ if (Array.isArray(list)) {
232
+ return normalizeMatchedFieldNames(list.filter((item) => typeof item === 'string'), validByLower);
233
+ }
234
+ }
235
+ catch (error) {
236
+ LogStatus(`[RestrictedFieldCommentClassifier] Governed prompt "${RESTRICTED_FIELD_CLASSIFIER_PROMPT_NAME}" threw: ${error instanceof Error ? error.message : String(error)}`);
237
+ }
238
+ return [];
239
+ }
240
+ //# sourceMappingURL=RestrictedFieldCommentClassifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RestrictedFieldCommentClassifier.js","sourceRoot":"","sources":["../../src/custom/RestrictedFieldCommentClassifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ import type { IEntityDataProvider, IMetadataProvider, IRunViewProvider, UserInfo } from "@memberjunction/core";
2
+ import type { MJQueryFieldEntity } from "@memberjunction/core-entities";
3
+ import type { QueryExtractionResult, QueryFieldFact } from "./extractionTypes.js";
4
+ /** Where the child rows are written, and as whom. */
5
+ export interface ChildRowWriteContext {
6
+ readonly QueryID: string;
7
+ /**
8
+ * The caller's provider. The writes run in an entity transaction on it, joining the caller's
9
+ * transaction when one is open; a provider without entity transactions writes without one.
10
+ */
11
+ readonly Provider: IMetadataProvider & IRunViewProvider & Partial<Pick<IEntityDataProvider, 'SupportsEntityTransactions' | 'BeginEntityTransaction'>>;
12
+ /** The user the rows are read and written as: the system user for save-triggered extraction. */
13
+ readonly User: UserInfo;
14
+ /** Work out and report the changes without writing anything. */
15
+ readonly DryRun?: boolean;
16
+ /** The name a Query Entities change is reported under, for an entity ID; the ID when omitted. */
17
+ readonly EntityName?: (entityID: string) => string;
18
+ }
19
+ /** The child collection of a query a row belongs to. */
20
+ export type QueryChildCollection = 'Fields' | 'Parameters' | 'Entities' | 'Dependencies';
21
+ /** One child row the writes add, update or remove. */
22
+ export interface ChildRowChange {
23
+ readonly Collection: QueryChildCollection;
24
+ readonly Action: 'Added' | 'Updated' | 'Removed';
25
+ /** The field or parameter name, the entity name, or the dependency's reference path. */
26
+ readonly Name: string;
27
+ /** For an update, the columns that change. */
28
+ readonly ChangedColumns: readonly string[];
29
+ /** For a field row, the entity field its output column comes from, when it maps to one. */
30
+ readonly SourceEntityFieldID: string | null;
31
+ }
32
+ /** What the writes changed, and which rows still have no description. */
33
+ export interface ChildRowWriteSummary {
34
+ Added: number;
35
+ Updated: number;
36
+ Removed: number;
37
+ /** Every row added, updated or removed, in write order. */
38
+ readonly Changes: ChildRowChange[];
39
+ /** Authored parameters the SQL no longer uses: kept, and flagged on the query. */
40
+ readonly FlaggedParameters: string[];
41
+ /** Field rows with an empty description, for the description pass. */
42
+ readonly FieldsWithoutDescription: string[];
43
+ /** Parameter rows with an empty description, for the description pass. */
44
+ readonly ParametersWithoutDescription: string[];
45
+ }
46
+ /**
47
+ * Brings a query's child rows in line with its extracted facts, keeping what people authored.
48
+ *
49
+ * **Facts** are corrected on every row, including declared and `Manual` ones: a field's name
50
+ * casing, sequence, types, nullability, source and computed flag; whether a parameter exists
51
+ * (and its name casing); which entities and dependencies the query has.
52
+ *
53
+ * **Annotations** are never overwritten when authored (`DetectionMethod` `Manual`, or a
54
+ * non-empty value): descriptions, `ComputationDescription`, `IsSummary` / `SummaryDescription`,
55
+ * and a `Manual` parameter's type, required flag, default, sample, validation filters and
56
+ * server-set flag. A doc-comment description is authored too: it fills an empty description and
57
+ * replaces one extraction or an LLM wrote.
58
+ *
59
+ * An authored parameter the SQL no longer uses is kept (extraction flags it on the query); an
60
+ * auto-detected one is deleted. Rows keep their IDs. A `null` fact collection leaves its rows as
61
+ * they are. Existing rows are read from the database on the caller's provider, never a cache, so
62
+ * rows written earlier in the same transaction are seen.
63
+ *
64
+ * The writes are one unit of work: they run in an entity transaction on the caller's provider,
65
+ * which joins the caller's transaction when one is open (a nested scope), so a failed write rolls
66
+ * every write of this call back and throws. A provider without entity transactions (a client)
67
+ * writes without one.
68
+ *
69
+ * With `DryRun` the same changes are worked out and reported, and nothing is written.
70
+ */
71
+ export declare function WriteExtractedChildRows(context: ChildRowWriteContext, result: QueryExtractionResult): Promise<ChildRowWriteSummary>;
72
+ /**
73
+ * Sets a field row's facts (name casing, sequence, types, nullability, computed flag, source) from
74
+ * the extracted fact, leaving its annotations alone.
75
+ */
76
+ export declare function ApplyFieldFacts(row: MJQueryFieldEntity, fact: QueryFieldFact): void;
77
+ //# sourceMappingURL=childRowWriter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"childRowWriter.d.ts","sourceRoot":"","sources":["../../../src/custom/query-extraction/childRowWriter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAc,mBAAmB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC3H,OAAO,KAAK,EAGR,kBAAkB,EAErB,MAAM,+BAA+B,CAAC;AAEvC,OAAO,KAAK,EAGR,qBAAqB,EACrB,cAAc,EAEjB,MAAM,mBAAmB,CAAC;AAE3B,qDAAqD;AACrD,MAAM,WAAW,oBAAoB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,mBAAmB,EAAE,4BAA4B,GAAG,wBAAwB,CAAC,CAAC,CAAC;IACtJ,gGAAgG;IAChG,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,gEAAgE;IAChE,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IAC1B,iGAAiG;IACjG,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,CAAC;CACtD;AAED,wDAAwD;AACxD,MAAM,MAAM,oBAAoB,GAAG,QAAQ,GAAG,YAAY,GAAG,UAAU,GAAG,cAAc,CAAC;AAEzF,sDAAsD;AACtD,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,UAAU,EAAE,oBAAoB,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,GAAG,SAAS,CAAC;IACjD,wFAAwF;IACxF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8CAA8C;IAC9C,QAAQ,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3C,2FAA2F;IAC3F,QAAQ,CAAC,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/C;AAED,yEAAyE;AACzE,MAAM,WAAW,oBAAoB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,QAAQ,CAAC,OAAO,EAAE,cAAc,EAAE,CAAC;IACnC,kFAAkF;IAClF,QAAQ,CAAC,iBAAiB,EAAE,MAAM,EAAE,CAAC;IACrC,sEAAsE;IACtE,QAAQ,CAAC,wBAAwB,EAAE,MAAM,EAAE,CAAC;IAC5C,0EAA0E;IAC1E,QAAQ,CAAC,4BAA4B,EAAE,MAAM,EAAE,CAAC;CACnD;AAYD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAWzI;AAsGD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,kBAAkB,EAAE,IAAI,EAAE,cAAc,GAAG,IAAI,CAWnF"}
@@ -0,0 +1,277 @@
1
+ import { RunInEntityTransaction, RunMaybeSerial } from "@memberjunction/core";
2
+ import { EscapeSQLString, NormalizeUUID, UUIDsEqual } from "@memberjunction/global";
3
+ /**
4
+ * Brings a query's child rows in line with its extracted facts, keeping what people authored.
5
+ *
6
+ * **Facts** are corrected on every row, including declared and `Manual` ones: a field's name
7
+ * casing, sequence, types, nullability, source and computed flag; whether a parameter exists
8
+ * (and its name casing); which entities and dependencies the query has.
9
+ *
10
+ * **Annotations** are never overwritten when authored (`DetectionMethod` `Manual`, or a
11
+ * non-empty value): descriptions, `ComputationDescription`, `IsSummary` / `SummaryDescription`,
12
+ * and a `Manual` parameter's type, required flag, default, sample, validation filters and
13
+ * server-set flag. A doc-comment description is authored too: it fills an empty description and
14
+ * replaces one extraction or an LLM wrote.
15
+ *
16
+ * An authored parameter the SQL no longer uses is kept (extraction flags it on the query); an
17
+ * auto-detected one is deleted. Rows keep their IDs. A `null` fact collection leaves its rows as
18
+ * they are. Existing rows are read from the database on the caller's provider, never a cache, so
19
+ * rows written earlier in the same transaction are seen.
20
+ *
21
+ * The writes are one unit of work: they run in an entity transaction on the caller's provider,
22
+ * which joins the caller's transaction when one is open (a nested scope), so a failed write rolls
23
+ * every write of this call back and throws. A provider without entity transactions (a client)
24
+ * writes without one.
25
+ *
26
+ * With `DryRun` the same changes are worked out and reported, and nothing is written.
27
+ */
28
+ export async function WriteExtractedChildRows(context, result) {
29
+ const stored = await loadStoredChildRows(context);
30
+ const summary = { Added: 0, Updated: 0, Removed: 0, Changes: [], FlaggedParameters: [], FieldsWithoutDescription: [], ParametersWithoutDescription: [] };
31
+ const writes = [];
32
+ if (result.Fields)
33
+ writes.push(...await fieldWrites(context, stored.Fields, result.Fields, summary));
34
+ writes.push(...await parameterWrites(context, stored.Parameters, result.Parameters, summary));
35
+ if (result.Entities)
36
+ writes.push(...await entityWrites(context, stored.Entities, result.Entities, summary));
37
+ if (result.Dependencies)
38
+ writes.push(...await dependencyWrites(context, stored.Dependencies, result.Dependencies, summary));
39
+ if (context.DryRun || writes.length === 0)
40
+ return summary;
41
+ await RunInEntityTransaction(context.Provider, () => runWrites(context, writes));
42
+ return summary;
43
+ }
44
+ /** Runs the writes; throws when any of them failed, so the enclosing transaction rolls them all back. */
45
+ async function runWrites(context, writes) {
46
+ const outcomes = await RunMaybeSerial(context.Provider, [...writes]);
47
+ const failed = outcomes.filter(ok => !ok).length;
48
+ if (failed > 0)
49
+ throw new Error(`Query ${context.QueryID}: ${failed} of ${writes.length} child-row writes failed; none of them were kept.`);
50
+ }
51
+ async function loadStoredChildRows(context) {
52
+ const filter = `QueryID='${EscapeSQLString(context.QueryID)}'`;
53
+ const load = async (entityName) => {
54
+ const result = await context.Provider.RunView({ EntityName: entityName, ExtraFilter: filter, ResultType: 'entity_object', BypassCache: true, IgnoreMaxRows: true }, context.User);
55
+ if (!result.Success)
56
+ throw new Error(`Could not read the stored ${entityName} of query ${context.QueryID}: ${result.ErrorMessage}`);
57
+ return result.Results ?? [];
58
+ };
59
+ const [fields, parameters, entities, dependencies] = await Promise.all([
60
+ load('MJ: Query Fields'),
61
+ load('MJ: Query Parameters'),
62
+ load('MJ: Query Entities'),
63
+ load('MJ: Query Dependencies'),
64
+ ]);
65
+ return { Fields: fields, Parameters: parameters, Entities: entities, Dependencies: dependencies };
66
+ }
67
+ /**
68
+ * A write for `row` when it has unsaved changes; counts and records it as added or updated.
69
+ *
70
+ * `alsoChanged` names columns that changed although the entity's dirty check does not see it: a
71
+ * nullable bit column going between `null` and `false` reads as unchanged there. Such a row is
72
+ * still written (ignoring the dirty state) and the column is reported.
73
+ */
74
+ function saveIfDirty(row, summary, label, alsoChanged = []) {
75
+ if (row.IsSaved && !row.Dirty && alsoChanged.length === 0)
76
+ return [];
77
+ const action = row.IsSaved ? 'Updated' : 'Added';
78
+ if (row.IsSaved)
79
+ summary.Updated++;
80
+ else
81
+ summary.Added++;
82
+ const dirtyColumns = row.IsSaved ? row.Fields.filter(f => f.Dirty).map(f => f.Name) : [];
83
+ const changedColumns = row.IsSaved ? [...dirtyColumns, ...alsoChanged.filter(c => !dirtyColumns.includes(c))] : [];
84
+ summary.Changes.push({ ...changeOf(label, action), ChangedColumns: changedColumns });
85
+ const ignoreDirtyState = row.IsSaved && !row.Dirty;
86
+ return [() => row.Save(ignoreDirtyState ? { IgnoreDirtyState: true } : undefined)];
87
+ }
88
+ function deleteRows(rows, summary, labelOf) {
89
+ summary.Removed += rows.length;
90
+ for (const row of rows)
91
+ summary.Changes.push(changeOf(labelOf(row), 'Removed'));
92
+ return rows.map(row => () => row.Delete());
93
+ }
94
+ function changeOf(label, action) {
95
+ return { Collection: label.Collection, Action: action, Name: label.Name, ChangedColumns: [], SourceEntityFieldID: label.SourceEntityFieldID ?? null };
96
+ }
97
+ function fieldLabel(row) {
98
+ return { Collection: 'Fields', Name: row.Name, SourceEntityFieldID: row.SourceEntityFieldID };
99
+ }
100
+ function parameterLabel(row) {
101
+ return { Collection: 'Parameters', Name: row.Name };
102
+ }
103
+ function byLowerName(rows) {
104
+ return new Map(rows.map(r => [r.Name.toLowerCase(), r]));
105
+ }
106
+ function isEmpty(value) {
107
+ return !value || value.trim().length === 0;
108
+ }
109
+ // ─── Fields ─────────────────────────────────────────────────────────────────
110
+ async function fieldWrites(context, stored, facts, summary) {
111
+ const existing = byLowerName(stored);
112
+ const writes = [];
113
+ for (const fact of facts) {
114
+ let row = existing.get(fact.Name.toLowerCase());
115
+ existing.delete(fact.Name.toLowerCase());
116
+ if (!row)
117
+ row = await newRow(context, 'MJ: Query Fields', r => newField(r, context.QueryID, fact));
118
+ else
119
+ applyFieldAnnotations(row, fact);
120
+ const nullabilityChanged = row.IsSaved && (row.IsNullable ?? null) !== (fact.IsNullable ?? null);
121
+ ApplyFieldFacts(row, fact);
122
+ writes.push(...saveIfDirty(row, summary, fieldLabel(row), nullabilityChanged ? ['IsNullable'] : []));
123
+ if (isEmpty(row.Description))
124
+ summary.FieldsWithoutDescription.push(row.Name);
125
+ }
126
+ return [...writes, ...deleteRows([...existing.values()], summary, fieldLabel)];
127
+ }
128
+ function newField(row, queryID, fact) {
129
+ row.QueryID = queryID;
130
+ row.Description = fact.DocDescription ?? fact.SourceDescription;
131
+ row.IsSummary = false;
132
+ row.DetectionMethod = 'Database';
133
+ }
134
+ /**
135
+ * Sets a field row's facts (name casing, sequence, types, nullability, computed flag, source) from
136
+ * the extracted fact, leaving its annotations alone.
137
+ */
138
+ export function ApplyFieldFacts(row, fact) {
139
+ row.Name = fact.Name;
140
+ row.Sequence = fact.Sequence;
141
+ row.SQLBaseType = fact.SQLBaseType;
142
+ row.SQLFullType = fact.SQLFullType;
143
+ row.IsNullable = fact.IsNullable;
144
+ row.IsComputed = fact.IsComputed;
145
+ row.SourceEntityID = fact.SourceEntityID;
146
+ row.SourceEntityFieldID = fact.SourceEntityFieldID;
147
+ row.SourceFieldName = fact.SourceFieldName;
148
+ row.SourceObjectName = fact.SourceObjectName;
149
+ }
150
+ /** A stored field's description and detection method: authored ones kept, a doc comment applied. */
151
+ function applyFieldAnnotations(row, fact) {
152
+ const authored = row.DetectionMethod === 'Manual';
153
+ if (fact.DocDescription !== null && (!authored || isEmpty(row.Description)))
154
+ row.Description = fact.DocDescription;
155
+ if (!authored && row.DetectionMethod !== 'AI')
156
+ row.DetectionMethod = 'Database';
157
+ if (row.DetectionMethod === 'AI' && fact.DocDescription !== null)
158
+ row.DetectionMethod = 'Database';
159
+ }
160
+ // ─── Parameters ─────────────────────────────────────────────────────────────
161
+ async function parameterWrites(context, stored, facts, summary) {
162
+ const existing = byLowerName(stored);
163
+ const writes = [];
164
+ for (const fact of facts) {
165
+ let row = existing.get(fact.Name.toLowerCase());
166
+ existing.delete(fact.Name.toLowerCase());
167
+ if (!row)
168
+ row = await newRow(context, 'MJ: Query Parameters', r => newParameter(r, context.QueryID, fact));
169
+ else
170
+ applyParameterAnnotations(row, fact);
171
+ row.Name = fact.Name;
172
+ writes.push(...saveIfDirty(row, summary, parameterLabel(row)));
173
+ if (isEmpty(row.Description))
174
+ summary.ParametersWithoutDescription.push(row.Name);
175
+ }
176
+ const leftover = [...existing.values()];
177
+ summary.FlaggedParameters.push(...leftover.filter(row => row.DetectionMethod === 'Manual').map(row => row.Name));
178
+ const unused = leftover.filter(row => row.DetectionMethod !== 'Manual');
179
+ return [...writes, ...deleteRows(unused, summary, parameterLabel)];
180
+ }
181
+ function newParameter(row, queryID, fact) {
182
+ row.QueryID = queryID;
183
+ row.Type = fact.Type ?? 'string';
184
+ row.IsRequired = fact.IsRequired;
185
+ row.DefaultValue = fact.DefaultValue;
186
+ row.SampleValue = fact.SampleValue;
187
+ row.Description = fact.DocDescription ?? fact.InheritedDescription;
188
+ row.IsServerSet = false;
189
+ row.DetectionMethod = 'Parser';
190
+ }
191
+ /**
192
+ * A stored parameter: a `Manual` row keeps every annotation (only an empty description is filled);
193
+ * an auto-detected row takes the template's type, required flag and default, keeps a non-empty
194
+ * sample and description, and takes a doc comment's description.
195
+ */
196
+ function applyParameterAnnotations(row, fact) {
197
+ if (row.DetectionMethod === 'Manual') {
198
+ if (isEmpty(row.Description))
199
+ row.Description = fact.DocDescription ?? fact.InheritedDescription ?? row.Description;
200
+ return;
201
+ }
202
+ if (fact.Type !== null)
203
+ row.Type = fact.Type;
204
+ row.IsRequired = fact.IsRequired;
205
+ row.DefaultValue = fact.DefaultValue;
206
+ if (isEmpty(row.SampleValue))
207
+ row.SampleValue = fact.SampleValue;
208
+ if (fact.DocDescription !== null)
209
+ row.Description = fact.DocDescription;
210
+ else if (isEmpty(row.Description))
211
+ row.Description = fact.InheritedDescription;
212
+ row.DetectionMethod = 'Parser';
213
+ }
214
+ // ─── Entities ───────────────────────────────────────────────────────────────
215
+ async function entityWrites(context, stored, facts, summary) {
216
+ const remaining = [...stored];
217
+ const writes = [];
218
+ const unmatched = facts.filter(fact => !takeRow(remaining, r => sameEntityLink(r, fact)));
219
+ for (const fact of unmatched) {
220
+ const row = takeRow(remaining, r => UUIDsEqual(r.EntityID, fact.EntityID))
221
+ ?? await newRow(context, 'MJ: Query Entities', r => newEntityLink(r, context.QueryID, fact));
222
+ row.AlternateBaseViewID = fact.AlternateBaseViewID;
223
+ writes.push(...saveIfDirty(row, summary, entityLabel(context, row)));
224
+ }
225
+ return [...writes, ...deleteRows(remaining, summary, row => entityLabel(context, row))];
226
+ }
227
+ function entityLabel(context, row) {
228
+ return { Collection: 'Entities', Name: context.EntityName ? context.EntityName(row.EntityID) : (row.Entity || row.EntityID) };
229
+ }
230
+ function sameEntityLink(row, fact) {
231
+ const abv = (id) => (id ? NormalizeUUID(id) : '');
232
+ return UUIDsEqual(row.EntityID, fact.EntityID) && abv(row.AlternateBaseViewID) === abv(fact.AlternateBaseViewID);
233
+ }
234
+ function newEntityLink(row, queryID, fact) {
235
+ row.QueryID = queryID;
236
+ row.EntityID = fact.EntityID;
237
+ row.DetectionMethod = 'Parser';
238
+ row.AutoDetectConfidenceScore = 1;
239
+ }
240
+ /** Removes and returns the first row matching `test`. */
241
+ function takeRow(rows, test) {
242
+ const index = rows.findIndex(test);
243
+ return index < 0 ? undefined : rows.splice(index, 1)[0];
244
+ }
245
+ // ─── Dependencies ───────────────────────────────────────────────────────────
246
+ async function dependencyWrites(context, stored, facts, summary) {
247
+ const remaining = [...stored];
248
+ const writes = [];
249
+ const seen = new Set();
250
+ for (const fact of facts) {
251
+ const key = `${NormalizeUUID(fact.DependsOnQueryID)}|${fact.ReferencePath.toLowerCase()}`;
252
+ if (seen.has(key))
253
+ continue;
254
+ seen.add(key);
255
+ const row = takeRow(remaining, r => UUIDsEqual(r.DependsOnQueryID, fact.DependsOnQueryID) && r.ReferencePath.toLowerCase() === fact.ReferencePath.toLowerCase())
256
+ ?? await newRow(context, 'MJ: Query Dependencies', r => newDependency(r, context.QueryID, fact));
257
+ row.ReferencePath = fact.ReferencePath;
258
+ row.Alias = fact.Alias;
259
+ row.ParameterMapping = fact.ParameterMapping;
260
+ writes.push(...saveIfDirty(row, summary, dependencyLabel(row)));
261
+ }
262
+ return [...writes, ...deleteRows(remaining, summary, dependencyLabel)];
263
+ }
264
+ function dependencyLabel(row) {
265
+ return { Collection: 'Dependencies', Name: row.ReferencePath };
266
+ }
267
+ function newDependency(row, queryID, fact) {
268
+ row.QueryID = queryID;
269
+ row.DependsOnQueryID = fact.DependsOnQueryID;
270
+ row.DetectionMethod = 'Auto';
271
+ }
272
+ async function newRow(context, entityName, init) {
273
+ const row = await context.Provider.GetEntityObject(entityName, context.User);
274
+ init(row);
275
+ return row;
276
+ }
277
+ //# sourceMappingURL=childRowWriter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"childRowWriter.js","sourceRoot":"","sources":["../../../src/custom/query-extraction/childRowWriter.ts"],"names":[],"mappings":"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"}