@memberjunction/codegen-lib 5.30.1 → 5.31.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 (57) hide show
  1. package/README.md +2 -0
  2. package/dist/Angular/angular-codegen.js +3 -3
  3. package/dist/Angular/angular-codegen.js.map +1 -1
  4. package/dist/Angular/related-entity-components.js +1 -1
  5. package/dist/Angular/related-entity-components.js.map +1 -1
  6. package/dist/Config/config.js +1 -1
  7. package/dist/Config/config.js.map +1 -1
  8. package/dist/Database/codeGenDatabaseProvider.d.ts +266 -12
  9. package/dist/Database/codeGenDatabaseProvider.d.ts.map +1 -1
  10. package/dist/Database/codeGenDatabaseProvider.js +352 -0
  11. package/dist/Database/codeGenDatabaseProvider.js.map +1 -1
  12. package/dist/Database/manage-metadata.d.ts.map +1 -1
  13. package/dist/Database/manage-metadata.js +86 -87
  14. package/dist/Database/manage-metadata.js.map +1 -1
  15. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts +105 -17
  16. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts.map +1 -1
  17. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js +324 -94
  18. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js.map +1 -1
  19. package/dist/Database/providers/postgresql/viewDependencyCapture.d.ts +99 -0
  20. package/dist/Database/providers/postgresql/viewDependencyCapture.d.ts.map +1 -0
  21. package/dist/Database/providers/postgresql/viewDependencyCapture.js +170 -0
  22. package/dist/Database/providers/postgresql/viewDependencyCapture.js.map +1 -0
  23. package/dist/Database/providers/postgresql/viewFallback.d.ts +75 -0
  24. package/dist/Database/providers/postgresql/viewFallback.d.ts.map +1 -0
  25. package/dist/Database/providers/postgresql/viewFallback.js +172 -0
  26. package/dist/Database/providers/postgresql/viewFallback.js.map +1 -0
  27. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts +0 -25
  28. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts.map +1 -1
  29. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js +9 -113
  30. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js.map +1 -1
  31. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.d.ts +2 -0
  32. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.d.ts.map +1 -0
  33. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.js +207 -0
  34. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.js.map +1 -0
  35. package/dist/Database/sql.d.ts +9 -1
  36. package/dist/Database/sql.d.ts.map +1 -1
  37. package/dist/Database/sql.js +41 -7
  38. package/dist/Database/sql.js.map +1 -1
  39. package/dist/Database/sql_codegen.d.ts +30 -0
  40. package/dist/Database/sql_codegen.d.ts.map +1 -1
  41. package/dist/Database/sql_codegen.js +205 -44
  42. package/dist/Database/sql_codegen.js.map +1 -1
  43. package/dist/Misc/advanced_generation.js +1 -1
  44. package/dist/Misc/advanced_generation.js.map +1 -1
  45. package/dist/Misc/createNewUser.js +2 -2
  46. package/dist/Misc/createNewUser.js.map +1 -1
  47. package/dist/Misc/entity_subclasses_codegen.js +5 -5
  48. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  49. package/dist/Misc/graphql_server_codegen.js +6 -6
  50. package/dist/Misc/graphql_server_codegen.js.map +1 -1
  51. package/dist/Misc/sql_logging.d.ts.map +1 -1
  52. package/dist/Misc/sql_logging.js +14 -4
  53. package/dist/Misc/sql_logging.js.map +1 -1
  54. package/dist/runCodeGen.d.ts.map +1 -1
  55. package/dist/runCodeGen.js +66 -2
  56. package/dist/runCodeGen.js.map +1 -1
  57. package/package.json +18 -18
