@memberjunction/core 3.3.0 → 4.0.0

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 (120) hide show
  1. package/dist/__tests__/mocks/TestMetadataProvider.d.ts +45 -0
  2. package/dist/__tests__/mocks/TestMetadataProvider.d.ts.map +1 -0
  3. package/dist/__tests__/mocks/TestMetadataProvider.js +217 -0
  4. package/dist/__tests__/mocks/TestMetadataProvider.js.map +1 -0
  5. package/dist/__tests__/providerBase.concurrency.test.d.ts +10 -0
  6. package/dist/__tests__/providerBase.concurrency.test.d.ts.map +1 -0
  7. package/dist/__tests__/providerBase.concurrency.test.js +253 -0
  8. package/dist/__tests__/providerBase.concurrency.test.js.map +1 -0
  9. package/dist/__tests__/providerBase.refresh.test.d.ts +10 -0
  10. package/dist/__tests__/providerBase.refresh.test.d.ts.map +1 -0
  11. package/dist/__tests__/providerBase.refresh.test.js +161 -0
  12. package/dist/__tests__/providerBase.refresh.test.js.map +1 -0
  13. package/dist/__tests__/setup.d.ts +5 -0
  14. package/dist/__tests__/setup.d.ts.map +1 -0
  15. package/dist/__tests__/setup.js +17 -0
  16. package/dist/__tests__/setup.js.map +1 -0
  17. package/dist/generic/InMemoryLocalStorageProvider.d.ts +1 -1
  18. package/dist/generic/InMemoryLocalStorageProvider.js +2 -6
  19. package/dist/generic/InMemoryLocalStorageProvider.js.map +1 -1
  20. package/dist/generic/QueryCache.d.ts +1 -1
  21. package/dist/generic/QueryCache.js +6 -10
  22. package/dist/generic/QueryCache.js.map +1 -1
  23. package/dist/generic/QueryCacheConfig.js +1 -2
  24. package/dist/generic/RegisterForStartup.d.ts +2 -2
  25. package/dist/generic/RegisterForStartup.js +7 -12
  26. package/dist/generic/RegisterForStartup.js.map +1 -1
  27. package/dist/generic/applicationInfo.d.ts +3 -3
  28. package/dist/generic/applicationInfo.js +4 -10
  29. package/dist/generic/applicationInfo.js.map +1 -1
  30. package/dist/generic/authEvaluator.d.ts +1 -1
  31. package/dist/generic/authEvaluator.js +4 -8
  32. package/dist/generic/authEvaluator.js.map +1 -1
  33. package/dist/generic/authTypes.js +1 -4
  34. package/dist/generic/authTypes.js.map +1 -1
  35. package/dist/generic/baseEngine.d.ts +5 -5
  36. package/dist/generic/baseEngine.js +51 -56
  37. package/dist/generic/baseEngine.js.map +1 -1
  38. package/dist/generic/baseEngineRegistry.js +13 -17
  39. package/dist/generic/baseEngineRegistry.js.map +1 -1
  40. package/dist/generic/baseEntity.d.ts +5 -5
  41. package/dist/generic/baseEntity.js +103 -113
  42. package/dist/generic/baseEntity.js.map +1 -1
  43. package/dist/generic/baseInfo.js +3 -7
  44. package/dist/generic/baseInfo.js.map +1 -1
  45. package/dist/generic/compositeKey.d.ts +2 -2
  46. package/dist/generic/compositeKey.js +5 -11
  47. package/dist/generic/compositeKey.js.map +1 -1
  48. package/dist/generic/databaseProviderBase.d.ts +2 -2
  49. package/dist/generic/databaseProviderBase.js +2 -6
  50. package/dist/generic/databaseProviderBase.js.map +1 -1
  51. package/dist/generic/entityInfo.d.ts +74 -5
  52. package/dist/generic/entityInfo.d.ts.map +1 -1
  53. package/dist/generic/entityInfo.js +138 -105
  54. package/dist/generic/entityInfo.js.map +1 -1
  55. package/dist/generic/explorerNavigationItem.d.ts +1 -1
  56. package/dist/generic/explorerNavigationItem.js +2 -6
  57. package/dist/generic/explorerNavigationItem.js.map +1 -1
  58. package/dist/generic/graphqlTypeNames.d.ts +1 -1
  59. package/dist/generic/graphqlTypeNames.js +4 -9
  60. package/dist/generic/graphqlTypeNames.js.map +1 -1
  61. package/dist/generic/interfaces.d.ts +51 -12
  62. package/dist/generic/interfaces.d.ts.map +1 -1
  63. package/dist/generic/interfaces.js +15 -30
  64. package/dist/generic/interfaces.js.map +1 -1
  65. package/dist/generic/libraryInfo.d.ts +1 -1
  66. package/dist/generic/libraryInfo.js +2 -6
  67. package/dist/generic/libraryInfo.js.map +1 -1
  68. package/dist/generic/localCacheManager.d.ts +2 -2
  69. package/dist/generic/localCacheManager.js +44 -48
  70. package/dist/generic/localCacheManager.js.map +1 -1
  71. package/dist/generic/logging.d.ts.map +1 -1
  72. package/dist/generic/logging.js +54 -67
  73. package/dist/generic/logging.js.map +1 -1
  74. package/dist/generic/metadata.d.ts +10 -10
  75. package/dist/generic/metadata.js +17 -21
  76. package/dist/generic/metadata.js.map +1 -1
  77. package/dist/generic/metadataUtil.d.ts +1 -1
  78. package/dist/generic/metadataUtil.js +3 -7
  79. package/dist/generic/metadataUtil.js.map +1 -1
  80. package/dist/generic/providerBase.d.ts +18 -12
  81. package/dist/generic/providerBase.d.ts.map +1 -1
  82. package/dist/generic/providerBase.js +130 -130
  83. package/dist/generic/providerBase.js.map +1 -1
  84. package/dist/generic/queryInfo.d.ts +5 -5
  85. package/dist/generic/queryInfo.js +21 -30
  86. package/dist/generic/queryInfo.js.map +1 -1
  87. package/dist/generic/queryInfoInterfaces.js +1 -2
  88. package/dist/generic/queryInfoInterfaces.js.map +1 -1
  89. package/dist/generic/querySQLFilters.js +5 -10
  90. package/dist/generic/querySQLFilters.js.map +1 -1
  91. package/dist/generic/runQuery.d.ts +2 -2
  92. package/dist/generic/runQuery.js +5 -9
  93. package/dist/generic/runQuery.js.map +1 -1
  94. package/dist/generic/runQuerySQLFilterImplementations.d.ts +1 -1
  95. package/dist/generic/runQuerySQLFilterImplementations.js +4 -8
  96. package/dist/generic/runQuerySQLFilterImplementations.js.map +1 -1
  97. package/dist/generic/runReport.d.ts +2 -2
  98. package/dist/generic/runReport.js +5 -9
  99. package/dist/generic/runReport.js.map +1 -1
  100. package/dist/generic/securityInfo.d.ts +2 -2
  101. package/dist/generic/securityInfo.js +10 -20
  102. package/dist/generic/securityInfo.js.map +1 -1
  103. package/dist/generic/telemetryManager.js +20 -32
  104. package/dist/generic/telemetryManager.js.map +1 -1
  105. package/dist/generic/transactionGroup.d.ts +1 -1
  106. package/dist/generic/transactionGroup.d.ts.map +1 -1
  107. package/dist/generic/transactionGroup.js +11 -19
  108. package/dist/generic/transactionGroup.js.map +1 -1
  109. package/dist/generic/util.js +15 -31
  110. package/dist/generic/util.js.map +1 -1
  111. package/dist/index.d.ts +34 -34
  112. package/dist/index.js +45 -63
  113. package/dist/index.js.map +1 -1
  114. package/dist/views/runView.d.ts +3 -3
  115. package/dist/views/runView.js +6 -11
  116. package/dist/views/runView.js.map +1 -1
  117. package/dist/views/viewInfo.d.ts +3 -3
  118. package/dist/views/viewInfo.js +10 -17
  119. package/dist/views/viewInfo.js.map +1 -1
  120. package/package.json +11 -10
