@memberjunction/codegen-lib 2.111.1 → 2.112.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 (58) hide show
  1. package/dist/Angular/angular-codegen.d.ts +1 -1
  2. package/dist/Angular/angular-codegen.d.ts.map +1 -1
  3. package/dist/Angular/angular-codegen.js +119 -80
  4. package/dist/Angular/angular-codegen.js.map +1 -1
  5. package/dist/Angular/join-grid-related-entity-component.d.ts +1 -1
  6. package/dist/Angular/join-grid-related-entity-component.d.ts.map +1 -1
  7. package/dist/Angular/join-grid-related-entity-component.js +12 -12
  8. package/dist/Angular/join-grid-related-entity-component.js.map +1 -1
  9. package/dist/Angular/related-entity-components.d.ts +1 -1
  10. package/dist/Angular/related-entity-components.d.ts.map +1 -1
  11. package/dist/Angular/related-entity-components.js +14 -14
  12. package/dist/Angular/related-entity-components.js.map +1 -1
  13. package/dist/Config/config.d.ts.map +1 -1
  14. package/dist/Config/config.js +3 -3
  15. package/dist/Config/config.js.map +1 -1
  16. package/dist/Database/dbSchema.d.ts +1 -1
  17. package/dist/Database/dbSchema.d.ts.map +1 -1
  18. package/dist/Database/dbSchema.js +14 -10
  19. package/dist/Database/dbSchema.js.map +1 -1
  20. package/dist/Database/manage-metadata.d.ts +3 -3
  21. package/dist/Database/manage-metadata.d.ts.map +1 -1
  22. package/dist/Database/manage-metadata.js +167 -139
  23. package/dist/Database/manage-metadata.js.map +1 -1
  24. package/dist/Database/sql.d.ts +1 -1
  25. package/dist/Database/sql.d.ts.map +1 -1
  26. package/dist/Database/sql.js +17 -17
  27. package/dist/Database/sql.js.map +1 -1
  28. package/dist/Database/sql_codegen.d.ts +2 -2
  29. package/dist/Database/sql_codegen.d.ts.map +1 -1
  30. package/dist/Database/sql_codegen.js +128 -119
  31. package/dist/Database/sql_codegen.js.map +1 -1
  32. package/dist/Misc/action_subclasses_codegen.d.ts.map +1 -1
  33. package/dist/Misc/action_subclasses_codegen.js +17 -17
  34. package/dist/Misc/action_subclasses_codegen.js.map +1 -1
  35. package/dist/Misc/advanced_generation.d.ts +2 -2
  36. package/dist/Misc/advanced_generation.d.ts.map +1 -1
  37. package/dist/Misc/advanced_generation.js +29 -29
  38. package/dist/Misc/advanced_generation.js.map +1 -1
  39. package/dist/Misc/createNewUser.d.ts +1 -1
  40. package/dist/Misc/createNewUser.d.ts.map +1 -1
  41. package/dist/Misc/createNewUser.js +30 -30
  42. package/dist/Misc/createNewUser.js.map +1 -1
  43. package/dist/Misc/entity_subclasses_codegen.d.ts +1 -1
  44. package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
  45. package/dist/Misc/entity_subclasses_codegen.js +56 -37
  46. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  47. package/dist/Misc/graphql_server_codegen.d.ts +1 -1
  48. package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
  49. package/dist/Misc/graphql_server_codegen.js +15 -17
  50. package/dist/Misc/graphql_server_codegen.js.map +1 -1
  51. package/dist/Misc/status_logging.d.ts +2 -2
  52. package/dist/Misc/status_logging.d.ts.map +1 -1
  53. package/dist/Misc/status_logging.js +22 -22
  54. package/dist/Misc/status_logging.js.map +1 -1
  55. package/dist/runCodeGen.d.ts.map +1 -1
  56. package/dist/runCodeGen.js +4 -4
  57. package/dist/runCodeGen.js.map +1 -1
  58. package/package.json +9 -10
@@ -27,7 +27,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
29
  exports.SQLCodeGenBase = exports.SPType = void 0;
30
- const core_1 = require("@memberjunction/core");
30
+ const global_1 = require("@memberjunction/global");
31
31
  const status_logging_1 = require("../Misc/status_logging");
32
32
  const fs = __importStar(require("fs"));
33
33
  const path_1 = __importDefault(require("path"));
@@ -36,7 +36,7 @@ const config_1 = require("../Config/config");
36
36
  const manage_metadata_1 = require("./manage-metadata");
37
37
  const sqlserver_dataprovider_1 = require("@memberjunction/sqlserver-dataprovider");
38
38
  const util_1 = require("../Misc/util");
39
- const global_1 = require("@memberjunction/global");
39
+ const global_2 = require("@memberjunction/global");
40
40
  const sql_logging_1 = require("../Misc/sql_logging");
41
41
  const temp_batch_file_1 = require("../Misc/temp_batch_file");