@@ -618,8 +618,8 @@ export class ManageMetadataBase {
618
618
  const setClauses = [];
619
619
  for (const [key, value] of attrs) {
620
620
  const paramName = `attr_${key}`;
621
- // Convert boolean values to SQL BIT (1/0)
622
- const sqlValue = typeof value === 'boolean' ? (value ? 1 : 0) : value;
621
+ // Pass booleans through — both mssql and pg drivers handle native boolean values
622
+ const sqlValue = value;
623
623
  queryParams[paramName] = sqlValue;
624
624
  setClauses.push(`${this.qi(key)} = @${paramName}`);
625
625
  }
@@ -710,7 +710,7 @@ export class ManageMetadataBase {
710
710
  * @returns
711
711
  */
712
712
  async manageMetadata(pool, currentUser) {
713
- const md = new Metadata();
713
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
714
714
  // Auto-exclude platform-specific system schemas.
715
715
  // We mutate configInfo.excludeSchemas directly so that all downstream code
716
716
  // (including createExcludeTablesAndSchemasFilter) picks up the exclusions.
@@ -803,7 +803,7 @@ export class ManageMetadataBase {
803
803
  logStatus(` > Created ${vecResult.createdCount} virtual entit${vecResult.createdCount === 1 ? 'y' : 'ies'} from config`);
804
804
  // Refresh metadata so manageVirtualEntities can find the newly-created entities
805
805
  // in the cache — otherwise EntityByName() returns null and field sync is silently skipped
806
- const md = new Metadata();
806
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
807
807
  await md.Refresh();
808
808
  }
809
809
  const veResult = await this.manageVirtualEntities(pool);
@@ -845,7 +845,7 @@ export class ManageMetadataBase {
845
845
  // virtual entities are records defined in the entity metadata and do NOT define a distinct base table
846
846
  // but they do specify a base view. We DO NOT generate a base view for a virtual entity, we simply use it to figure
847
847
  // out the fields that should be in the entity definition and add/update/delete the entity definition to match what's in the view when this runs
848
- const sql = `SELECT * FROM ${this.qs(mj_core_schema(), 'vwEntities')} WHERE VirtualEntity = 1`;
848
+ const sql = `SELECT * FROM ${this.qs(mj_core_schema(), 'vwEntities')} WHERE VirtualEntity = ${this.boolLit(true)}`;
849
849
  const virtualEntitiesResult = await this.runQuery(pool, sql);
850
850
  const virtualEntities = virtualEntitiesResult.recordset;
851
851
  let anyUpdates = false;
@@ -874,7 +874,7 @@ export class ManageMetadataBase {
874
874
  if (veFields && veFields.length > 0) {
875
875
  // we have 1+ fields, now loop through them and process each one
876
876
  // first though, remove any fields that are no longer in the view
877
- const md = new Metadata();
877
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
878
878
  const entity = md.EntityByName(virtualEntity.Name);
879
879
  if (entity) {
880
880
  const removeList = [];
@@ -919,7 +919,7 @@ export class ManageMetadataBase {
919
919
  // this protected checks to see if the field exists in the entity definition, and if not, adds it
920
920
  // if it exist it updates the entity field to match the view's data type and nullability attributes
921
921
  // first, get the entity definition
922
- const md = new Metadata();
922
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
923
923
  const entity = md.EntityByName(virtualEntity.Name);
924
924
  let newEntityFieldUUID = null;
925
925
  let didUpdate = false;
@@ -940,8 +940,8 @@ export class ManageMetadataBase {
940
940
  SET
941
941
  Sequence=${fieldSequence},
942
942
  Type='${veField.Type}',
943
- AllowsNull=${veField.AllowsNull ? 1 : 0},
944
- ${makePrimaryKey ? 'IsPrimaryKey=1,IsUnique=1,' : ''}
943
+ AllowsNull=${this.boolLit(veField.AllowsNull)},
944
+ ${makePrimaryKey ? `IsPrimaryKey=${this.boolLit(true)},IsUnique=${this.boolLit(true)},` : ''}
945
945
  Length=${veField.Length},
946
946
  Precision=${veField.Precision},
947
947
  Scale=${veField.Scale}
@@ -960,9 +960,9 @@ export class ManageMetadataBase {
960
960
  ${q('Length')}, ${q('Precision')}, ${q('Scale')},
961
961
  ${q('Sequence')}, ${q('IsPrimaryKey')}, ${q('IsUnique')},
962
962
  ${q('__mj_CreatedAt')}, ${q('__mj_UpdatedAt')} )
963
- VALUES ( '${newEntityFieldUUID}', '${entity.ID}', '${veField.FieldName}', '${veField.Type}', ${veField.AllowsNull ? 1 : 0},
963
+ VALUES ( '${newEntityFieldUUID}', '${entity.ID}', '${veField.FieldName}', '${veField.Type}', ${this.boolLit(veField.AllowsNull)},
964
964
  ${veField.Length}, ${veField.Precision}, ${veField.Scale},
965
- ${fieldSequence}, ${makePrimaryKey ? 1 : 0}, ${makePrimaryKey ? 1 : 0},
965
+ ${fieldSequence}, ${this.boolLit(makePrimaryKey)}, ${this.boolLit(makePrimaryKey)},
966
966
  ${this.utcNow()}, ${this.utcNow()}
967
967
  )`;
968
968
  await this.LogSQLAndExecute(pool, sqlAdd, `SQL text to add virtual entity field ${veField.FieldName} for entity ${virtualEntity.Name}`);
@@ -982,7 +982,7 @@ export class ManageMetadataBase {
982
982
  if (!ag.featureEnabled('VirtualEntityFieldDecoration')) {
983
983
  return; // Feature not enabled, nothing to do
984
984
  }
985
- const md = new Metadata();
985
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
986
986
  const virtualEntities = md.Entities.filter(e => e.VirtualEntity);
987
987
  if (virtualEntities.length === 0) {
988
988
  return;
@@ -1086,7 +1086,7 @@ export class ManageMetadataBase {
1086
1086
  */
1087
1087
  buildSourceEntityContext(viewDefinition) {
1088
1088
  const tableRefs = SQLParser.ExtractTableRefs(viewDefinition);
1089
- const md = new Metadata();
1089
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
1090
1090
  const sourceEntities = [];
1091
1091
  const seen = new Set();
1092
1092
  for (const tableRef of tableRefs) {
@@ -1178,12 +1178,12 @@ export class ManageMetadataBase {
1178
1178
  const sqlStatements = [];
1179
1179
  // Clear existing default PK (field #1 fallback) before applying LLM-identified PKs
1180
1180
  sqlStatements.push(`UPDATE ${this.qs(schema, 'EntityField')}
1181
- SET IsPrimaryKey=0, IsUnique=0
1182
- WHERE EntityID='${entity.ID}' AND IsPrimaryKey=1 AND IsSoftPrimaryKey=0`);
1181
+ SET IsPrimaryKey=${this.boolLit(false)}, IsUnique=${this.boolLit(false)}
1182
+ WHERE EntityID='${entity.ID}' AND IsPrimaryKey=${this.boolLit(true)} AND IsSoftPrimaryKey=${this.boolLit(false)}`);
1183
1183
  // Set LLM-identified PKs
1184
1184
  for (const pk of validPKs) {
1185
1185
  sqlStatements.push(`UPDATE ${this.qs(schema, 'EntityField')}
1186
- SET IsPrimaryKey=1, IsUnique=1, IsSoftPrimaryKey=1
1186
+ SET IsPrimaryKey=${this.boolLit(true)}, IsUnique=${this.boolLit(true)}, IsSoftPrimaryKey=${this.boolLit(true)}
1187
1187
  WHERE EntityID='${entity.ID}' AND Name='${pk}'`);
1188
1188
  logStatus(` ✓ Set PK for ${entity.Name}.${pk} (LLM-identified)`);
1189
1189
  }
@@ -1200,7 +1200,7 @@ export class ManageMetadataBase {
1200
1200
  if (!foreignKeys || foreignKeys.length === 0) {
1201
1201
  return false;
1202
1202
  }
1203
- const md = new Metadata();
1203
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
1204
1204
  const sqlStatements = [];
1205
1205
  for (const fk of foreignKeys) {
1206
1206
  // Only apply high/medium confidence
@@ -1336,7 +1336,7 @@ export class ManageMetadataBase {
1336
1336
  async manageParentEntityFields(pool) {
1337
1337
  let bSuccess = true;
1338
1338
  let anyUpdates = false;
1339
- const md = new Metadata();
1339
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
1340
1340
  const childEntities = md.Entities.filter(e => e.IsChildType);
1341
1341
  if (childEntities.length === 0) {
1342
1342
  return { success: true, anyUpdates: false };
@@ -1397,13 +1397,13 @@ export class ManageMetadataBase {
1397
1397
  !existingRow.AllowUpdateAPI;
1398
1398
  if (needsUpdate) {
1399
1399
  const sqlUpdate = `UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
1400
- SET IsVirtual=1,
1400
+ SET IsVirtual=${this.boolLit(true)},
1401
1401
  Type='${parentField.Type}',
1402
1402
  Length=${parentField.Length},
1403
1403
  Precision=${parentField.Precision},
1404
1404
  Scale=${parentField.Scale},
1405
- AllowsNull=${parentField.AllowsNull ? 1 : 0},
1406
- AllowUpdateAPI=1
1405
+ AllowsNull=${this.boolLit(parentField.AllowsNull)},
1406
+ AllowUpdateAPI=${this.boolLit(true)}
1407
1407
  WHERE ID='${existingRow.ID}'`;
1408
1408
  await this.LogSQLAndExecute(pool, sqlUpdate, `Update IS-A parent field ${parentField.Name} on ${childEntity.Name}`);
1409
1409
  bUpdated = true;
@@ -1423,9 +1423,9 @@ export class ManageMetadataBase {
1423
1423
  ${q('__mj_CreatedAt')}, ${q('__mj_UpdatedAt')})
1424
1424
  VALUES (
1425
1425
  '${newFieldID}', '${childEntity.ID}', '${parentField.Name}',
1426
- '${parentField.Type}', ${parentField.AllowsNull ? 1 : 0},
1426
+ '${parentField.Type}', ${this.boolLit(parentField.AllowsNull)},
1427
1427
  ${parentField.Length}, ${parentField.Precision}, ${parentField.Scale},
1428
- ${sequence}, 1, 1, 0, 0,
1428
+ ${sequence}, ${this.boolLit(true)}, ${this.boolLit(true)}, ${this.boolLit(false)}, ${this.boolLit(false)},
1429
1429
  ${this.utcNow()}, ${this.utcNow()})`;
1430
1430
  await this.LogSQLAndExecute(pool, sqlInsert, `Create IS-A parent field ${parentField.Name} on ${childEntity.Name}`);
1431
1431
  bUpdated = true;
@@ -1498,7 +1498,7 @@ export class ManageMetadataBase {
1498
1498
  FROM ${this.qs(mj_core_schema(), 'vwEntityFields')}
1499
1499
  WHERE
1500
1500
  RelatedEntityID IS NOT NULL AND
1501
- IsVirtual = 0 AND
1501
+ IsVirtual = ${this.boolLit(false)} AND
1502
1502
  EntityID NOT IN (SELECT ID FROM ${this.qs(mj_core_schema(), 'Entity')} WHERE SchemaName IN (${excludeSchemas.map(s => `'${s}'`).join(',')}))
1503
1503
  ORDER BY RelatedEntityID`;
1504
1504
  const entityFieldsResult = await this.runQuery(pool, sSQL);
@@ -1666,7 +1666,7 @@ export class ManageMetadataBase {
1666
1666
  FROM ${this.qs(mj_core_schema(), 'vwEntityFields')}
1667
1667
  WHERE
1668
1668
  RelatedEntityID IS NOT NULL AND
1669
- IsVirtual = 0 AND
1669
+ IsVirtual = ${this.boolLit(false)} AND
1670
1670
  EntityID NOT IN (SELECT ID FROM ${this.qs(mj_core_schema(), 'Entity')} WHERE SchemaName IN (${excludeSchemas.map(s => `'${s}'`).join(',')}))
1671
1671
  ORDER BY RelatedEntityID`;
1672
1672
  const entityFieldsResult = await this.runQuery(pool, sSQL);
@@ -1743,7 +1743,7 @@ export class ManageMetadataBase {
1743
1743
  }
1744
1744
  }
1745
1745
  // if we get here we now need to refresh our metadata object
1746
- const md = new Metadata();
1746
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
1747
1747
  await md.Refresh();
1748
1748
  }
1749
1749
  return true;
@@ -1810,7 +1810,7 @@ export class ManageMetadataBase {
1810
1810
  * other lookup failure (e.g., name shape we didn't anticipate).
1811
1811
  */
1812
1812
  resolveEntityNamesToIDs(entityNames) {
1813
- const md = new Metadata();
1813
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
1814
1814
  const ids = [];
1815
1815
  for (const name of entityNames) {
1816
1816
  if (typeof name !== 'string' || name.trim().length === 0)
@@ -1915,7 +1915,7 @@ export class ManageMetadataBase {
1915
1915
  // because entity.Fields and entity.PrimaryKeys won't reflect the updated flags
1916
1916
  if (configInfo.additionalSchemaInfo) {
1917
1917
  logStatus(' Refreshing metadata after applying soft PK/FK configuration...');
1918
- const md = new Metadata();
1918
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
1919
1919
  await md.Refresh();
1920
1920
  logStatus(' Metadata refresh complete');
1921
1921
  }
@@ -1973,7 +1973,7 @@ export class ManageMetadataBase {
1973
1973
  FROM
1974
1974
  ${this.qs(mj_core_schema(), 'vwEntities')}
1975
1975
  WHERE
1976
- VirtualEntity=0 AND
1976
+ VirtualEntity=${this.boolLit(false)} AND
1977
1977
  DeleteType='Soft' AND
1978
1978
  SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
1979
1979
  const entitiesResult = await this.runQuery(pool, sqlEntities);
@@ -2111,8 +2111,8 @@ export class ManageMetadataBase {
2111
2111
  FROM
2112
2112
  ${this.qs(mj_core_schema(), 'vwEntities')}
2113
2113
  WHERE
2114
- VirtualEntity = 0 AND
2115
- TrackRecordChanges = 1 AND
2114
+ VirtualEntity = ${this.boolLit(false)} AND
2115
+ TrackRecordChanges = ${this.boolLit(true)} AND
2116
2116
  SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
2117
2117
  const entitiesResult = await this.runQuery(pool, sqlEntities);
2118
2118
  const entities = entitiesResult.recordset;
@@ -2432,19 +2432,19 @@ export class ManageMetadataBase {
2432
2432
  ${n.Length},
2433
2433
  ${n.Precision},
2434
2434
  ${n.Scale},
2435
- ${n.AllowsNull ? 1 : 0},
2435
+ ${this.boolLit(n.AllowsNull)},
2436
2436
  ${quotedDefaultValue},
2437
- ${n.AutoIncrement ? 1 : 0},
2438
- ${n.AllowUpdateAPI ? 1 : 0},
2439
- ${n.IsVirtual ? 1 : 0},
2437
+ ${this.boolLit(n.AutoIncrement)},
2438
+ ${this.boolLit(n.AllowUpdateAPI)},
2439
+ ${this.boolLit(n.IsVirtual)},
2440
2440
  ${n.RelatedEntityID && n.RelatedEntityID.length > 0 ? `'${n.RelatedEntityID}'` : 'NULL'},
2441
2441
  ${n.RelatedEntityFieldName && n.RelatedEntityFieldName.length > 0 ? `'${n.RelatedEntityFieldName}'` : 'NULL'},
2442
- ${n.IsNameField !== null ? n.IsNameField : 0},
2443
- ${n.FieldName === 'ID' || n.IsNameField ? 1 : 0},
2444
- ${n.RelatedEntityID && n.RelatedEntityID.length > 0 ? 1 : 0},
2445
- ${bDefaultInView ? 1 : 0},
2446
- ${n.IsPrimaryKey},
2447
- ${n.IsUnique},
2442
+ ${this.boolLit(n.IsNameField !== null ? n.IsNameField : false)},
2443
+ ${this.boolLit(n.FieldName === 'ID' || n.IsNameField)},
2444
+ ${this.boolLit(n.RelatedEntityID && n.RelatedEntityID.length > 0)},
2445
+ ${this.boolLit(bDefaultInView)},
2446
+ ${this.boolLit(n.IsPrimaryKey)},
2447
+ ${this.boolLit(n.IsUnique)},
2448
2448
  '${n.RelationshipDefaultDisplayType}',
2449
2449
  ${this.utcNow()},
2450
2450
  ${this.utcNow()}
@@ -3050,7 +3050,7 @@ export class ManageMetadataBase {
3050
3050
  const newEntitiesResult = await this.runQuery(pool, sSQL);
3051
3051
  const newEntities = newEntitiesResult.recordset;
3052
3052
  if (newEntities && newEntities.length > 0) {
3053
- const md = new Metadata();
3053
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
3054
3054
  const transaction = await pool.beginTransaction();
3055
3055
  try {
3056
3056
  // wrap in a transaction so we get all of it or none of it
@@ -3082,7 +3082,7 @@ export class ManageMetadataBase {
3082
3082
  // criteria:
3083
3083
  // 1) entity has a field that is a primary key
3084
3084
  // validate all of these factors by getting the sql from SQL Server and check the result, if failure, shouldCreate=false and generate validation message, otherwise return empty validation message and true for shouldCreate.
3085
- const query = this.dbProvider.callRoutineSQL(Metadata.Provider.ConfigData.MJCoreSchemaName, 'spGetPrimaryKeyForTable', [`'${newEntity.TableName}'`, `'${newEntity.SchemaName}'`], ['TableName', 'SchemaName']);
3085
+ const query = this.dbProvider.callRoutineSQL(Metadata.Provider.ConfigData.MJCoreSchemaName, 'spGetPrimaryKeyForTable', [`'${newEntity.TableName}'`, `'${newEntity.SchemaName}'`], ['TableName', 'SchemaName']); // global-provider-ok: codegen runs offline against a single provider
3086
3086
  try {
3087
3087
  const resultResult = await ds.query(query);
3088
3088
  const result = resultResult.recordset;
@@ -3353,7 +3353,7 @@ export class ManageMetadataBase {
3353
3353
  if (RoleID) {
3354
3354
  const sSQLInsertPermission = `INSERT INTO ${this.qs(mj_core_schema(), 'EntityPermission')}
3355
3355
  (${this.qi('EntityID')}, ${this.qi('RoleID')}, ${this.qi('CanRead')}, ${this.qi('CanCreate')}, ${this.qi('CanUpdate')}, ${this.qi('CanDelete')}, ${this.qi('__mj_CreatedAt')}, ${this.qi('__mj_UpdatedAt')}) VALUES
3356
- ('${newEntityID}', '${RoleID}', ${p.CanRead ? 1 : 0}, ${p.CanCreate ? 1 : 0}, ${p.CanUpdate ? 1 : 0}, ${p.CanDelete ? 1 : 0}, ${this.utcNow()}, ${this.utcNow()})`;
3356
+ ('${newEntityID}', '${RoleID}', ${this.boolLit(p.CanRead)}, ${this.boolLit(p.CanCreate)}, ${this.boolLit(p.CanUpdate)}, ${this.boolLit(p.CanDelete)}, ${this.utcNow()}, ${this.utcNow()})`;
3357
3357
  await this.LogSQLAndExecute(pool, sSQLInsertPermission, `SQL generated to add new permission for entity ${newEntityName} for role ${p.RoleName}`);
3358
3358
  }
3359
3359
  else
@@ -3430,13 +3430,13 @@ export class ManageMetadataBase {
3430
3430
  if (!defaults?.AutoAddRolesForNewApplications) {
3431
3431
  return;
3432
3432
  }
3433
- const md = new Metadata();
3433
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
3434
3434
  for (const roleDef of defaults.Roles) {
3435
3435
  const role = md.Roles.find(r => r.Name.trim().toLowerCase() === roleDef.RoleName.trim().toLowerCase());
3436
3436
  if (role) {
3437
3437
  const sSQLInsert = `INSERT INTO ${this.qs(mj_core_schema(), 'ApplicationRole')}
3438
3438
  (${this.qi('ApplicationID')}, ${this.qi('RoleID')}, ${this.qi('CanAccess')}, ${this.qi('CanAdmin')}) VALUES
3439
- ('${appId}', '${role.ID}', ${roleDef.CanAccess ? 1 : 0}, ${roleDef.CanAdmin ? 1 : 0})`;
3439
+ ('${appId}', '${role.ID}', ${this.boolLit(roleDef.CanAccess)}, ${this.boolLit(roleDef.CanAdmin)})`;
3440
3440
  await this.LogSQLAndExecute(pool, sSQLInsert, `Adding role ${roleDef.RoleName} to application ${appName}`);
3441
3441
  }
3442
3442
  else {
@@ -3484,7 +3484,7 @@ export class ManageMetadataBase {
3484
3484
  const newAppID = await this.createNewApplication(pool, appUUID, schemaName, schemaName, currentUser);
3485
3485
  if (newAppID) {
3486
3486
  apps = [newAppID];
3487
- const md = new Metadata();
3487
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
3488
3488
  await md.Refresh();
3489
3489
  }
3490
3490
  else {
@@ -3513,14 +3513,14 @@ export class ManageMetadataBase {
3513
3513
  if (!configInfo.newEntityDefaults.PermissionDefaults?.AutoAddPermissionsForNewEntities) {
3514
3514
  return;
3515
3515
  }
3516
- const md = new Metadata();
3516
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
3517
3517
  const permissions = configInfo.newEntityDefaults.PermissionDefaults.Permissions;
3518
3518
  for (const p of permissions) {
3519
3519
  const RoleID = md.Roles.find(r => r.Name.trim().toLowerCase() === p.RoleName.trim().toLowerCase())?.ID;
3520
3520
  if (RoleID) {
3521
3521
  const sSQLInsert = `INSERT INTO ${this.qs(mj_core_schema(), 'EntityPermission')}
3522
3522
  (${this.qi('EntityID')}, ${this.qi('RoleID')}, ${this.qi('CanRead')}, ${this.qi('CanCreate')}, ${this.qi('CanUpdate')}, ${this.qi('CanDelete')}, ${this.qi('__mj_CreatedAt')}, ${this.qi('__mj_UpdatedAt')}) VALUES
3523
- ('${entityId}', '${RoleID}', ${p.CanRead ? 1 : 0}, ${p.CanCreate ? 1 : 0}, ${p.CanUpdate ? 1 : 0}, ${p.CanDelete ? 1 : 0}, ${this.utcNow()}, ${this.utcNow()})`;
3523
+ ('${entityId}', '${RoleID}', ${this.boolLit(p.CanRead)}, ${this.boolLit(p.CanCreate)}, ${this.boolLit(p.CanUpdate)}, ${this.boolLit(p.CanDelete)}, ${this.utcNow()}, ${this.utcNow()})`;
3524
3524
  await this.LogSQLAndExecute(pool, sSQLInsert, `SQL generated to add permission for entity ${entityName} for role ${p.RoleName}`);
3525
3525
  }
3526
3526
  else {
@@ -3566,16 +3566,16 @@ export class ManageMetadataBase {
3566
3566
  '${newEntity.TableName}',
3567
3567
  'vw${generatePluralName(newEntity.TableName, { capitalizeFirstLetterOnly: true }) + (newEntitySuffix && newEntitySuffix.length > 0 ? newEntitySuffix : '')}',
3568
3568
  '${newEntity.SchemaName}',
3569
- 1,
3570
- ${newEntityDefaults.AllowUserSearchAPI === undefined ? 1 : newEntityDefaults.AllowUserSearchAPI ? 1 : 0},
3571
- ${allowCaching ? 1 : 0}
3572
- ${newEntityDefaults.TrackRecordChanges === undefined ? '' : ', ' + (newEntityDefaults.TrackRecordChanges ? '1' : '0')}
3573
- ${newEntityDefaults.AuditRecordAccess === undefined ? '' : ', ' + (newEntityDefaults.AuditRecordAccess ? '1' : '0')}
3574
- ${newEntityDefaults.AuditViewRuns === undefined ? '' : ', ' + (newEntityDefaults.AuditViewRuns ? '1' : '0')}
3575
- ${newEntityDefaults.AllowAllRowsAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowAllRowsAPI ? '1' : '0')}
3576
- ${newEntityDefaults.AllowCreateAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowCreateAPI ? '1' : '0')}
3577
- ${newEntityDefaults.AllowUpdateAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowUpdateAPI ? '1' : '0')}
3578
- ${newEntityDefaults.AllowDeleteAPI === undefined ? '' : ', ' + (newEntityDefaults.AllowDeleteAPI ? '1' : '0')}
3569
+ ${this.boolLit(true)},
3570
+ ${newEntityDefaults.AllowUserSearchAPI === undefined ? this.boolLit(true) : this.boolLit(newEntityDefaults.AllowUserSearchAPI)},
3571
+ ${this.boolLit(allowCaching)}
3572
+ ${newEntityDefaults.TrackRecordChanges === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.TrackRecordChanges)}
3573
+ ${newEntityDefaults.AuditRecordAccess === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AuditRecordAccess)}
3574
+ ${newEntityDefaults.AuditViewRuns === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AuditViewRuns)}
3575
+ ${newEntityDefaults.AllowAllRowsAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowAllRowsAPI)}
3576
+ ${newEntityDefaults.AllowCreateAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowCreateAPI)}
3577
+ ${newEntityDefaults.AllowUpdateAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowUpdateAPI)}
3578
+ ${newEntityDefaults.AllowDeleteAPI === undefined ? '' : ', ' + this.boolLit(newEntityDefaults.AllowDeleteAPI)}
3579
3579
  ${newEntityDefaults.UserViewMaxRows === undefined ? '' : ', ' + (newEntityDefaults.UserViewMaxRows)}
3580
3580
  , ${this.utcNow()}
3581
3581
  , ${this.utcNow()}
@@ -3620,7 +3620,7 @@ export class ManageMetadataBase {
3620
3620
  if (configInfo.forceRegeneration?.enabled) {
3621
3621
  // Force regeneration mode - process all entities (or filtered by entityWhereClause)
3622
3622
  logStatus(` Force regeneration enabled - processing all entities...`);
3623
- whereClause = 'e.VirtualEntity = 0';
3623
+ whereClause = `e.VirtualEntity = ${this.boolLit(false)}`;
3624
3624
  if (configInfo.forceRegeneration.entityWhereClause && configInfo.forceRegeneration.entityWhereClause.trim().length > 0) {
3625
3625
  whereClause += ` AND (${configInfo.forceRegeneration.entityWhereClause})`;
3626
3626
  logStatus(` Filtered by: ${configInfo.forceRegeneration.entityWhereClause}`);
@@ -3640,7 +3640,7 @@ export class ManageMetadataBase {
3640
3640
  return true;
3641
3641
  }
3642
3642
  logStatus(` Advanced Generation enabled, processing ${entitiesToProcess.length} entities...`);
3643
- whereClause = `e.VirtualEntity = 0 AND e.Name IN (${entitiesToProcess.map(name => `'${name}'`).join(',')}) AND e.SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
3643
+ whereClause = `e.VirtualEntity = ${this.boolLit(false)} AND e.Name IN (${entitiesToProcess.map(name => `'${name}'`).join(',')}) AND e.SchemaName NOT IN (${excludeSchemas.map(s => `'${s}'`).join(',')})`;
3644
3644
  }
3645
3645
  // Get entity details for entities that need processing
3646
3646
  const entitiesSQL = `
@@ -3697,7 +3697,7 @@ export class ManageMetadataBase {
3697
3697
  ef.AutoUpdateUserSearchPredicate,
3698
3698
  ef.FullTextSearchEnabled,
3699
3699
  ef.AutoUpdateFullTextSearch,
3700
- ef.Length as MaxLength
3700
+ ef.${this.qi('Length')} as MaxLength
3701
3701
  FROM
3702
3702
  ${this.qs(mj_core_schema(), 'vwEntityFields')} ef
3703
3703
  WHERE
@@ -3850,7 +3850,7 @@ export class ManageMetadataBase {
3850
3850
  return {};
3851
3851
  }
3852
3852
  // Walk the IS-A chain using in-memory metadata
3853
- const md = new Metadata();
3853
+ const md = new Metadata(); // global-provider-ok: codegen runs offline against a single provider
3854
3854
  const allEntities = md.Entities;
3855
3855
  const parentChain = [];
3856
3856
  const visited = new Set();
@@ -3932,9 +3932,9 @@ export class ManageMetadataBase {
3932
3932
  if (nameField && nameField.AutoUpdateIsNameField && nameField.ID && !nameField.IsNameField) {
3933
3933
  sqlStatements.push(`
3934
3934
  UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
3935
- SET IsNameField = 1
3935
+ SET IsNameField = ${this.boolLit(true)}
3936
3936
  WHERE ID = '${nameField.ID}'
3937
- AND AutoUpdateIsNameField = 1
3937
+ AND AutoUpdateIsNameField = ${this.boolLit(true)}
3938
3938
  `);
3939
3939
  }
3940
3940
  else if (!nameField) {
@@ -3955,9 +3955,9 @@ export class ManageMetadataBase {
3955
3955
  if (!field.DefaultInView) {
3956
3956
  sqlStatements.push(`
3957
3957
  UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
3958
- SET DefaultInView = 1
3958
+ SET DefaultInView = ${this.boolLit(true)}
3959
3959
  WHERE ID = '${field.ID}'
3960
- AND AutoUpdateDefaultInView = 1
3960
+ AND AutoUpdateDefaultInView = ${this.boolLit(true)}
3961
3961
  `);
3962
3962
  }
3963
3963
  }
@@ -3978,9 +3978,9 @@ export class ManageMetadataBase {
3978
3978
  if (!field.IncludeInUserSearchAPI) {
3979
3979
  sqlStatements.push(`
3980
3980
  UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
3981
- SET IncludeInUserSearchAPI = 1
3981
+ SET IncludeInUserSearchAPI = ${this.boolLit(true)}
3982
3982
  WHERE ID = '${field.ID}'
3983
- AND AutoUpdateIncludeInUserSearchAPI = 1
3983
+ AND AutoUpdateIncludeInUserSearchAPI = ${this.boolLit(true)}
3984
3984
  `);
3985
3985
  }
3986
3986
  }
@@ -4007,7 +4007,7 @@ export class ManageMetadataBase {
4007
4007
  UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
4008
4008
  SET UserSearchPredicateAPI = '${sp.predicate}'
4009
4009
  WHERE ID = '${field.ID}'
4010
- AND AutoUpdateUserSearchPredicate = 1
4010
+ AND AutoUpdateUserSearchPredicate = ${this.boolLit(true)}
4011
4011
  `);
4012
4012
  }
4013
4013
  }
@@ -4019,14 +4019,14 @@ export class ManageMetadataBase {
4019
4019
  if (result.allowUserSearch == null || !entity.AutoUpdateAllowUserSearchAPI) {
4020
4020
  return;
4021
4021
  }
4022
- const newValue = result.allowUserSearch ? 1 : 0;
4023
- const currentValue = entity.AllowUserSearchAPI ? 1 : 0;
4022
+ const newValue = result.allowUserSearch;
4023
+ const currentValue = !!entity.AllowUserSearchAPI;
4024
4024
  if (newValue !== currentValue) {
4025
4025
  sqlStatements.push(`
4026
4026
  UPDATE ${this.qs(mj_core_schema(), 'Entity')}
4027
- SET AllowUserSearchAPI = ${newValue}
4027
+ SET AllowUserSearchAPI = ${this.boolLit(newValue)}
4028
4028
  WHERE ID = '${entity.ID}'
4029
- AND AutoUpdateAllowUserSearchAPI = 1
4029
+ AND AutoUpdateAllowUserSearchAPI = ${this.boolLit(true)}
4030
4030
  `);
4031
4031
  }
4032
4032
  }
@@ -4036,14 +4036,14 @@ export class ManageMetadataBase {
4036
4036
  applyFullTextSearchUpdates(sqlStatements, entity, fields, result) {
4037
4037
  // Entity-level FullTextSearchEnabled
4038
4038
  if (result.enableFullTextSearch != null && entity.AutoUpdateFullTextSearch) {
4039
- const newValue = result.enableFullTextSearch ? 1 : 0;
4040
- const currentValue = entity.FullTextSearchEnabled ? 1 : 0;
4039
+ const newValue = result.enableFullTextSearch;
4040
+ const currentValue = !!entity.FullTextSearchEnabled;
4041
4041
  if (newValue !== currentValue) {
4042
4042
  sqlStatements.push(`
4043
4043
  UPDATE ${this.qs(mj_core_schema(), 'Entity')}
4044
- SET FullTextSearchEnabled = ${newValue}
4044
+ SET FullTextSearchEnabled = ${this.boolLit(newValue)}
4045
4045
  WHERE ID = '${entity.ID}'
4046
- AND AutoUpdateFullTextSearch = 1
4046
+ AND AutoUpdateFullTextSearch = ${this.boolLit(true)}
4047
4047
  `);
4048
4048
  }
4049
4049
  }
@@ -4063,9 +4063,9 @@ export class ManageMetadataBase {
4063
4063
  if (!field.FullTextSearchEnabled) {
4064
4064
  sqlStatements.push(`
4065
4065
  UPDATE ${this.qs(mj_core_schema(), 'EntityField')}
4066
- SET FullTextSearchEnabled = 1
4066
+ SET FullTextSearchEnabled = ${this.boolLit(true)}
4067
4067
  WHERE ID = '${field.ID}'
4068
- AND AutoUpdateFullTextSearch = 1
4068
+ AND AutoUpdateFullTextSearch = ${this.boolLit(true)}
4069
4069
  `);
4070
4070
  }
4071
4071
  }
@@ -4135,9 +4135,9 @@ export class ManageMetadataBase {
4135
4135
  if (shouldSupportGeo !== currentValue) {
4136
4136
  await this.LogSQLAndExecute(pool, `
4137
4137
  UPDATE ${this.qs(schema, 'Entity')}
4138
- SET ${this.qi('SupportsGeoCoding')} = ${shouldSupportGeo ? 1 : 0}
4139
- WHERE ${this.qi('ID')} = '${entity.ID}' AND ${this.qi('AutoUpdateSupportsGeoCoding')} = 1
4140
- `, `Set SupportsGeoCoding = ${shouldSupportGeo ? 1 : 0} for ${entity.Name}`);
4138
+ SET ${this.qi('SupportsGeoCoding')} = ${this.boolLit(shouldSupportGeo)}
4139
+ WHERE ${this.qi('ID')} = '${entity.ID}' AND ${this.qi('AutoUpdateSupportsGeoCoding')} = ${this.boolLit(true)}
4140
+ `, `Set SupportsGeoCoding = ${shouldSupportGeo} for ${entity.Name}`);
4141
4141
  logStatus(` Entity ${entity.Name}: SupportsGeoCoding = ${shouldSupportGeo ? 1 : 0} (auto-detected from ${hasGeoFields ? 'LLM' : 'existing'} geo fields)`);
4142
4142
  // Queue for late-phase view regeneration — the view was already generated
4143
4143
  // before this flag was set, so it needs to be regenerated with the geo JOIN
@@ -4229,7 +4229,7 @@ export class ManageMetadataBase {
4229
4229
  SET
4230
4230
  ${setClauses.join(',\n ')}
4231
4231
  WHERE
4232
- ID = '${field.ID}' AND AutoUpdateCategory = 1`);
4232
+ ID = '${field.ID}' AND AutoUpdateCategory = ${this.boolLit(true)}`);
4233
4233
  }
4234
4234
  }
4235
4235
  else if (!field) {
@@ -4346,14 +4346,13 @@ WHERE
4346
4346
  * Only called for NEW entities to set DefaultForNewUser.
4347
4347
  */
4348
4348
  async applyEntityImportance(pool, entityId, importance) {
4349
- const defaultForNewUser = importance.defaultForNewUser ? 1 : 0;
4350
4349
  const updateSQL = `
4351
4350
  UPDATE ${this.qs(mj_core_schema(), 'ApplicationEntity')}
4352
- SET DefaultForNewUser = ${defaultForNewUser}, __mj_UpdatedAt = ${this.utcNow()}
4351
+ SET DefaultForNewUser = ${this.boolLit(importance.defaultForNewUser)}, __mj_UpdatedAt = ${this.utcNow()}
4353
4352
  WHERE EntityID = '${entityId}'
4354
4353
  `;
4355
4354
  try {
4356
- await this.LogSQLAndExecute(pool, updateSQL, `Set DefaultForNewUser=${defaultForNewUser} for NEW entity (category: ${importance.entityCategory}, confidence: ${importance.confidence})`, false);
4355
+ await this.LogSQLAndExecute(pool, updateSQL, `Set DefaultForNewUser=${importance.defaultForNewUser} for NEW entity (category: ${importance.entityCategory}, confidence: ${importance.confidence})`, false);
4357
4356
  logStatus(` Entity importance (NEW Entity): ${importance.entityCategory} (defaultForNewUser: ${importance.defaultForNewUser}, confidence: ${importance.confidence})`);
4358
4357
  logStatus(` Reasoning: ${importance.reasoning}`);
4359
4358
  }