@@ -1,15 +1,12 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.RecordMergeResult = exports.RecordMergeDetailResult = exports.RecordMergeRequest = exports.RecordDependency = exports.EntityDependency = exports.ValidationResult = exports.ValidationErrorInfo = exports.ValidationErrorType = exports.EntityInfo = exports.EntitySettingInfo = exports.EntityDocumentTypeInfo = exports.EntityFieldInfo = exports.GeneratedFormSectionType = exports.EntityFieldValueInfo = exports.EntityFieldValueListType = exports.EntityFieldGraphQLType = exports.EntityFieldTSType = exports.EntityPermissionInfo = exports.EntityUserPermissionInfo = exports.EntityPermissionType = exports.EntityRelationshipInfo = exports.RecordChange = exports.RecordChangeStatus = void 0;
4
- const baseInfo_1 = require("./baseInfo");
5
- const metadata_1 = require("./metadata");
6
- const util_1 = require("./util");
7
- const logging_1 = require("./logging");
8
- const global_1 = require("@memberjunction/global");
1
+ import { BaseInfo } from "./baseInfo.js";
2
+ import { Metadata } from "./metadata.js";
3
+ import { TypeScriptTypeFromSQLType, SQLFullType, SQLMaxLength, FormatValue, CodeNameFromString } from "./util.js";
4
+ import { LogError } from "./logging.js";
5
+ import { WarningManager, SafeJSONParse } from "@memberjunction/global";
9
6
  /**
10
7
  * The possible status values for a record change
11
8
  */