42
42
  exports.SPType = {
@@ -50,7 +50,7 @@ exports.SPType = {
50
50
  * of that abstract base class and other databases will be sub-classes of the abstract base class as well.
51
51
  */
52
52
  class SQLCodeGenBase {
53
- _sqlUtilityObject = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(sql_1.SQLUtilityBase);
53
+ _sqlUtilityObject = global_2.MJGlobal.Instance.ClassFactory.CreateInstance(sql_1.SQLUtilityBase);
54
54
  get SQLUtilityObject() {
55
55
  return this._sqlUtilityObject;
56
56
  }
@@ -105,7 +105,7 @@ class SQLCodeGenBase {
105
105
  // objects like spCreate for a given entity might reference the vw for that entity
106
106
  (0, status_logging_1.startSpinner)('Running custom SQL scripts...');
107
107
  const startTime = new Date();
108
- if (!await this.runCustomSQLScripts(pool, 'before-sql')) {
108
+ if (!(await this.runCustomSQLScripts(pool, 'before-sql'))) {
109
109
  (0, status_logging_1.failSpinner)('Failed to run custom SQL scripts');
110
110
  return false;
111
111
  }
@@ -113,12 +113,12 @@ class SQLCodeGenBase {
113
113
  // ALWAYS use the first filter where we only include entities that have IncludeInAPI = 1
114
114
  // Sort entities by name for deterministic processing order (workaround until MJCore fix in issue #1436)
115
115
  const sortedEntities = entities.sort((a, b) => a.Name.localeCompare(b.Name));
116
- const baselineEntities = sortedEntities.filter(e => e.IncludeInAPI);
117
- const includedEntities = baselineEntities.filter(e => config_1.configInfo.excludeSchemas.find(s => s.toLowerCase() === e.SchemaName.toLowerCase()) === undefined); //only include entities that are NOT in the excludeSchemas list
118
- const excludedEntities = baselineEntities.filter(e => config_1.configInfo.excludeSchemas.find(s => s.toLowerCase() === e.SchemaName.toLowerCase()) !== undefined); //only include entities that ARE in the excludeSchemas list in this array
116
+ const baselineEntities = sortedEntities.filter((e) => e.IncludeInAPI);
117
+ const includedEntities = baselineEntities.filter((e) => config_1.configInfo.excludeSchemas.find((s) => s.toLowerCase() === e.SchemaName.toLowerCase()) === undefined); //only include entities that are NOT in the excludeSchemas list
118
+ const excludedEntities = baselineEntities.filter((e) => config_1.configInfo.excludeSchemas.find((s) => s.toLowerCase() === e.SchemaName.toLowerCase()) !== undefined); //only include entities that ARE in the excludeSchemas list in this array
119
119
  // Initialize temp batch files for each schema
120
120
  // These will be populated as SQL is generated and will be used for actual execution
121
- const schemas = Array.from(new Set(baselineEntities.map(e => e.SchemaName)));
121
+ const schemas = Array.from(new Set(baselineEntities.map((e) => e.SchemaName)));
122
122
  temp_batch_file_1.TempBatchFile.initialize(directory, schemas);
123
123
  // STEP 1.5 - Check for cascade delete dependencies that require regeneration
124
124
  (0, status_logging_1.startSpinner)('Analyzing cascade delete dependencies...');
@@ -132,10 +132,10 @@ class SQLCodeGenBase {
132
132
  (0, status_logging_1.startSpinner)(`Generating SQL for ${includedEntities.length} entities...`);
133
133
  const step2StartTime = new Date();
134
134
  // First, separate entities that need cascade delete regeneration from others
135
- const entitiesWithoutCascadeRegeneration = includedEntities.filter(e => !this.entitiesNeedingDeleteSPRegeneration.has(e.ID));
135
+ const entitiesWithoutCascadeRegeneration = includedEntities.filter((e) => !this.entitiesNeedingDeleteSPRegeneration.has(e.ID));
136
136
  const entitiesForCascadeRegeneration = this.orderedEntitiesForDeleteSPRegeneration
137
- .map(id => includedEntities.find(e => e.ID === id))
138
- .filter(e => e !== undefined);
137
+ .map((id) => includedEntities.find((e) => e.ID === id))
138
+ .filter((e) => e !== undefined);
139
139
  // Generate SQL for entities that don't need cascade delete regeneration
140
140
  const genResult = await this.generateAndExecuteEntitySQLToSeparateFiles({
141
141
  pool,
@@ -145,7 +145,7 @@ class SQLCodeGenBase {
145
145
  skipExecution: true, // skip execution because we execute it all in a giant batch below
146
146
  writeFiles: true,
147
147
  batchSize: 5,
148
- enableSQLLoggingForNewOrModifiedEntities: true
148
+ enableSQLLoggingForNewOrModifiedEntities: true,
149
149
  }); // enable sql logging for NEW entities....
150
150
  if (!genResult.Success) {
151
151
  (0, status_logging_1.failSpinner)('Failed to generate entity SQL files');
@@ -162,7 +162,7 @@ class SQLCodeGenBase {
162
162
  skipExecution: true,
163
163
  writeFiles: true,
164
164
  batchSize: 1, // Process sequentially to maintain dependency order
165
- enableSQLLoggingForNewOrModifiedEntities: true
165
+ enableSQLLoggingForNewOrModifiedEntities: true,
166
166
  });
167
167
  if (!cascadeGenResult.Success) {
168
168
  (0, status_logging_1.failSpinner)('Failed to regenerate cascade delete SPs');
@@ -180,7 +180,7 @@ class SQLCodeGenBase {
180
180
  skipExecution: true, // skip execution because we execute it all in a giant batch below
181
181
  batchSize: 5,
182
182
  writeFiles: true,
183
- enableSQLLoggingForNewOrModifiedEntities: false /*don't log this stuff, it is just permissions for excluded entities*/
183
+ enableSQLLoggingForNewOrModifiedEntities: false /*don't log this stuff, it is just permissions for excluded entities*/,
184
184
  });
185
185
  if (!genResult2.Success) {
186
186
  (0, status_logging_1.failSpinner)('Failed to generate permissions for excluded entities');
@@ -216,11 +216,11 @@ class SQLCodeGenBase {
216
216
  }
217
217
  const step2eEndTime = new Date();
218
218
  (0, status_logging_1.succeedSpinner)(`SQL execution completed (${(step2eEndTime.getTime() - step2eStartTime.getTime()) / 1000}s)`);
219
- const manageMD = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(manage_metadata_1.ManageMetadataBase);
219
+ const manageMD = global_2.MJGlobal.Instance.ClassFactory.CreateInstance(manage_metadata_1.ManageMetadataBase);
220
220
  // STEP 3 - re-run the process to manage entity fields since the Step 1 and 2 above might have resulted in differences in base view columns compared to what we had at first
221
221
  // we CAN skip the entity field values part because that wouldn't change from the first time we ran it
222
222
  (0, status_logging_1.startSpinner)('Managing entity fields metadata...');
223
- if (!await manageMD.manageEntityFields(pool, config_1.configInfo.excludeSchemas, true, true, currentUser)) {
223
+ if (!(await manageMD.manageEntityFields(pool, config_1.configInfo.excludeSchemas, true, true, currentUser))) {
224
224
  (0, status_logging_1.failSpinner)('Failed to manage entity fields');
225
225
  return false;
226
226
  }
@@ -229,7 +229,7 @@ class SQLCodeGenBase {
229
229
  // STEP 4- Apply permissions, executing all .permissions files
230
230
  (0, status_logging_1.startSpinner)('Applying permissions...');
231
231
  const step4StartTime = new Date();
232
- if (!await this.applyPermissions(pool, directory, baselineEntities)) {
232
+ if (!(await this.applyPermissions(pool, directory, baselineEntities))) {
233
233
  (0, status_logging_1.failSpinner)('Failed to apply permissions');
234
234
  return false;
235
235
  }
@@ -237,14 +237,14 @@ class SQLCodeGenBase {
237
237
  // STEP 5 - execute any custom SQL scripts that should run afterwards
238
238
  (0, status_logging_1.startSpinner)('Running post-generation SQL scripts...');
239
239
  const step5StartTime = new Date();
240
- if (!await this.runCustomSQLScripts(pool, 'after-sql')) {
240
+ if (!(await this.runCustomSQLScripts(pool, 'after-sql'))) {
241
241
  (0, status_logging_1.failSpinner)('Failed to run post-generation SQL scripts');
242
242
  return false;
243
243
  }
244
244
  (0, status_logging_1.succeedSpinner)(`Post-generation scripts completed (${(new Date().getTime() - step5StartTime.getTime()) / 1000}s)`);
245
- (0, status_logging_1.succeedSpinner)(`CodeGen completed successfully (${((new Date().getTime() - startTime.getTime()) / 1000)}s total)`);
245
+ (0, status_logging_1.succeedSpinner)(`CodeGen completed successfully (${(new Date().getTime() - startTime.getTime()) / 1000}s total)`);
246
246
  // now - we need to tell our metadata object to refresh itself
247
- const md = new core_1.Metadata();
247
+ const md = new global_1.Metadata();
248
248
  await md.Refresh();
249
249
  return true;
250
250
  }
@@ -262,7 +262,7 @@ class SQLCodeGenBase {
262
262
  if (scripts) {
263
263
  for (let i = 0; i < scripts.length; ++i) {
264
264
  const s = scripts[i];
265
- if (!await this.SQLUtilityObject.executeSQLFile(s.scriptFile)) {
265
+ if (!(await this.SQLUtilityObject.executeSQLFile(s.scriptFile))) {
266
266
  (0, status_logging_1.logError)(`Error executing custom '${when}' SQL script ${s.scriptFile}`);
267
267
  bSuccess = false; // keep going if we have more scripts, but make sure we return false
268
268
  }
@@ -335,7 +335,7 @@ class SQLCodeGenBase {
335
335
  for (let i = 0; i < totalEntities; i += options.batchSize) {
336
336
  const batch = options.entities.slice(i, i + options.batchSize);
337
337
  const promises = batch.map(async (e) => {
338
- const pkeyField = e.Fields.find(f => f.IsPrimaryKey);
338
+ const pkeyField = e.Fields.find((f) => f.IsPrimaryKey);
339
339
  if (!pkeyField) {
340
340
  (0, status_logging_1.logError)(`SKIPPING ENTITY: Entity ${e.Name}, because it does not have a primary key field defined. A table must have a primary key defined to quality to be a MemberJunction entity`);
341
341
  return { Success: false, Files: [] };
@@ -347,11 +347,11 @@ class SQLCodeGenBase {
347
347
  onlyPermissions: options.onlyPermissions,
348
348
  writeFiles: options.writeFiles,
349
349
  skipExecution: options.skipExecution,
350
- enableSQLLoggingForNewOrModifiedEntities: options.enableSQLLoggingForNewOrModifiedEntities
350
+ enableSQLLoggingForNewOrModifiedEntities: options.enableSQLLoggingForNewOrModifiedEntities,
351
351
  });
352
352
  });
353
353
  const results = await Promise.all(promises);
354
- results.forEach(r => {
354
+ results.forEach((r) => {
355
355
  if (!r.Success)
356
356
  bFail = true; // keep going, but will return false at the end
357
357
  files.push(...r.Files); // add the files to the main files array
@@ -367,7 +367,7 @@ class SQLCodeGenBase {
367
367
  deleteGeneratedEntityFiles(directory, entities) {
368
368
  try {
369
369
  // for the schemas associated with the specified entities, clean out all the generated files
370
- const schemaNames = entities.map(e => e.SchemaName).filter((value, index, self) => self.indexOf(value) === index);
370
+ const schemaNames = entities.map((e) => e.SchemaName).filter((value, index, self) => self.indexOf(value) === index);
371
371
  for (const s of schemaNames) {
372
372
  const fullPath = path_1.default.join(directory, s);
373
373
  // now, within each schema directory, clean out all the generated files
@@ -381,7 +381,7 @@ class SQLCodeGenBase {
381
381
  //logMessage(` Directory '${fullPath}' does not exist so no need to delete previously generated SQL`, 'Info');
382
382
  }
383
383
  if (stats?.isDirectory()) {
384
- const files = fs.readdirSync(fullPath).filter(f => f.endsWith('.generated.sql') || f.endsWith('.permissions.generated.sql'));
384
+ const files = fs.readdirSync(fullPath).filter((f) => f.endsWith('.generated.sql') || f.endsWith('.permissions.generated.sql'));
385
385
  for (const f of files) {
386
386
  const filePath = path_1.default.join(fullPath, f);
387
387
  fs.unlinkSync(filePath);
@@ -396,7 +396,7 @@ class SQLCodeGenBase {
396
396
  createCombinedEntitySQLFiles(directory, entities) {
397
397
  // first, get a disinct list of schemanames from the entities
398
398
  const files = [];
399
- const schemaNames = entities.map(e => e.SchemaName).filter((value, index, self) => self.indexOf(value) === index);
399
+ const schemaNames = entities.map((e) => e.SchemaName).filter((value, index, self) => self.indexOf(value) === index);
400
400
  for (const s of schemaNames) {
401
401
  // generate the all-entities.sql file and all-entities.permissions.sql file in each schema folder
402
402
  const fullPath = path_1.default.join(directory, s);
@@ -414,8 +414,8 @@ class SQLCodeGenBase {
414
414
  const { sql, permissionsSQL, files } = await this.generateSingleEntitySQLToSeparateFiles(options); // this creates the files and returns a single string with all the SQL we can then execute
415
415
  if (!options.skipExecution) {
416
416
  return {
417
- Success: await this.SQLUtilityObject.executeSQLScript(options.pool, sql + "\n\nGO\n\n" + permissionsSQL, true), // combine the SQL and permissions and execute it,
418
- Files: files
417
+ Success: await this.SQLUtilityObject.executeSQLScript(options.pool, sql + '\n\nGO\n\n' + permissionsSQL, true), // combine the SQL and permissions and execute it,
418
+ Files: files,
419
419
  };
420
420
  }
421
421
  else
@@ -431,23 +431,23 @@ class SQLCodeGenBase {
431
431
  let shouldLog = false;
432
432
  if (logSql) {
433
433
  // Check if entity is in new or modified lists
434
- const isNewOrModified = !!manage_metadata_1.ManageMetadataBase.newEntityList.find(e => e === entity.Name) ||
435
- !!manage_metadata_1.ManageMetadataBase.modifiedEntityList.find(e => e === entity.Name);
434
+ const isNewOrModified = !!manage_metadata_1.ManageMetadataBase.newEntityList.find((e) => e === entity.Name) ||
435
+ !!manage_metadata_1.ManageMetadataBase.modifiedEntityList.find((e) => e === entity.Name);
436
436
  // Check if entity is being regenerated due to cascade dependencies
437
- const isCascadeDependencyRegeneration = description.toLowerCase().includes('spdelete') &&
438
- this.entitiesNeedingDeleteSPRegeneration.has(entity.ID);
437
+ const isCascadeDependencyRegeneration = description.toLowerCase().includes('spdelete') && this.entitiesNeedingDeleteSPRegeneration.has(entity.ID);
439
438
  // Check if force regeneration is enabled for relevant SQL types
440
- const isForceRegeneration = config_1.configInfo.forceRegeneration?.enabled && ((description.toLowerCase().includes('base view') && config_1.configInfo.forceRegeneration.baseViews) ||
441
- (description.toLowerCase().includes('root id function') && config_1.configInfo.forceRegeneration.baseViews) || // TVFs are part of base view infrastructure
442
- (description.toLowerCase().includes('spcreate') && config_1.configInfo.forceRegeneration.spCreate) ||
443
- (description.toLowerCase().includes('spupdate') && config_1.configInfo.forceRegeneration.spUpdate) ||
444
- (description.toLowerCase().includes('spdelete') && config_1.configInfo.forceRegeneration.spDelete) ||
445
- (description.toLowerCase().includes('index') && config_1.configInfo.forceRegeneration.indexes) ||
446
- (description.toLowerCase().includes('full text search') && config_1.configInfo.forceRegeneration.fullTextSearch) ||
447
- (config_1.configInfo.forceRegeneration.allStoredProcedures &&
448
- (description.toLowerCase().includes('spcreate') ||
449
- description.toLowerCase().includes('spupdate') ||
450
- description.toLowerCase().includes('spdelete'))));
439
+ const isForceRegeneration = config_1.configInfo.forceRegeneration?.enabled &&
440
+ ((description.toLowerCase().includes('base view') && config_1.configInfo.forceRegeneration.baseViews) ||
441
+ (description.toLowerCase().includes('root id function') && config_1.configInfo.forceRegeneration.baseViews) || // TVFs are part of base view infrastructure
442
+ (description.toLowerCase().includes('spcreate') && config_1.configInfo.forceRegeneration.spCreate) ||
443
+ (description.toLowerCase().includes('spupdate') && config_1.configInfo.forceRegeneration.spUpdate) ||
444
+ (description.toLowerCase().includes('spdelete') && config_1.configInfo.forceRegeneration.spDelete) ||
445
+ (description.toLowerCase().includes('index') && config_1.configInfo.forceRegeneration.indexes) ||
446
+ (description.toLowerCase().includes('full text search') && config_1.configInfo.forceRegeneration.fullTextSearch) ||
447
+ (config_1.configInfo.forceRegeneration.allStoredProcedures &&
448
+ (description.toLowerCase().includes('spcreate') ||
449
+ description.toLowerCase().includes('spupdate') ||
450
+ description.toLowerCase().includes('spdelete'))));
451
451
  // Determine if we should log based on entity state and force regeneration settings
452
452
  if (isNewOrModified) {
453
453
  // Always log new or modified entities
@@ -458,7 +458,7 @@ class SQLCodeGenBase {
458
458
  shouldLog = true;
459
459
  }
460
460
  else if (isForceRegeneration) {
461
- // For force regeneration, the specific type flags (spCreate, baseViews, etc.)
461
+ // For force regeneration, the specific type flags (spCreate, baseViews, etc.)
462
462
  // already filtered this - now we just need to check entity filtering
463
463
  if (this.filterEntitiesQualifiedForRegeneration) {
464
464
  // Only log if entity is in the qualified list
@@ -505,9 +505,7 @@ class SQLCodeGenBase {
505
505
  // BASE VIEW AND RELATED TVFs
506
506
  // Only generate if BaseViewGenerated is true (respects custom views where it's false)
507
507
  // forceRegeneration.baseViews only forces regeneration of views where BaseViewGenerated=true
508
- if (!options.onlyPermissions &&
509
- options.entity.BaseViewGenerated &&
510
- !options.entity.VirtualEntity) {
508
+ if (!options.onlyPermissions && options.entity.BaseViewGenerated && !options.entity.VirtualEntity) {
511
509
  // ROOT ID FUNCTIONS (TVFs)
512
510
  // Generate inline Table Value Functions for recursive foreign keys
513
511
  // These must be created BEFORE the view that references them
@@ -515,8 +513,7 @@ class SQLCodeGenBase {
515
513
  if (recursiveFKs.length > 0) {
516
514
  for (const field of recursiveFKs) {
517
515
  const functionName = `fn${options.entity.BaseTable}${field.Name}_GetRootID`;
518
- const s = this.generateSingleEntitySQLFileHeader(options.entity, functionName) +
519
- this.generateRootIDFunction(options.entity, field);
516
+ const s = this.generateSingleEntitySQLFileHeader(options.entity, functionName) + this.generateRootIDFunction(options.entity, field);
520
517
  const filePath = path_1.default.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('function', options.entity.SchemaName, functionName, false, true));
521
518
  if (options.writeFiles) {
522
519
  this.logSQLForNewOrModifiedEntity(options.entity, s, `Root ID Function SQL for ${options.entity.Name}.${field.Name}`, options.enableSQLLoggingForNewOrModifiedEntities);
@@ -528,7 +525,8 @@ class SQLCodeGenBase {
528
525
  }
529
526
  }
530
527
  // Generate the base view (which may reference the TVFs created above)
531
- const s = this.generateSingleEntitySQLFileHeader(options.entity, options.entity.BaseView) + await this.generateBaseView(options.pool, options.entity);
528
+ const s = this.generateSingleEntitySQLFileHeader(options.entity, options.entity.BaseView) +
529
+ (await this.generateBaseView(options.pool, options.entity));
532
530
  const filePath = path_1.default.join(options.directory, this.SQLUtilityObject.getDBObjectFileName('view', options.entity.SchemaName, options.entity.BaseView, false, true));
533
531
  if (options.writeFiles) {
534
532
  this.logSQLForNewOrModifiedEntity(options.entity, s, `Base View SQL for ${options.entity.Name}`, options.enableSQLLoggingForNewOrModifiedEntities);
@@ -538,7 +536,8 @@ class SQLCodeGenBase {
538
536
  sRet += s + '\nGO\n';
539
537
  }
540
538
  // always generate permissions for the base view
541
- const s = this.generateSingleEntitySQLFileHeader(options.entity, 'Permissions for ' + options.entity.BaseView) + this.generateViewPermissions(options.entity);
539
+ const s = this.generateSingleEntitySQLFileHeader(options.entity, 'Permissions for ' + options.entity.BaseView) +
540
+ this.generateViewPermissions(options.entity);
542
541
  if (s.length > 0)
543
542
  permissionsSQL += s + '\nGO\n';
544
543
  if (options.writeFiles) {
@@ -618,8 +617,7 @@ class SQLCodeGenBase {
618
617
  // OR if this entity has cascade delete dependencies that require regeneration
619
618
  // forceRegeneration only forces regeneration of SPs where spDeleteGenerated=true
620
619
  if (!options.onlyPermissions &&
621
- (options.entity.spDeleteGenerated ||
622
- this.entitiesNeedingDeleteSPRegeneration.has(options.entity.ID))) {
620
+ (options.entity.spDeleteGenerated || this.entitiesNeedingDeleteSPRegeneration.has(options.entity.ID))) {
623
621
  // generate the delete SP
624
622
  if (this.entitiesNeedingDeleteSPRegeneration.has(options.entity.ID)) {
625
623
  (0, status_logging_1.logStatus)(` Regenerating ${spName} due to cascade dependency changes`);
@@ -721,37 +719,37 @@ class SQLCodeGenBase {
721
719
  let sOutput = '';
722
720
  if (entity.BaseViewGenerated && !entity.VirtualEntity)
723
721
  // generated the base view (will include permissions)
724
- sOutput += await this.generateBaseView(pool, entity) + '\n\n';
722
+ sOutput += (await this.generateBaseView(pool, entity)) + '\n\n';
723
+ // still generate the permissions for the view even if a custom view
725
724
  else
726
- // still generate the permissions for the view even if a custom view
727
725
  sOutput += this.generateViewPermissions(entity) + '\n\n';
728
726
  if (entity.AllowCreateAPI && !entity.VirtualEntity) {
729
727
  if (entity.spCreateGenerated)
730
728
  // generated SP, will include permissions
731
729
  sOutput += this.generateSPCreate(entity) + '\n\n';
730
+ // custom SP, still generate the permissions
732
731
  else
733
- // custom SP, still generate the permissions
734
732
  sOutput += this.generateSPPermissions(entity, entity.spCreate, exports.SPType.Create) + '\n\n';
735
733
  }
736
734
  if (entity.AllowUpdateAPI && !entity.VirtualEntity) {
737
735
  if (entity.spUpdateGenerated)
738
736
  // generated SP, will include permissions
739
737
  sOutput += this.generateSPUpdate(entity) + '\n\n';
738
+ // custom SP, still generate the permissions
740
739
  else
741
- // custom SP, still generate the permissions
742
740
  sOutput += this.generateSPPermissions(entity, entity.spUpdate, exports.SPType.Update) + '\n\n';
743
741
  }
744
742
  if (entity.AllowDeleteAPI && !entity.VirtualEntity) {
745
743
  if (entity.spDeleteGenerated)
746
744
  // generated SP, will include permissions
747
745
  sOutput += this.generateSPDelete(entity) + '\n\n';
746
+ // custom SP, still generate the permissions
748
747
  else
749
- // custom SP, still generate the permissions
750
748
  sOutput += this.generateSPPermissions(entity, entity.spDelete, exports.SPType.Delete) + '\n\n';
751
749
  }
752
750
  // check to see if the entity supports full text search or not
753
751
  if (entity.FullTextSearchEnabled) {
754
- sOutput += await this.generateEntityFullTextSearchSQL(pool, entity) + '\n\n';
752
+ sOutput += (await this.generateEntityFullTextSearchSQL(pool, entity)) + '\n\n';
755
753
  }
756
754
  return sOutput;
757
755
  }
@@ -771,7 +769,9 @@ class SQLCodeGenBase {
771
769
  `;
772
770
  }
773
771
  if (entity.FullTextIndexGenerated) {
774
- const fullTextFields = entity.Fields.filter(f => f.FullTextSearchEnabled).map(f => `${f.Name} LANGUAGE 'English'`).join(', ');
772
+ const fullTextFields = entity.Fields.filter((f) => f.FullTextSearchEnabled)
773
+ .map((f) => `${f.Name} LANGUAGE 'English'`)
774
+ .join(', ');
775
775
  if (fullTextFields.length === 0)
776
776
  throw new Error(`FullTextIndexGenerated is true for entity ${entity.Name}, but no fields are marked as FullTextSearchEnabled`);
777
777
  // drop and recreate the full text index
@@ -803,24 +803,28 @@ class SQLCodeGenBase {
803
803
  GO
804
804
  `;
805
805
  }
806
- const functionName = entity.FullTextSearchFunction && entity.FullTextSearchFunction.length > 0 ? entity.FullTextSearchFunction : `fnSearch${entity.CodeName}`;
806
+ const functionName = entity.FullTextSearchFunction && entity.FullTextSearchFunction.length > 0
807
+ ? entity.FullTextSearchFunction
808
+ : `fnSearch${entity.CodeName}`;
807
809
  if (entity.FullTextSearchFunctionGenerated) {
808
- const fullTextFieldsSimple = entity.Fields.filter(f => f.FullTextSearchEnabled).map(f => '[' + f.Name + ']').join(', ');
810
+ const fullTextFieldsSimple = entity.Fields.filter((f) => f.FullTextSearchEnabled)
811
+ .map((f) => '[' + f.Name + ']')
812
+ .join(', ');
809
813
  if (fullTextFieldsSimple.length === 0)
810
814
  throw new Error(`FullTextSearchFunctionGenerated is true for entity ${entity.Name}, but no fields are marked as FullTextSearchEnabled`);
811
815
  if (!entity.FullTextSearchFunction || entity.FullTextSearchFunction.length === 0) {
812
816
  // update this in the DB
813
- const md = new core_1.Metadata();
817
+ const md = new global_1.Metadata();
814
818
  const u = sqlserver_dataprovider_1.UserCache.Instance.Users[0];
815
819
  if (!u)
816
820
  throw new Error('Could not find the first user in the cache, cant generate the full text search function without a user');
817
821
  const e = await md.GetEntityObject('Entities', u);
818
822
  await e.Load(entity.ID);
819
823
  e.FullTextSearchFunction = functionName;
820
- if (!await e.Save())
824
+ if (!(await e.Save()))
821
825
  throw new Error(`Could not update the FullTextSearchFunction for entity ${entity.Name}`);
822
826
  }
823
- const pkeyList = entity.PrimaryKeys.map(pk => '[' + pk.Name + ']').join(', ');
827
+ const pkeyList = entity.PrimaryKeys.map((pk) => '[' + pk.Name + ']').join(', ');
824
828
  // drop and recreate the full text search function
825
829
  sql += ` -- DROP AND RECREATE THE FULL TEXT SEARCH FUNCTION
826
830
  -- Create an inline table-valued function to perform full-text search
@@ -921,8 +925,7 @@ CREATE INDEX ${indexName} ON [${entity.SchemaName}].[${entity.BaseTable}] ([${f.
921
925
  * Returns array of field info objects representing recursive relationships
922
926
  */
923
927
  detectRecursiveForeignKeys(entity) {
924
- return entity.Fields.filter(field => field.RelatedEntityID != null &&
925
- field.RelatedEntityID === entity.ID);
928
+ return entity.Fields.filter((field) => field.RelatedEntityID != null && field.RelatedEntityID === entity.ID);
926
929
  }
927
930
  /**
928
931
  * Generates an inline Table Value Function for calculating root ID for a recursive FK field
@@ -1000,20 +1003,20 @@ GO
1000
1003
  if (recursiveFKs.length === 0) {
1001
1004
  return '';
1002
1005
  }
1003
- return recursiveFKs
1004
- .map(field => this.generateRootIDFunction(entity, field))
1005
- .join('\n');
1006
+ return recursiveFKs.map((field) => this.generateRootIDFunction(entity, field)).join('\n');
1006
1007
  }
1007
1008
  /**
1008
1009
  * Generates the SELECT clause additions for root fields from TVFs
1009
1010
  * Example: , root_ParentID.RootID AS [RootParentID]
1010
1011
  */
1011
1012
  generateRootFieldSelects(recursiveFKs, classNameFirstChar) {
1012
- return recursiveFKs.map(field => {
1013
+ return recursiveFKs
1014
+ .map((field) => {
1013
1015
  const alias = `root_${field.Name}`;
1014
1016
  const columnName = `Root${field.Name}`;
1015
1017
  return `,\n ${alias}.RootID AS [${columnName}]`;
1016
- }).join('');
1018
+ })
1019
+ .join('');
1017
1020
  }
1018
1021
  /**
1019
1022
  * Generates OUTER APPLY joins to inline Table Value Functions for root ID calculation
@@ -1026,11 +1029,13 @@ GO
1026
1029
  const primaryKey = entity.FirstPrimaryKey.Name;
1027
1030
  const schemaName = entity.SchemaName;
1028
1031
  const tableName = entity.BaseTable;
1029
- const joins = recursiveFKs.map(field => {
1032
+ const joins = recursiveFKs
1033
+ .map((field) => {
1030
1034
  const functionName = `fn${tableName}${field.Name}_GetRootID`;
1031
1035
  const alias = `root_${field.Name}`;
1032
1036
  return `OUTER APPLY\n [${schemaName}].[${functionName}]([${classNameFirstChar}].[${primaryKey}], [${classNameFirstChar}].[${field.Name}]) AS ${alias}`;
1033
- }).join('\n');
1037
+ })
1038
+ .join('\n');
1034
1039
  return '\n' + joins;
1035
1040
  }
1036
1041
  /**
@@ -1046,9 +1051,11 @@ GO
1046
1051
  const relatedFieldsString = await this.generateBaseViewRelatedFieldsString(pool, entity.Fields);
1047
1052
  const relatedFieldsJoinString = this.generateBaseViewJoins(entity, entity.Fields);
1048
1053
  const permissions = this.generateViewPermissions(entity);
1049
- const whereClause = entity.DeleteType === 'Soft' ? `WHERE
1050
- ${classNameFirstChar}.[${core_1.EntityInfo.DeletedAtFieldName}] IS NULL
1051
- ` : '';
1054
+ const whereClause = entity.DeleteType === 'Soft'
1055
+ ? `WHERE
1056
+ ${classNameFirstChar}.[${global_1.EntityInfo.DeletedAtFieldName}] IS NULL
1057
+ `
1058
+ : '';
1052
1059
  // Detect recursive foreign keys and generate TVF joins and root field selects
1053
1060
  const recursiveFKs = this.detectRecursiveForeignKeys(entity);
1054
1061
  const rootFields = recursiveFKs.length > 0 ? this.generateRootFieldSelects(recursiveFKs, classNameFirstChar) : '';
@@ -1058,7 +1065,7 @@ GO
1058
1065
  ----- BASE VIEW FOR ENTITY: ${entity.Name}
1059
1066
  ----- SCHEMA: ${entity.SchemaName}
1060
1067
  ----- BASE TABLE: ${entity.BaseTable}
1061
- ----- PRIMARY KEY: ${entity.PrimaryKeys.map(pk => pk.Name).join(', ')}
1068
+ ----- PRIMARY KEY: ${entity.PrimaryKeys.map((pk) => pk.Name).join(', ')}
1062
1069
  ------------------------------------------------------------
1063
1070
  IF OBJECT_ID('[${entity.SchemaName}].[${viewName}]', 'V') IS NOT NULL
1064
1071
  DROP VIEW [${entity.SchemaName}].[${viewName}];
@@ -1098,9 +1105,9 @@ ${whereClause}GO${permissions}
1098
1105
  async generateBaseViewRelatedFieldsString(pool, entityFields) {
1099
1106
  let sOutput = '';
1100
1107
  let fieldCount = 0;
1101
- const manageMD = global_1.MJGlobal.Instance.ClassFactory.CreateInstance(manage_metadata_1.ManageMetadataBase);
1108
+ const manageMD = global_2.MJGlobal.Instance.ClassFactory.CreateInstance(manage_metadata_1.ManageMetadataBase);
1102
1109
  // next get the fields that are related entities and have the IncludeRelatedEntityNameFieldInBaseView flag set to true
1103
- const qualifyingFields = entityFields.filter(f => f.RelatedEntityID && f.IncludeRelatedEntityNameFieldInBaseView);
1110
+ const qualifyingFields = entityFields.filter((f) => f.RelatedEntityID && f.IncludeRelatedEntityNameFieldInBaseView);
1104
1111
  for (const ef of qualifyingFields) {
1105
1112
  const { nameField, nameFieldIsVirtual } = this.getIsNameFieldForSingleEntity(ef.RelatedEntity);
1106
1113
  if (nameField !== '') {
@@ -1111,7 +1118,8 @@ ${whereClause}GO${permissions}
1111
1118
  const candidateName = this.stripID(ef.Name);
1112
1119
  // check to make sure candidateName is not already a field name in the base table (other than a virtual field of course, as that is what we're creating)
1113
1120
  // because if it is, we need to change it to something else
1114
- const bFound = entityFields.find(f => f.IsVirtual === false && f.Name.trim().toLowerCase() === candidateName.trim().toLowerCase()) !== undefined;
1121
+ const bFound = entityFields.find((f) => f.IsVirtual === false && f.Name.trim().toLowerCase() === candidateName.trim().toLowerCase()) !==
1122
+ undefined;
1115
1123
  if (bFound)
1116
1124
  ef._RelatedEntityNameFieldMap = candidateName + '_Virtual';
1117
1125
  else
@@ -1135,8 +1143,8 @@ ${whereClause}GO${permissions}
1135
1143
  return sOutput;
1136
1144
  }
1137
1145
  getIsNameFieldForSingleEntity(entityName) {
1138
- const md = new core_1.Metadata(); // use the full metadata entity list, not the filtered version that we receive
1139
- const e = md.Entities.find(e => e.Name === entityName);
1146
+ const md = new global_1.Metadata(); // use the full metadata entity list, not the filtered version that we receive
1147
+ const e = md.Entities.find((e) => e.Name === entityName);
1140
1148
  if (e) {
1141
1149
  const ef = e.NameField;
1142
1150
  if (e.NameField)
@@ -1156,9 +1164,7 @@ ${whereClause}GO${permissions}
1156
1164
  let sOutput = '';
1157
1165
  for (let i = 0; i < entity.Permissions.length; i++) {
1158
1166
  const ep = entity.Permissions[i];
1159
- if ((type == exports.SPType.Create && ep.CanCreate) ||
1160
- (type == exports.SPType.Update && ep.CanUpdate) ||
1161
- (type == exports.SPType.Delete && ep.CanDelete)) {
1167
+ if ((type == exports.SPType.Create && ep.CanCreate) || (type == exports.SPType.Update && ep.CanUpdate) || (type == exports.SPType.Delete && ep.CanDelete)) {
1162
1168
  if (ep.RoleSQLName && ep.RoleSQLName.length > 0) {
1163
1169
  sOutput += (sOutput === '' ? `GRANT EXECUTE ON [${entity.SchemaName}].[${spName}] TO ` : ', ') + `[${ep.RoleSQLName}]`;
1164
1170
  }
@@ -1270,7 +1276,9 @@ CREATE PROCEDURE [${entity.SchemaName}].[${spName}]
1270
1276
  AS
1271
1277
  BEGIN
1272
1278
  SET NOCOUNT ON;
1273
- ${preInsertCode}${preInsertCode.includes('INSERT INTO') ? '' : `
1279
+ ${preInsertCode}${preInsertCode.includes('INSERT INTO')
1280
+ ? ''
1281
+ : `
1274
1282
  INSERT INTO
1275
1283
  [${entity.SchemaName}].[${entity.BaseTable}]
1276
1284
  (
@@ -1287,12 +1295,12 @@ GO${permissions}
1287
1295
  `;
1288
1296
  }
1289
1297
  generateUpdatedAtTrigger(entity) {
1290
- const updatedAtField = entity.Fields.find(f => f.Name.toLowerCase().trim() === core_1.EntityInfo.UpdatedAtFieldName.toLowerCase().trim());
1298
+ const updatedAtField = entity.Fields.find((f) => f.Name.toLowerCase().trim() === global_1.EntityInfo.UpdatedAtFieldName.toLowerCase().trim());
1291
1299
  if (!updatedAtField)
1292
1300
  return '';
1293
1301
  const triggerStatement = `
1294
1302
  ------------------------------------------------------------
1295
- ----- TRIGGER FOR ${core_1.EntityInfo.UpdatedAtFieldName} field for the ${entity.BaseTable} table
1303
+ ----- TRIGGER FOR ${global_1.EntityInfo.UpdatedAtFieldName} field for the ${entity.BaseTable} table
1296
1304
  ------------------------------------------------------------
1297
1305
  IF OBJECT_ID('[${entity.SchemaName}].[trgUpdate${entity.ClassName}]', 'TR') IS NOT NULL
1298
1306
  DROP TRIGGER [${entity.SchemaName}].[trgUpdate${entity.ClassName}];
@@ -1306,12 +1314,12 @@ BEGIN
1306
1314
  UPDATE
1307
1315
  [${entity.SchemaName}].[${entity.BaseTable}]
1308
1316
  SET
1309
- ${core_1.EntityInfo.UpdatedAtFieldName} = GETUTCDATE()
1317
+ ${global_1.EntityInfo.UpdatedAtFieldName} = GETUTCDATE()
1310
1318
  FROM
1311
1319
  [${entity.SchemaName}].[${entity.BaseTable}] AS _organicTable
1312
1320
  INNER JOIN
1313
1321
  INSERTED AS I ON
1314
- ${entity.PrimaryKeys.map(k => `_organicTable.[${k.Name}] = I.[${k.Name}]`).join(' AND ')};
1322
+ ${entity.PrimaryKeys.map((k) => `_organicTable.[${k.Name}] = I.[${k.Name}]`).join(' AND ')};
1315
1323
  END;
1316
1324
  GO`;
1317
1325
  return triggerStatement;
@@ -1320,14 +1328,14 @@ GO`;
1320
1328
  const spName = entity.spUpdate ? entity.spUpdate : `spUpdate${entity.BaseTableCodeName}`;
1321
1329
  const efParamString = this.createEntityFieldsParamString(entity.Fields, true);
1322
1330
  const permissions = this.generateSPPermissions(entity, spName, exports.SPType.Update);
1323
- const hasUpdatedAtField = entity.Fields.find(f => f.Name.toLowerCase().trim() === core_1.EntityInfo.UpdatedAtFieldName.trim().toLowerCase()) !== undefined;
1331
+ const hasUpdatedAtField = entity.Fields.find((f) => f.Name.toLowerCase().trim() === global_1.EntityInfo.UpdatedAtFieldName.trim().toLowerCase()) !== undefined;
1324
1332
  const updatedAtTrigger = hasUpdatedAtField ? this.generateUpdatedAtTrigger(entity) : '';
1325
1333
  let selectUpdatedRecord = `SELECT
1326
1334
  *
1327
1335
  FROM
1328
1336
  [${entity.SchemaName}].[${entity.BaseView}]
1329
1337
  WHERE
1330
- ${entity.PrimaryKeys.map(k => `[${k.Name}] = @${k.CodeName}`).join(' AND ')}
1338
+ ${entity.PrimaryKeys.map((k) => `[${k.Name}] = @${k.CodeName}`).join(' AND ')}
1331
1339
  `;
1332
1340
  return `
1333
1341
  ------------------------------------------------------------
@@ -1347,7 +1355,7 @@ BEGIN
1347
1355
  SET
1348
1356
  ${this.createEntityFieldsUpdateString(entity.Fields)}
1349
1357
  WHERE
1350
- ${entity.PrimaryKeys.map(k => `[${k.Name}] = @${k.CodeName}`).join(' AND ')}
1358
+ ${entity.PrimaryKeys.map((k) => `[${k.Name}] = @${k.CodeName}`).join(' AND ')}
1351
1359
 
1352
1360
  -- Check if the update was successful
1353
1361
  IF @@ROWCOUNT = 0
@@ -1386,7 +1394,7 @@ ${updatedAtTrigger}
1386
1394
  'current_timestamp',
1387
1395
  'user_name()',
1388
1396
  'suser_name()',
1389
- 'system_user'
1397
+ 'system_user',
1390
1398
  ];
1391
1399
  // Check if this is a SQL function
1392
1400
  for (const func of sqlFunctions) {
@@ -1446,7 +1454,11 @@ ${updatedAtTrigger}
1446
1454
  const ef = entityFields[i];
1447
1455
  // we only want fields that are (a) not primary keys, or if a pkey, not an auto-increment pkey and (b) not virtual fields and (c) updateable fields and (d) not auto-increment fields if they're not pkeys)
1448
1456
  // ALSO: if excludePrimaryKey is true, skip all primary key fields
1449
- if ((excludePrimaryKey && ef.IsPrimaryKey) || (ef.IsPrimaryKey && autoGeneratedPrimaryKey) || ef.IsVirtual || !ef.AllowUpdateAPI || ef.AutoIncrement) {
1457
+ if ((excludePrimaryKey && ef.IsPrimaryKey) ||
1458
+ (ef.IsPrimaryKey && autoGeneratedPrimaryKey) ||
1459
+ ef.IsVirtual ||
1460
+ !ef.AllowUpdateAPI ||
1461
+ ef.AutoIncrement) {
1450
1462
  continue; // skip this field
1451
1463
  }
1452
1464
  if (!isFirst)
@@ -1459,7 +1471,7 @@ ${updatedAtTrigger}
1459
1471
  else
1460
1472
  sOutput += `NULL`; // we don't set the deleted at field on an insert, only on a delete
1461
1473
  }
1462
- else if ((prefix && prefix !== '') && !ef.IsPrimaryKey && ef.IsUniqueIdentifier && ef.HasDefaultValue && !ef.AllowsNull) {
1474
+ else if (prefix && prefix !== '' && !ef.IsPrimaryKey && ef.IsUniqueIdentifier && ef.HasDefaultValue && !ef.AllowsNull) {
1463
1475
  // this is the VALUE side (prefix not null/blank), is NOT a primary key, and is a uniqueidentifier column with a default value and does NOT allow NULL
1464
1476
  // We need to handle both NULL and the special value '00000000-0000-0000-0000-000000000000' for backward compatibility
1465
1477
  // Existing code uses the special value to indicate "use the default", so we preserve that behavior
@@ -1497,11 +1509,7 @@ ${updatedAtTrigger}
1497
1509
  let sOutput = '', isFirst = true;
1498
1510
  for (let i = 0; i < entityFields.length; ++i) {
1499
1511
  const ef = entityFields[i];
1500
- if (!ef.IsPrimaryKey &&
1501
- !ef.IsVirtual &&
1502
- ef.AllowUpdateAPI &&
1503
- !ef.AutoIncrement &&
1504
- !ef.IsSpecialDateField) {
1512
+ if (!ef.IsPrimaryKey && !ef.IsVirtual && ef.AllowUpdateAPI && !ef.AutoIncrement && !ef.IsSpecialDateField) {
1505
1513
  if (!isFirst)
1506
1514
  sOutput += ',\n ';
1507
1515
  else
@@ -1528,7 +1536,7 @@ ${updatedAtTrigger}
1528
1536
  // next up, create the delete code which is based on the type of delete the entity is set to
1529
1537
  // start off by creating the where clause first and then prepend the delete or update statement to it
1530
1538
  let deleteCode = ` WHERE
1531
- ${entity.PrimaryKeys.map(k => `[${k.Name}] = @${k.CodeName}`).join(' AND ')}
1539
+ ${entity.PrimaryKeys.map((k) => `[${k.Name}] = @${k.CodeName}`).join(' AND ')}
1532
1540
  `;
1533
1541
  if (entity.DeleteType === 'Hard') {
1534
1542
  deleteCode = ` DELETE FROM
@@ -1539,8 +1547,8 @@ ${deleteCode}`;
1539
1547
  deleteCode = ` UPDATE
1540
1548
  [${entity.SchemaName}].[${entity.BaseTable}]
1541
1549
  SET
1542
- ${core_1.EntityInfo.DeletedAtFieldName} = GETUTCDATE()
1543
- ${deleteCode} AND ${core_1.EntityInfo.DeletedAtFieldName} IS NULL -- don't update the record if it's already been deleted via a soft delete`;
1550
+ ${global_1.EntityInfo.DeletedAtFieldName} = GETUTCDATE()
1551
+ ${deleteCode} AND ${global_1.EntityInfo.DeletedAtFieldName} IS NULL -- don't update the record if it's already been deleted via a soft delete`;
1544
1552
  }
1545
1553
  // Build the NULL select statement for when no rows are affected
1546
1554
  let sNullSelect = '';
@@ -1577,7 +1585,7 @@ GO${permissions}
1577
1585
  generateCascadeDeletes(entity) {
1578
1586
  let sOutput = '';
1579
1587
  if (entity.CascadeDeletes) {
1580
- const md = new core_1.Metadata();
1588
+ const md = new global_1.Metadata();
1581
1589
  // Find all fields in other entities that are foreign keys to this entity
1582
1590
  for (const e of md.Entities) {
1583
1591
  for (const ef of e.Fields) {
@@ -1719,7 +1727,10 @@ GO${permissions}
1719
1727
  const pkComponents = this.buildPrimaryKeyComponents(entity, varPrefix);
1720
1728
  // Add primary key declarations to the declarations string
1721
1729
  // Need to add DECLARE keyword since buildPrimaryKeyComponents doesn't include it
1722
- declarations = pkComponents.varDeclarations.split(', ').map(decl => `DECLARE ${decl}`).join('\n ');
1730
+ declarations = pkComponents.varDeclarations
1731
+ .split(', ')
1732
+ .map((decl) => `DECLARE ${decl}`)
1733
+ .join('\n ');
1723
1734
  selectFields = pkComponents.selectFields;
1724
1735
  fetchInto = pkComponents.fetchInto;
1725
1736
  allParams = pkComponents.spParams;
@@ -1750,7 +1761,7 @@ GO${permissions}
1750
1761
  */
1751
1762
  analyzeCascadeDeleteDependencies(entity) {
1752
1763
  if (entity.CascadeDeletes) {
1753
- const md = new core_1.Metadata();
1764
+ const md = new global_1.Metadata();
1754
1765
  // Find all fields in other entities that are foreign keys to this entity
1755
1766
  for (const e of md.Entities) {
1756
1767
  for (const ef of e.Fields) {
@@ -1812,9 +1823,9 @@ GO${permissions}
1812
1823
  // Log the dependency map
1813
1824
  (0, status_logging_1.logStatus)(`Cascade delete dependency map built:`);
1814
1825
  for (const [dependedOnEntityId, dependentEntityIds] of this.cascadeDeleteDependencies) {
1815
- const dependedOnEntity = entities.find(e => e.ID === dependedOnEntityId);
1826
+ const dependedOnEntity = entities.find((e) => e.ID === dependedOnEntityId);
1816
1827
  const dependentNames = Array.from(dependentEntityIds)
1817
- .map(id => entities.find(e => e.ID === id)?.Name || id)
1828
+ .map((id) => entities.find((e) => e.ID === id)?.Name || id)
1818
1829
  .join(', ');
1819
1830
  (0, status_logging_1.logStatus)(` ${dependedOnEntity?.Name || dependedOnEntityId} is depended on by: ${dependentNames}`);
1820
1831
  }
@@ -1830,15 +1841,13 @@ GO${permissions}
1830
1841
  (0, status_logging_1.logStatus)(`Modified entities from metadata phase: ${modifiedEntityNames.join(', ')}`);
1831
1842
  // Convert entity names to IDs and filter for those with update API
1832
1843
  for (const entityName of modifiedEntityNames) {
1833
- const entity = entities.find(e => e.Name === entityName &&
1834
- e.AllowUpdateAPI &&
1835
- e.spUpdateGenerated);
1844
+ const entity = entities.find((e) => e.Name === entityName && e.AllowUpdateAPI && e.spUpdateGenerated);
1836
1845
  if (entity) {
1837
1846
  modifiedEntitiesMap.set(entity.Name, entity.ID);
1838
1847
  (0, status_logging_1.logStatus)(` - ${entity.Name} (${entity.ID}) has update API and will be tracked`);
1839
1848
  }
1840
1849
  else {
1841
- const nonUpdateEntity = entities.find(e => e.Name === entityName);
1850
+ const nonUpdateEntity = entities.find((e) => e.Name === entityName);
1842
1851
  if (nonUpdateEntity) {
1843
1852
  (0, status_logging_1.logStatus)(` - ${entityName} found but AllowUpdateAPI=${nonUpdateEntity.AllowUpdateAPI}, spUpdateGenerated=${nonUpdateEntity.spUpdateGenerated}`);
1844
1853
  }
@@ -1886,7 +1895,7 @@ GO${permissions}
1886
1895
  (0, status_logging_1.logStatus)(`Identified ${entitiesNeedingRegeneration.size} entities requiring delete SP regeneration due to cascade dependencies`);
1887
1896
  // Store the entity IDs that need regeneration (only if spDeleteGenerated=true)
1888
1897
  for (const entityId of entitiesNeedingRegeneration) {
1889
- const entity = entities.find(e => e.ID === entityId);
1898
+ const entity = entities.find((e) => e.ID === entityId);
1890
1899
  if (entity && entity.spDeleteGenerated) {
1891
1900
  this.entitiesNeedingDeleteSPRegeneration.add(entityId);
1892
1901
  (0, status_logging_1.logStatus)(` - Marked ${entity.Name} for delete SP regeneration (cascade dependency)`);
@@ -1900,7 +1909,7 @@ GO${permissions}
1900
1909
  if (this.orderedEntitiesForDeleteSPRegeneration.length > 0) {
1901
1910
  (0, status_logging_1.logStatus)(`Ordered entities for delete SP regeneration:`);
1902
1911
  this.orderedEntitiesForDeleteSPRegeneration.forEach((entityId, index) => {
1903
- const entity = entities.find(e => e.ID === entityId);
1912
+ const entity = entities.find((e) => e.ID === entityId);
1904
1913
  (0, status_logging_1.logStatus)(` ${index + 1}. ${entity?.Name || entityId}`);
1905
1914
  });
1906
1915
  }
@@ -1948,7 +1957,7 @@ GO${permissions}
1948
1957
  }
1949
1958
  if (visiting.has(entityId)) {
1950
1959
  // Circular dependency detected - mark it but don't fail
1951
- const entity = entities.find(e => e.ID === entityId);
1960
+ const entity = entities.find((e) => e.ID === entityId);
1952
1961
  (0, status_logging_1.logStatus)(`Warning: Circular cascade delete dependency detected involving ${entity?.Name || entityId}`);
1953
1962
  circularDeps.add(entityId);
1954
1963
  return false; // Signal circular dependency but continue processing
@@ -1975,7 +1984,7 @@ GO${permissions}
1975
1984
  if (!success && circularDeps.has(entityId)) {
1976
1985
  // Entity is part of circular dependency - add it anyway in arbitrary order
1977
1986
  // The SQL will still be generated, just not in perfect dependency order
1978
- (0, status_logging_1.logStatus)(` - Adding ${entities.find(e => e.ID === entityId)?.Name || entityId} despite circular dependency`);
1987
+ (0, status_logging_1.logStatus)(` - Adding ${entities.find((e) => e.ID === entityId)?.Name || entityId} despite circular dependency`);
1979
1988
  visited.add(entityId);
1980
1989
  ordered.push(entityId);
1981
1990
  }