12
- exports.RecordChangeStatus = {
9
+ export const RecordChangeStatus = {
13
10
  Pending: 'Pending',
14
11
  Complete: 'Complete',
15
12
  Error: 'Error',
@@ -17,9 +14,9 @@ exports.RecordChangeStatus = {
17
14
  /**
18
15
  * Record Change object has information on a change to a record in the Record Changes entity
19
16
  */
20
- class RecordChange extends baseInfo_1.BaseInfo {
17
+ export class RecordChange extends BaseInfo {
21
18
  get StatusValue() {
22
- return exports.RecordChangeStatus[this.Status?.trim()];
19
+ return RecordChangeStatus[this.Status?.trim()];
23
20
  }
24
21
  get Changes() {
25
22
  return JSON.parse(this.ChangesJSON);
@@ -40,7 +37,6 @@ class RecordChange extends baseInfo_1.BaseInfo {
40
37
  this.copyInitData(initData);
41
38
  }
42
39
  }
43
- exports.RecordChange = RecordChange;
44
40
  /**
45
41
  * Information about the Entity Relationship between the Entity and the Related Entity - this class
46
42
  * maps to information in the Entity Relationships metadata entity.
@@ -49,7 +45,7 @@ exports.RecordChange = RecordChange;
49
45
  * Metadata about relationships between entities including display preferences for the UI.
50
46
  * Defines foreign key relationships and how they should be represented in the user interface.
51
47
  */
52
- class EntityRelationshipInfo extends baseInfo_1.BaseInfo {
48
+ export class EntityRelationshipInfo extends BaseInfo {
53
49
  constructor(initData) {
54
50
  super();
55
51
  this.ID = null;
@@ -97,54 +93,52 @@ class EntityRelationshipInfo extends baseInfo_1.BaseInfo {
97
93
  this.copyInitData(initData);
98
94
  }
99
95
  }
100
- exports.EntityRelationshipInfo = EntityRelationshipInfo;
101
- exports.EntityPermissionType = {
96
+ export const EntityPermissionType = {
102
97
  Read: 'Read',
103
98
  Create: 'Create',
104
99
  Update: 'Update',
105
100
  Delete: 'Delete',
106
101
  };
107
- class EntityUserPermissionInfo {
102
+ export class EntityUserPermissionInfo {
108
103
  constructor() {
109
104
  this.ID = null;
110
105
  }
111
106
  }
112
- exports.EntityUserPermissionInfo = EntityUserPermissionInfo;
113
107
  /**
114
108
  * Security settings for each entity.
115
109
  * Controls which roles can perform create, read, update, and delete operations.
116
110
  */
117
- class EntityPermissionInfo extends baseInfo_1.BaseInfo {
111
+ export class EntityPermissionInfo extends BaseInfo {
118
112
  get CreateRLSFilterObject() {
119
- return this.RLSFilter(exports.EntityPermissionType.Create);
113
+ return this.RLSFilter(EntityPermissionType.Create);
120
114
  }
121
115
  get ReadRLSFilterObject() {
122
- return this.RLSFilter(exports.EntityPermissionType.Read);
116
+ return this.RLSFilter(EntityPermissionType.Read);
123
117
  }
124
118
  get UpdateRLSFilterObject() {
125
- return this.RLSFilter(exports.EntityPermissionType.Update);
119
+ return this.RLSFilter(EntityPermissionType.Update);
126
120
  }
127
121
  get DeleteRLSFilterObject() {
128
- return this.RLSFilter(exports.EntityPermissionType.Delete);
122
+ return this.RLSFilter(EntityPermissionType.Delete);
129
123
  }
130
124
  RLSFilter(type) {
131
125
  let fID = "";
132
126
  switch (type) {
133
- case exports.EntityPermissionType.Read:
127
+ case EntityPermissionType.Read:
134
128
  fID = this.ReadRLSFilterID;
135
129
  break;
136
- case exports.EntityPermissionType.Create:
130
+ case EntityPermissionType.Create:
137
131
  fID = this.CreateRLSFilterID;
138
132
  break;
139
- case exports.EntityPermissionType.Update:
133
+ case EntityPermissionType.Update:
140
134
  fID = this.UpdateRLSFilterID;
141
135
  break;
142
- case exports.EntityPermissionType.Delete:
136
+ case EntityPermissionType.Delete:
143
137
  fID = this.DeleteRLSFilterID;
144
138
  break;
145
139
  }
146
140
  if (fID && fID.length > 0)
147
- return metadata_1.Metadata.Provider.RowLevelSecurityFilters.find(f => f.ID === fID);
141
+ return Metadata.Provider.RowLevelSecurityFilters.find(f => f.ID === fID);
148
142
  }
149
143
  constructor(initData) {
150
144
  super();
@@ -172,21 +166,20 @@ class EntityPermissionInfo extends baseInfo_1.BaseInfo {
172
166
  this.copyInitData(initData);
173
167
  }
174
168
  }
175
- exports.EntityPermissionInfo = EntityPermissionInfo;
176
- exports.EntityFieldTSType = {
169
+ export const EntityFieldTSType = {
177
170
  String: 'string',
178
171
  Number: 'number',
179
172
  Date: 'Date',
180
173
  Boolean: 'boolean',
181
174
  };
182
- exports.EntityFieldGraphQLType = {
175
+ export const EntityFieldGraphQLType = {
183
176
  Int: 'Int',
184
177
  Float: 'Float',
185
178
  String: 'String',
186
179
  Boolean: 'Boolean',
187
180
  Timestamp: 'Timestamp',
188
181
  };
189
- exports.EntityFieldValueListType = {
182
+ export const EntityFieldValueListType = {
190
183
  None: 'None',
191
184
  List: 'List',
192
185
  ListOrUserEntry: 'ListOrUserEntry',
@@ -195,7 +188,7 @@ exports.EntityFieldValueListType = {
195
188
  * Defines allowed values for entity fields with value lists.
196
189
  * Supports dropdowns, validations, and data integrity constraints.
197
190
  */
198
- class EntityFieldValueInfo extends baseInfo_1.BaseInfo {
191
+ export class EntityFieldValueInfo extends BaseInfo {
199
192
  constructor(initData) {
200
193
  super();
201
194
  this.ID = null;
@@ -209,8 +202,7 @@ class EntityFieldValueInfo extends baseInfo_1.BaseInfo {
209
202
  this.copyInitData(initData);
210
203
  }
211
204
  }
212
- exports.EntityFieldValueInfo = EntityFieldValueInfo;
213
- exports.GeneratedFormSectionType = {
205
+ export const GeneratedFormSectionType = {
214
206
  Top: 'Top',
215
207
  Details: 'Details',
216
208
  Category: 'Category',
@@ -222,7 +214,36 @@ exports.GeneratedFormSectionType = {
222
214
  * List of all fields within each entity with metadata about each field.
223
215
  * Includes data types, relationships, defaults, and UI display preferences.
224
216
  */
225
- class EntityFieldInfo extends baseInfo_1.BaseInfo {
217
+ export class EntityFieldInfo extends BaseInfo {
218
+ /**
219
+ * JSON configuration for additional fields to join from the related entity.
220
+ * Parsed from the RelatedEntityJoinFields column. Uses lazy initialization and caching
221
+ * to avoid repeated JSON.parse calls. If parsing fails, it won't be attempted again.
222
+ */
223
+ get RelatedEntityJoinFieldsConfig() {
224
+ // If parsing already failed, don't try again
225
+ if (this._relatedEntityJoinFieldsFailedParsing) {
226
+ return null;
227
+ }
228
+ // If no RelatedEntityJoinFields data, return null
229
+ if (!this.RelatedEntityJoinFields) {
230
+ return null;
231
+ }
232
+ // If already parsed and cached, return cached value
233
+ if (this._relatedEntityJoinFieldsParsed !== undefined) {
234
+ return this._relatedEntityJoinFieldsParsed;
235
+ }
236
+ // Parse and cache the configuration
237
+ const parsed = SafeJSONParse(this.RelatedEntityJoinFields, false);
238
+ if (parsed === null) {
239
+ // Parsing failed - mark as failed so we don't try again
240
+ this._relatedEntityJoinFieldsFailedParsing = true;
241
+ return null;
242
+ }
243
+ // Successfully parsed - cache and return
244
+ this._relatedEntityJoinFieldsParsed = parsed;
245
+ return parsed;
246
+ }
226
247
  get EntityFieldValues() {
227
248
  return this._EntityFieldValues;
228
249
  }
@@ -231,34 +252,34 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
231
252
  */
232
253
  get ValueListTypeEnum() {
233
254
  if (this.ValueListType == null)
234
- return exports.EntityFieldValueListType.None;
255
+ return EntityFieldValueListType.None;
235
256
  else {
236
257
  // iterate through list of possibilities from enum and compare lcase
237
- for (let enumMember in exports.EntityFieldValueListType) {
238
- if (typeof exports.EntityFieldValueListType[enumMember] === 'string' &&
258
+ for (let enumMember in EntityFieldValueListType) {
259
+ if (typeof EntityFieldValueListType[enumMember] === 'string' &&
239
260
  enumMember.toLowerCase().trim() === this.ValueListType.toLowerCase().trim()) {
240
- return exports.EntityFieldValueListType[enumMember];
261
+ return EntityFieldValueListType[enumMember];
241
262
  }
242
263
  }
243
264
  }
244
265
  }
245
266
  get GeneratedFormSectionType() {
246
- return exports.GeneratedFormSectionType[this.GeneratedFormSection];
267
+ return GeneratedFormSectionType[this.GeneratedFormSection];
247
268
  }
248
269
  /**
249
270
  * Provides the TypeScript type for a given Entity Field. This is useful to map
250
271
  * a wide array of database types to a narrower set of TypeScript types.
251
272
  */
252
273
  get TSType() {
253
- switch ((0, util_1.TypeScriptTypeFromSQLType)(this.Type).toLowerCase()) {
274
+ switch (TypeScriptTypeFromSQLType(this.Type).toLowerCase()) {
254
275
  case "number":
255
- return exports.EntityFieldTSType.Number;
276
+ return EntityFieldTSType.Number;
256
277
  case "boolean":
257
- return exports.EntityFieldTSType.Boolean;
278
+ return EntityFieldTSType.Boolean;
258
279
  case "date":
259
- return exports.EntityFieldTSType.Date;
280
+ return EntityFieldTSType.Date;
260
281
  default:
261
- return exports.EntityFieldTSType.String;
282
+ return EntityFieldTSType.String;
262
283
  }
263
284
  }
264
285
  /**
@@ -303,8 +324,8 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
303
324
  */
304
325
  get NeedsQuotes() {
305
326
  switch (this.TSType) {
306
- case exports.EntityFieldTSType.Number:
307
- case exports.EntityFieldTSType.Boolean:
327
+ case EntityFieldTSType.Number:
328
+ case EntityFieldTSType.Boolean:
308
329
  return false;
309
330
  default:
310
331
  return true;
@@ -312,12 +333,12 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
312
333
  }
313
334
  get CodeName() {
314
335
  if (this._codeName === null) {
315
- this._codeName = (0, util_1.CodeNameFromString)(this.Name);
336
+ this._codeName = CodeNameFromString(this.Name);
316
337
  }
317
338
  return this._codeName;
318
339
  }
319
340
  get GraphQLType() {
320
- switch ((0, util_1.TypeScriptTypeFromSQLType)(this.Type).toLowerCase()) {
341
+ switch (TypeScriptTypeFromSQLType(this.Type).toLowerCase()) {
321
342
  case "number":
322
343
  // either an int or float if not an int
323
344
  switch (this.Type.toLowerCase().trim()) {
@@ -325,26 +346,26 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
325
346
  case "smallint":
326
347
  case "tinyint":
327
348
  case "bigint":
328
- return exports.EntityFieldGraphQLType.Int;
349
+ return EntityFieldGraphQLType.Int;
329
350
  default:
330
- return exports.EntityFieldGraphQLType.Float;
351
+ return EntityFieldGraphQLType.Float;
331
352
  }
332
353
  case "boolean":
333
- return exports.EntityFieldGraphQLType.Boolean;
354
+ return EntityFieldGraphQLType.Boolean;
334
355
  case "date":
335
- return exports.EntityFieldGraphQLType.Timestamp;
356
+ return EntityFieldGraphQLType.Timestamp;
336
357
  default:
337
- return exports.EntityFieldGraphQLType.String;
358
+ return EntityFieldGraphQLType.String;
338
359
  }
339
360
  }
340
361
  /**
341
362
  * Returns a string with the full SQL data type that combines, as appropriate, Type, Length, Precision and Scale where these attributes are relevant to the Type
342
363
  */
343
364
  get SQLFullType() {
344
- return (0, util_1.SQLFullType)(this.Type, this.Length, this.Precision, this.Scale);
365
+ return SQLFullType(this.Type, this.Length, this.Precision, this.Scale);
345
366
  }
346
367
  get MaxLength() {
347
- return (0, util_1.SQLMaxLength)(this.Type, this.Length);
368
+ return SQLMaxLength(this.Type, this.Length);
348
369
  }
349
370
  get ReadOnly() {
350
371
  return this.IsVirtual ||
@@ -422,7 +443,7 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
422
443
  * @returns either the original string value or a formatted version. If the format cannot be applied an an exception occurs it is captured and the error is put to the log, and the original value is returned
423
444
  */
424
445
  FormatValue(value, decimals = 2, currency = 'USD', maxLength = 0, trailingChars = "...") {
425
- return (0, util_1.FormatValue)(this.Type, value, decimals, currency, maxLength, trailingChars);
446
+ return FormatValue(this.Type, value, decimals, currency, maxLength, trailingChars);
426
447
  }
427
448
  constructor(initData = null) {
428
449
  super();
@@ -446,6 +467,16 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
446
467
  * If true, the field is the primary key for the entity. There must be one primary key field per entity.
447
468
  */
448
469
  this.IsPrimaryKey = null;
470
+ /**
471
+ * Indicates this field is a soft primary key (metadata-defined, not a database constraint).
472
+ * The view ORs this with IsPrimaryKey, so existing code checking IsPrimaryKey works automatically.
473
+ */
474
+ this.IsSoftPrimaryKey = null;
475
+ /**
476
+ * Indicates this field is a soft foreign key (metadata-defined, not a database constraint).
477
+ * When set to 1, RelatedEntityID and RelatedEntityFieldName are preserved and not overwritten by CodeGen schema sync.
478
+ */
479
+ this.IsSoftForeignKey = null;
449
480
  /**
450
481
  * If true, the field is a unique key for the entity. There can be zero to many unique key fields per entity.
451
482
  */
@@ -476,6 +507,11 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
476
507
  this.RelatedEntityFieldName = null;
477
508
  this.IncludeRelatedEntityNameFieldInBaseView = null;
478
509
  this.RelatedEntityNameFieldMap = null;
510
+ /**
511
+ * JSON configuration for additional fields to join from the related entity.
512
+ * Parsed from the RelatedEntityJoinFields column.
513
+ */
514
+ this.RelatedEntityJoinFields = null;
479
515
  this.RelatedEntityDisplayType = null;
480
516
  this.EntityIDFieldName = null;
481
517
  this.__mj_CreatedAt = null;
@@ -665,6 +701,15 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
665
701
  this.RelatedEntityBaseView = null;
666
702
  this.RelatedEntityCodeName = null;
667
703
  this.RelatedEntityClassName = null;
704
+ /**
705
+ * Cached parsed RelatedEntityJoinFieldsConfig to avoid repeated JSON.parse calls.
706
+ * Lazy-initialized on first access.
707
+ */
708
+ this._relatedEntityJoinFieldsParsed = undefined;
709
+ /**
710
+ * Flag to track if RelatedEntityJoinFieldsConfig parsing failed to avoid repeated parse attempts on bad JSON.
711
+ */
712
+ this._relatedEntityJoinFieldsFailedParsing = false;
668
713
  /**
669
714
  * For fields in the database that have characters invalid for SQL identifiers in them, we need to replace those characters with _ in order to create variables for stored procedures.
670
715
  * This property returns a consistent CodeName you can use everywhere to refer to the field when generated variable names
@@ -699,15 +744,26 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
699
744
  }
700
745
  if (entityField.Status?.trim().toLowerCase() === 'deprecated') {
701
746
  // Record deprecation warning - will be batched and displayed after debounce period
702
- global_1.WarningManager.Instance.RecordFieldDeprecationWarning(entityField.Entity, entityField.Name, callerName);
747
+ WarningManager.Instance.RecordFieldDeprecationWarning(entityField.Entity, entityField.Name, callerName);
703
748
  }
704
749
  else if (entityField.Status?.trim().toLowerCase() === 'disabled') {
705
750
  // console.error and throw the exception
706
751
  const exceptionString = `${callerName}: Entity Field ${entityField.Entity}.${entityField.Name} is disabled and cannot be used.`;
707
- (0, logging_1.LogError)(exceptionString);
752
+ LogError(exceptionString);
708
753
  throw new Error(exceptionString);
709
754
  }
710
755
  }
756
+ /**
757
+ * Readonly array of SQL Server date/time functions that return the current date/time
758
+ */
759
+ static { this.SQL_CURRENT_DATE_FUNCTIONS = [
760
+ 'getdate()',
761
+ 'getutcdate()',
762
+ 'sysdatetimeoffset()',
763
+ 'current_timestamp',
764
+ 'sysdatetime()',
765
+ 'sysutcdatetime()'
766
+ ]; }
711
767
  /**
712
768
  * Checks if a default value is a SQL Server function that returns the current date/time
713
769
  * @param defaultValue - The default value to check
@@ -724,18 +780,6 @@ class EntityFieldInfo extends baseInfo_1.BaseInfo {
724
780
  return EntityFieldInfo.SQL_CURRENT_DATE_FUNCTIONS.some(func => normalizedValue.includes(func));
725
781
  }
726
782
  }
727
- exports.EntityFieldInfo = EntityFieldInfo;
728
- /**
729
- * Readonly array of SQL Server date/time functions that return the current date/time
730
- */
731
- EntityFieldInfo.SQL_CURRENT_DATE_FUNCTIONS = [
732
- 'getdate()',
733
- 'getutcdate()',
734
- 'sysdatetimeoffset()',
735
- 'current_timestamp',
736
- 'sysdatetime()',
737
- 'sysutcdatetime()'
738
- ];
739
783
  /**
740
784
  * Entity Document Type Info object has information about the document types that exist across all entities. When Entity Documents are created they are associated with a document type.
741
785
  */
@@ -743,7 +787,7 @@ EntityFieldInfo.SQL_CURRENT_DATE_FUNCTIONS = [
743
787
  * Defines types of documents that can be generated from entity data.
744
788
  * Supports various output formats for entity records.
745
789
  */
746
- class EntityDocumentTypeInfo extends baseInfo_1.BaseInfo {
790
+ export class EntityDocumentTypeInfo extends BaseInfo {
747
791
  constructor(initData = null) {
748
792
  super();
749
793
  this.ID = null;
@@ -754,7 +798,6 @@ class EntityDocumentTypeInfo extends baseInfo_1.BaseInfo {
754
798
  this.copyInitData(initData);
755
799
  }
756
800
  }
757
- exports.EntityDocumentTypeInfo = EntityDocumentTypeInfo;
758
801
  /**
759
802
  * Settings allow you to store key/value pairs of information that can be used to configure the behavior of the entity.
760
803
  */
@@ -762,7 +805,7 @@ exports.EntityDocumentTypeInfo = EntityDocumentTypeInfo;
762
805
  * Stores entity-specific configuration settings.
763
806
  * Allows customization of how entities function within the system.
764
807
  */
765
- class EntitySettingInfo extends baseInfo_1.BaseInfo {
808
+ export class EntitySettingInfo extends BaseInfo {
766
809
  constructor(initData = null) {
767
810
  super();
768
811
  this.ID = null;
@@ -775,12 +818,11 @@ class EntitySettingInfo extends baseInfo_1.BaseInfo {
775
818
  this.copyInitData(initData);
776
819
  }
777
820
  }
778
- exports.EntitySettingInfo = EntitySettingInfo;
779
821
  /**
780
822
  * Catalog of all entities across all schemas.
781
823
  * Contains comprehensive metadata about each entity including its database mappings, security settings, and UI preferences.
782
824
  */
783
- class EntityInfo extends baseInfo_1.BaseInfo {
825
+ export class EntityInfo extends BaseInfo {
784
826
  /**
785
827
  * Returns the primary key field for the entity. For entities with a composite primary key, use the PrimaryKeys property which returns all.
786
828
  * In the case of a composite primary key, the PrimaryKey property will return the first field in the sequence of the primary key fields.
@@ -844,6 +886,9 @@ class EntityInfo extends baseInfo_1.BaseInfo {
844
886
  get Settings() {
845
887
  return this._Settings;
846
888
  }
889
+ static { this.__createdAtFieldName = '__mj_CreatedAt'; }
890
+ static { this.__updatedAtFieldName = '__mj_UpdatedAt'; }
891
+ static { this.__deletedAtFieldName = '__mj_DeletedAt'; }
847
892
  /**
848
893
  * Returns the name of the special reserved field that is used to store the CreatedAt timestamp across all of MJ. This is only used when an entity has TrackRecordChanges turned on
849
894
  */
@@ -875,12 +920,12 @@ class EntityInfo extends baseInfo_1.BaseInfo {
875
920
  }
876
921
  if (entity.Status?.trim().toLowerCase() === 'deprecated') {
877
922
  // Record deprecation warning - will be batched and displayed after debounce period
878
- global_1.WarningManager.Instance.RecordEntityDeprecationWarning(entity.Name, callerName);
923
+ WarningManager.Instance.RecordEntityDeprecationWarning(entity.Name, callerName);
879
924
  }
880
925
  else if (entity.Status?.trim().toLowerCase() === 'disabled') {
881
926
  // console.error and throw the exception
882
927
  const exceptionString = `${callerName}: Entity ${entity.Name} is disabled and cannot be used.`;
883
- (0, logging_1.LogError)(exceptionString);
928
+ LogError(exceptionString);
884
929
  throw new Error(exceptionString);
885
930
  }
886
931
  }
@@ -955,19 +1000,19 @@ class EntityInfo extends baseInfo_1.BaseInfo {
955
1000
  const roleMatch = user.UserRoles?.find((r) => r.RoleID === ep.RoleID);
956
1001
  if (roleMatch) { // user has this role
957
1002
  switch (type) {
958
- case exports.EntityPermissionType.Create:
1003
+ case EntityPermissionType.Create:
959
1004
  if (!ep.CreateRLSFilterID)
960
1005
  return true;
961
1006
  break;
962
- case exports.EntityPermissionType.Read:
1007
+ case EntityPermissionType.Read:
963
1008
  if (!ep.ReadRLSFilterID)
964
1009
  return true;
965
1010
  break;
966
- case exports.EntityPermissionType.Update:
1011
+ case EntityPermissionType.Update:
967
1012
  if (!ep.UpdateRLSFilterID)
968
1013
  return true;
969
1014
  break;
970
- case exports.EntityPermissionType.Delete:
1015
+ case EntityPermissionType.Delete:
971
1016
  if (!ep.DeleteRLSFilterID)
972
1017
  return true;
973
1018
  break;
@@ -990,19 +1035,19 @@ class EntityInfo extends baseInfo_1.BaseInfo {
990
1035
  if (roleMatch) { // user has this role
991
1036
  let matchObject = null;
992
1037
  switch (type) {
993
- case exports.EntityPermissionType.Create:
1038
+ case EntityPermissionType.Create:
994
1039
  if (ep.CreateRLSFilterID)
995
1040
  matchObject = ep.CreateRLSFilterObject;
996
1041
  break;
997
- case exports.EntityPermissionType.Read:
1042
+ case EntityPermissionType.Read:
998
1043
  if (ep.ReadRLSFilterID)
999
1044
  matchObject = ep.ReadRLSFilterObject;
1000
1045
  break;
1001
- case exports.EntityPermissionType.Update:
1046
+ case EntityPermissionType.Update:
1002
1047
  if (ep.UpdateRLSFilterID)
1003
1048
  matchObject = ep.UpdateRLSFilterObject;
1004
1049
  break;
1005
- case exports.EntityPermissionType.Delete:
1050
+ case EntityPermissionType.Delete:
1006
1051
  if (ep.DeleteRLSFilterID)
1007
1052
  matchObject = ep.DeleteRLSFilterObject;
1008
1053
  break;
@@ -1472,47 +1517,35 @@ class EntityInfo extends baseInfo_1.BaseInfo {
1472
1517
  this._oneToManyCount = oneToManyCount;
1473
1518
  }
1474
1519
  catch (e) {
1475
- (0, logging_1.LogError)(e);
1520
+ LogError(e);
1476
1521
  }
1477
1522
  }
1478
1523
  }
1479
- exports.EntityInfo = EntityInfo;
1480
- EntityInfo.__createdAtFieldName = '__mj_CreatedAt';
1481
- EntityInfo.__updatedAtFieldName = '__mj_UpdatedAt';
1482
- EntityInfo.__deletedAtFieldName = '__mj_DeletedAt';
1483
1524
  // Re-export validation types from @memberjunction/global for backward compatibility
1484
- var global_2 = require("@memberjunction/global");
1485
- Object.defineProperty(exports, "ValidationErrorType", { enumerable: true, get: function () { return global_2.ValidationErrorType; } });
1486
- Object.defineProperty(exports, "ValidationErrorInfo", { enumerable: true, get: function () { return global_2.ValidationErrorInfo; } });
1487
- Object.defineProperty(exports, "ValidationResult", { enumerable: true, get: function () { return global_2.ValidationResult; } });
1525
+ export { ValidationErrorType, ValidationErrorInfo, ValidationResult } from '@memberjunction/global';
1488
1526
  /**
1489
1527
  * Information about the link between two entities
1490
1528
  */
1491
- class EntityDependency {
1529
+ export class EntityDependency {
1492
1530
  }
1493
- exports.EntityDependency = EntityDependency;
1494
1531
  /**
1495
1532
  * Information about the link between two records
1496
1533
  */
1497
- class RecordDependency {
1534
+ export class RecordDependency {
1498
1535
  }
1499
- exports.RecordDependency = RecordDependency;
1500
1536
  /**
1501
1537
  * Information about a merge request including the entity, the surviving record and the records to merge into the surviving record. Additionally, there is an optional field map that can be used to override field values in the surviving record to values specified.
1502
1538
  */
1503
- class RecordMergeRequest {
1539
+ export class RecordMergeRequest {
1504
1540
  }
1505
- exports.RecordMergeRequest = RecordMergeRequest;
1506
1541
  /**
1507
1542
  * The result of a merge request for a single record
1508
1543
  */
1509
- class RecordMergeDetailResult {
1544
+ export class RecordMergeDetailResult {
1510
1545
  }
1511
- exports.RecordMergeDetailResult = RecordMergeDetailResult;
1512
1546
  /**
1513
1547
  * The result of a merge request
1514
1548
  */
1515
- class RecordMergeResult {
1549
+ export class RecordMergeResult {
1516
1550
  }
1517
- exports.RecordMergeResult = RecordMergeResult;
1518
1551
  //# sourceMappingURL=entityInfo.js.map