@memberjunction/codegen-lib 3.4.0 → 4.1.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 (94) hide show
  1. package/README.md +828 -630
  2. package/dist/Angular/angular-codegen.d.ts +10 -3
  3. package/dist/Angular/angular-codegen.d.ts.map +1 -1
  4. package/dist/Angular/angular-codegen.js +164 -199
  5. package/dist/Angular/angular-codegen.js.map +1 -1
  6. package/dist/Angular/entity-data-grid-related-entity-component.d.ts +1 -1
  7. package/dist/Angular/entity-data-grid-related-entity-component.d.ts.map +1 -1
  8. package/dist/Angular/entity-data-grid-related-entity-component.js +8 -10
  9. package/dist/Angular/entity-data-grid-related-entity-component.js.map +1 -1
  10. package/dist/Angular/join-grid-related-entity-component.d.ts +1 -1
  11. package/dist/Angular/join-grid-related-entity-component.js +8 -36
  12. package/dist/Angular/join-grid-related-entity-component.js.map +1 -1
  13. package/dist/Angular/related-entity-components.js +13 -79
  14. package/dist/Angular/related-entity-components.js.map +1 -1
  15. package/dist/Angular/timeline-related-entity-component.d.ts +1 -1
  16. package/dist/Angular/timeline-related-entity-component.js +14 -38
  17. package/dist/Angular/timeline-related-entity-component.js.map +1 -1
  18. package/dist/Config/config.d.ts.map +1 -1
  19. package/dist/Config/config.js +171 -177
  20. package/dist/Config/config.js.map +1 -1
  21. package/dist/Config/db-connection.d.ts +1 -1
  22. package/dist/Config/db-connection.d.ts.map +1 -1
  23. package/dist/Config/db-connection.js +6 -33
  24. package/dist/Config/db-connection.js.map +1 -1
  25. package/dist/Database/dbSchema.js +28 -35
  26. package/dist/Database/dbSchema.js.map +1 -1
  27. package/dist/Database/manage-metadata.d.ts +302 -6
  28. package/dist/Database/manage-metadata.d.ts.map +1 -1
  29. package/dist/Database/manage-metadata.js +1294 -445
  30. package/dist/Database/manage-metadata.js.map +1 -1
  31. package/dist/Database/reorder-columns.d.ts +1 -1
  32. package/dist/Database/reorder-columns.d.ts.map +1 -1
  33. package/dist/Database/reorder-columns.js +1 -5
  34. package/dist/Database/reorder-columns.js.map +1 -1
  35. package/dist/Database/sql.d.ts +1 -1
  36. package/dist/Database/sql.d.ts.map +1 -1
  37. package/dist/Database/sql.js +67 -98
  38. package/dist/Database/sql.js.map +1 -1
  39. package/dist/Database/sql_codegen.d.ts +15 -2
  40. package/dist/Database/sql_codegen.d.ts.map +1 -1
  41. package/dist/Database/sql_codegen.js +282 -253
  42. package/dist/Database/sql_codegen.js.map +1 -1
  43. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts +11 -0
  44. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts.map +1 -1
  45. package/dist/Manifest/GenerateClassRegistrationsManifest.js +43 -41
  46. package/dist/Manifest/GenerateClassRegistrationsManifest.js.map +1 -1
  47. package/dist/Misc/action_subclasses_codegen.d.ts.map +1 -1
  48. package/dist/Misc/action_subclasses_codegen.js +15 -26
  49. package/dist/Misc/action_subclasses_codegen.js.map +1 -1
  50. package/dist/Misc/advanced_generation.d.ts +69 -7
  51. package/dist/Misc/advanced_generation.d.ts.map +1 -1
  52. package/dist/Misc/advanced_generation.js +114 -75
  53. package/dist/Misc/advanced_generation.js.map +1 -1
  54. package/dist/Misc/createNewUser.d.ts +1 -1
  55. package/dist/Misc/createNewUser.js +22 -26
  56. package/dist/Misc/createNewUser.js.map +1 -1
  57. package/dist/Misc/entity_subclasses_codegen.d.ts +7 -2
  58. package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
  59. package/dist/Misc/entity_subclasses_codegen.js +56 -45
  60. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  61. package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
  62. package/dist/Misc/graphql_server_codegen.js +39 -42
  63. package/dist/Misc/graphql_server_codegen.js.map +1 -1
  64. package/dist/Misc/runCommand.d.ts +1 -1
  65. package/dist/Misc/runCommand.js +13 -20
  66. package/dist/Misc/runCommand.js.map +1 -1
  67. package/dist/Misc/sql_logging.d.ts +1 -1
  68. package/dist/Misc/sql_logging.d.ts.map +1 -1
  69. package/dist/Misc/sql_logging.js +21 -51
  70. package/dist/Misc/sql_logging.js.map +1 -1
  71. package/dist/Misc/status_logging.js +45 -60
  72. package/dist/Misc/status_logging.js.map +1 -1
  73. package/dist/Misc/system_integrity.d.ts +1 -1
  74. package/dist/Misc/system_integrity.d.ts.map +1 -1
  75. package/dist/Misc/system_integrity.js +12 -16
  76. package/dist/Misc/system_integrity.js.map +1 -1
  77. package/dist/Misc/temp_batch_file.js +15 -22
  78. package/dist/Misc/temp_batch_file.js.map +1 -1
  79. package/dist/Misc/util.d.ts.map +1 -1
  80. package/dist/Misc/util.js +17 -28
  81. package/dist/Misc/util.js.map +1 -1
  82. package/dist/__tests__/metadataConfig.test.d.ts +12 -0
  83. package/dist/__tests__/metadataConfig.test.d.ts.map +1 -0
  84. package/dist/__tests__/metadataConfig.test.js +604 -0
  85. package/dist/__tests__/metadataConfig.test.js.map +1 -0
  86. package/dist/index.d.ts +21 -21
  87. package/dist/index.d.ts.map +1 -1
  88. package/dist/index.js +21 -41
  89. package/dist/index.js.map +1 -1
  90. package/dist/runCodeGen.d.ts +1 -0
  91. package/dist/runCodeGen.d.ts.map +1 -1
  92. package/dist/runCodeGen.js +150 -178
  93. package/dist/runCodeGen.js.map +1 -1
  94. package/package.json +29 -23
@@ -1,123 +1,117 @@
1
- "use strict";
2
1
  /**
3
2
  * Configuration management module for MemberJunction CodeGen.
4
3
  * Handles loading, parsing, and validation of configuration files using Zod schemas.
5
4
  * Supports various configuration sources through cosmiconfig (package.json, .mjrc, etc.).
6
5
  */
7
- var __importDefault = (this && this.__importDefault) || function (mod) {
8
- return (mod && mod.__esModule) ? mod : { "default": mod };
9
- };
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.mj_core_schema = exports.MAX_INDEX_NAME_LENGTH = exports.autoIndexForeignKeys = exports.getSettingValue = exports.getSetting = exports.customSqlScripts = exports.commands = exports.outputOptionValue = exports.outputOptions = exports.outputDir = exports.initializeConfig = exports.dbDatabase = exports.mjCoreSchema = exports.configInfo = exports.currentWorkingDirectory = exports.DEFAULT_CODEGEN_CONFIG = void 0;
12
- const zod_1 = require("zod");
13
- const cosmiconfig_1 = require("cosmiconfig");
14
- const path_1 = __importDefault(require("path"));
15
- const status_logging_1 = require("../Misc/status_logging");
16
- const config_1 = require("@memberjunction/config");
6
+ import { z } from 'zod';
7
+ import { cosmiconfigSync } from 'cosmiconfig';
8
+ import path from 'path';
9
+ import { logStatus } from '../Misc/status_logging.js';
10
+ import { mergeConfigs, parseBooleanEnv } from '@memberjunction/config';
17
11
  /** Global configuration explorer for finding MJ config files */
18
- const explorer = (0, cosmiconfig_1.cosmiconfigSync)('mj', { searchStrategy: 'global' });
12
+ const explorer = cosmiconfigSync('mj', { searchStrategy: 'global' });
19
13
  /** Initial config search result from current working directory */
20
14
  const configSearchResult = explorer.search(process.cwd());
21
- const settingInfoSchema = zod_1.z.object({
15
+ const settingInfoSchema = z.object({
22
16
  /** The name/key of the setting */
23
- name: zod_1.z.string(),
17
+ name: z.string(),
24
18
  /** The value of the setting (can be any type) */
25
- value: zod_1.z.any(),
19
+ value: z.any(),
26
20
  });
27
- const logInfoSchema = zod_1.z.object({
21
+ const logInfoSchema = z.object({
28
22
  /** Whether logging is enabled */
29
- log: zod_1.z.boolean().default(true),
23
+ log: z.boolean().default(true),
30
24
  /** File path for log output */
31
- logFile: zod_1.z.string().default('codegen.output.log'),
25
+ logFile: z.string().default('codegen.output.log'),
32
26
  /** Whether to also log to console */
33
- console: zod_1.z.boolean().default(true),
27
+ console: z.boolean().default(true),
34
28
  });
35
- const customSQLScriptSchema = zod_1.z.object({
29
+ const customSQLScriptSchema = z.object({
36
30
  /** When to run the script (e.g., 'before-all', 'after-all') */
37
- when: zod_1.z.string(),
31
+ when: z.string(),
38
32
  /** Path to the SQL script file */
39
- scriptFile: zod_1.z.string(),
33
+ scriptFile: z.string(),
40
34
  });
41
- const commandInfoSchema = zod_1.z.object({
35
+ const commandInfoSchema = z.object({
42
36
  /** Working directory to run the command from */
43
- workingDirectory: zod_1.z.string(),
37
+ workingDirectory: z.string(),
44
38
  /** The command to execute */
45
- command: zod_1.z.string(),
39
+ command: z.string(),
46
40
  /** Command line arguments */
47
- args: zod_1.z.string().array(),
41
+ args: z.string().array(),
48
42
  /** Optional timeout in milliseconds */
49
- timeout: zod_1.z.number().nullish(),
43
+ timeout: z.number().nullish(),
50
44
  /** When to run the command (e.g., 'before', 'after') */
51
- when: zod_1.z.string(),
45
+ when: z.string(),
52
46
  });
53
- const outputOptionInfoSchema = zod_1.z.object({
47
+ const outputOptionInfoSchema = z.object({
54
48
  /** Name of the output option */
55
- name: zod_1.z.string(),
49
+ name: z.string(),
56
50
  /** Value of the output option */
57
- value: zod_1.z.any(),
51
+ value: z.any(),
58
52
  });
59
- const outputInfoSchema = zod_1.z.object({
53
+ const outputInfoSchema = z.object({
60
54
  /** Type of output (e.g., 'SQL', 'Angular', 'GraphQLServer') */
61
- type: zod_1.z.string(),
55
+ type: z.string(),
62
56
  /** Directory path for output files */
63
- directory: zod_1.z.string(),
57
+ directory: z.string(),
64
58
  /** Whether to append additional output code subdirectory */
65
- appendOutputCode: zod_1.z.boolean().optional(),
59
+ appendOutputCode: z.boolean().optional(),
66
60
  /** Additional options for this output type */
67
61
  options: outputOptionInfoSchema.array().optional(),
68
62
  });
69
- const tableInfoSchema = zod_1.z.object({
63
+ const tableInfoSchema = z.object({
70
64
  /** Schema name (supports wildcards like '%') */
71
- schema: zod_1.z.string(),
65
+ schema: z.string(),
72
66
  /** Table name (supports wildcards like 'sys%') */
73
- table: zod_1.z.string(),
67
+ table: z.string(),
74
68
  });
75
- const dbSchemaJSONOutputBundleSchema = zod_1.z.object({
69
+ const dbSchemaJSONOutputBundleSchema = z.object({
76
70
  /** Name of the bundle */
77
- name: zod_1.z.string(),
71
+ name: z.string(),
78
72
  /** Schemas to include in this bundle */
79
- schemas: zod_1.z.string().array().default([]),
73
+ schemas: z.string().array().default([]),
80
74
  /** Schemas to exclude from this bundle */
81
- excludeSchemas: zod_1.z.string().array().default(['sys', 'staging']),
75
+ excludeSchemas: z.string().array().default(['sys', 'staging']),
82
76
  /** Entities to exclude from this bundle */
83
- excludeEntities: zod_1.z.string().array().default([]),
77
+ excludeEntities: z.string().array().default([]),
84
78
  });
85
- const dbSchemaJSONOutputSchema = zod_1.z.object({
86
- excludeEntities: zod_1.z.string().array(),
87
- excludeSchemas: zod_1.z.string().array().default(['sys', 'staging', 'dbo']),
79
+ const dbSchemaJSONOutputSchema = z.object({
80
+ excludeEntities: z.string().array(),
81
+ excludeSchemas: z.string().array().default(['sys', 'staging', 'dbo']),
88
82
  bundles: dbSchemaJSONOutputBundleSchema.array().default([{ name: '_Core_Apps', excludeSchemas: ['__mj'] }]),
89
83
  });
90
- const newUserSetupSchema = zod_1.z.object({
91
- UserName: zod_1.z.string(),
92
- FirstName: zod_1.z.string(),
93
- LastName: zod_1.z.string(),
94
- Email: zod_1.z.string(),
95
- Roles: zod_1.z.string().array().default(['Developer', 'Integration', 'UI']),
96
- CreateUserApplicationRecords: zod_1.z.boolean().optional().default(false),
97
- UserApplications: zod_1.z.array(zod_1.z.string()).optional().default([]),
84
+ const newUserSetupSchema = z.object({
85
+ UserName: z.string(),
86
+ FirstName: z.string(),
87
+ LastName: z.string(),
88
+ Email: z.string(),
89
+ Roles: z.string().array().default(['Developer', 'Integration', 'UI']),
90
+ CreateUserApplicationRecords: z.boolean().optional().default(false),
91
+ UserApplications: z.array(z.string()).optional().default([]),
98
92
  });
99
- const advancedGenerationFeatureOptionSchema = zod_1.z.object({
93
+ const advancedGenerationFeatureOptionSchema = z.object({
100
94
  /** Name of the option */
101
- name: zod_1.z.string(),
95
+ name: z.string(),
102
96
  /** Value of the option (can be any type) */
103
- value: zod_1.z.unknown(),
97
+ value: z.unknown(),
104
98
  });
105
- const advancedGenerationFeatureSchema = zod_1.z.object({
99
+ const advancedGenerationFeatureSchema = z.object({
106
100
  /** Name of the feature */
107
- name: zod_1.z.string(),
101
+ name: z.string(),
108
102
  /** Whether the feature is enabled */
109
- enabled: zod_1.z.boolean(),
103
+ enabled: z.boolean(),
110
104
  /** Description for documentation (not used by code) */
111
- description: zod_1.z.string().nullish(),
105
+ description: z.string().nullish(),
112
106
  /** System prompt for AI interaction */
113
- systemPrompt: zod_1.z.string().nullish(),
107
+ systemPrompt: z.string().nullish(),
114
108
  /** User message template for AI interaction */
115
- userMessage: zod_1.z.string().nullish(),
109
+ userMessage: z.string().nullish(),
116
110
  /** Additional options for the feature */
117
111
  options: advancedGenerationFeatureOptionSchema.array().nullish(),
118
112
  });
119
- const advancedGenerationSchema = zod_1.z.object({
120
- enableAdvancedGeneration: zod_1.z.boolean().default(true),
113
+ const advancedGenerationSchema = z.object({
114
+ enableAdvancedGeneration: z.boolean().default(true),
121
115
  // NOTE: AIVendor and AIModel have been removed. Model configuration is now per-prompt
122
116
  // in the AI Prompts table via the MJ: AI Prompt Models relationship.
123
117
  features: advancedGenerationFeatureSchema.array().default([
@@ -156,78 +150,83 @@ const advancedGenerationSchema = zod_1.z.object({
156
150
  description: "Use AI to decide which entity relationships should have visible tabs and the best order to display those tabs. All relationships will be generated based on the Database Schema, but the EntityRelationship.DisplayInForm. The idea is that the AI will pick which of these tabs should be visible by default. In some cases an entity will have a large # of relationships and it isn't necessarily a good idea to display all of them. This feature only applies when an entity is created or new Entity Relationships are detected. This tool will not change existing EntityRelationship records.",
157
151
  enabled: false,
158
152
  },
153
+ {
154
+ name: 'VirtualEntityFieldDecoration',
155
+ description: 'Use AI to analyze SQL view definitions for virtual entities and identify primary keys, foreign keys, and field descriptions. Only runs for virtual entities that lack soft PK/FK annotations. Respects explicit config-defined PKs/FKs (from additionalSchemaInfo) — LLM fills in the gaps.',
156
+ enabled: true,
157
+ },
159
158
  ]),
160
159
  });
161
- const integrityCheckConfigSchema = zod_1.z.object({
162
- enabled: zod_1.z.boolean(),
163
- entityFieldsSequenceCheck: zod_1.z.boolean(),
160
+ const integrityCheckConfigSchema = z.object({
161
+ enabled: z.boolean(),
162
+ entityFieldsSequenceCheck: z.boolean(),
164
163
  });
165
- const forceRegenerationConfigSchema = zod_1.z.object({
164
+ const forceRegenerationConfigSchema = z.object({
166
165
  /**
167
166
  * Force regeneration of all SQL objects even if no schema changes are detected
168
167
  */
169
- enabled: zod_1.z.boolean().default(false),
168
+ enabled: z.boolean().default(false),
170
169
  /**
171
170
  * Optional SQL WHERE clause to filter entities for forced regeneration
172
171
  * Example: "SchemaName = 'dbo' AND Name LIKE 'User%'"
173
172
  */
174
- entityWhereClause: zod_1.z.string().optional(),
173
+ entityWhereClause: z.string().optional(),
175
174
  /**
176
175
  * Force regeneration of base views
177
176
  */
178
- baseViews: zod_1.z.boolean().default(false),
177
+ baseViews: z.boolean().default(false),
179
178
  /**
180
179
  * Force regeneration of spCreate procedures
181
180
  */
182
- spCreate: zod_1.z.boolean().default(false),
181
+ spCreate: z.boolean().default(false),
183
182
  /**
184
183
  * Force regeneration of spUpdate procedures
185
184
  */
186
- spUpdate: zod_1.z.boolean().default(false),
185
+ spUpdate: z.boolean().default(false),
187
186
  /**
188
187
  * Force regeneration of spDelete procedures
189
188
  */
190
- spDelete: zod_1.z.boolean().default(false),
189
+ spDelete: z.boolean().default(false),
191
190
  /**
192
191
  * Force regeneration of all stored procedures
193
192
  */
194
- allStoredProcedures: zod_1.z.boolean().default(false),
193
+ allStoredProcedures: z.boolean().default(false),
195
194
  /**
196
195
  * Force regeneration of indexes for foreign keys
197
196
  */
198
- indexes: zod_1.z.boolean().default(false),
197
+ indexes: z.boolean().default(false),
199
198
  /**
200
199
  * Force regeneration of full text search components
201
200
  */
202
- fullTextSearch: zod_1.z.boolean().default(false),
201
+ fullTextSearch: z.boolean().default(false),
203
202
  });
204
- const sqlOutputConfigSchema = zod_1.z.object({
203
+ const sqlOutputConfigSchema = z.object({
205
204
  /**
206
205
  * Whether or not sql statements generated while managing metadata should be written to a file
207
206
  */
208
- enabled: zod_1.z.boolean().default(true),
207
+ enabled: z.boolean().default(true),
209
208
  /**
210
209
  * The path of the folder to use when logging is enabled.
211
210
  * If provided, a file will be created with the format "CodeGen_Run_yyyy-mm-dd_hh-mm-ss.sql"
212
211
  */
213
- folderPath: zod_1.z.string().default('../../migrations/v3/'),
212
+ folderPath: z.string().default('../../migrations/v3/'),
214
213
  /**
215
214
  * Optional, the file name that will be written WITHIN the folderPath specified.
216
215
  */
217
- fileName: zod_1.z.string().optional(),
216
+ fileName: z.string().optional(),
218
217
  /**
219
218
  * If set to true, then we append to the existing file, if one exists, otherwise we create a new file.
220
219
  */
221
- appendToFile: zod_1.z.boolean().default(true),
220
+ appendToFile: z.boolean().default(true),
222
221
  /**
223
222
  * If true, all mention of the core schema within the log file will be replaced with the flyway schema,
224
223
  * ${flyway:defaultSchema}
225
224
  */
226
- convertCoreSchemaToFlywayMigrationFile: zod_1.z.boolean().default(true),
225
+ convertCoreSchemaToFlywayMigrationFile: z.boolean().default(true),
227
226
  /**
228
227
  * If true, scripts that are being emitted via SQL logging that are marked by CodeGen as recurring will be SKIPPED. Defaults to false
229
228
  */
230
- omitRecurringScriptsFromLog: zod_1.z.boolean().default(false),
229
+ omitRecurringScriptsFromLog: z.boolean().default(false),
231
230
  /**
232
231
  * Optional array of schema-to-placeholder mappings for Flyway migrations.
233
232
  * Each mapping specifies a database schema name and its corresponding Flyway placeholder.
@@ -239,62 +238,62 @@ const sqlOutputConfigSchema = zod_1.z.object({
239
238
  * { schema: '__BCSaaS', placeholder: '${flyway:defaultSchema}' }
240
239
  * ]
241
240
  */
242
- schemaPlaceholders: zod_1.z.array(zod_1.z.object({
243
- schema: zod_1.z.string(),
244
- placeholder: zod_1.z.string()
241
+ schemaPlaceholders: z.array(z.object({
242
+ schema: z.string(),
243
+ placeholder: z.string()
245
244
  })).optional(),
246
245
  });
247
- const newSchemaDefaultsSchema = zod_1.z.object({
248
- CreateNewApplicationWithSchemaName: zod_1.z.boolean().default(true),
246
+ const newSchemaDefaultsSchema = z.object({
247
+ CreateNewApplicationWithSchemaName: z.boolean().default(true),
249
248
  });
250
- const entityPermissionSchema = zod_1.z.object({
251
- RoleName: zod_1.z.string(),
252
- CanRead: zod_1.z.boolean(),
253
- CanCreate: zod_1.z.boolean(),
254
- CanUpdate: zod_1.z.boolean(),
255
- CanDelete: zod_1.z.boolean(),
249
+ const entityPermissionSchema = z.object({
250
+ RoleName: z.string(),
251
+ CanRead: z.boolean(),
252
+ CanCreate: z.boolean(),
253
+ CanUpdate: z.boolean(),
254
+ CanDelete: z.boolean(),
256
255
  });
257
- const newEntityPermissionDefaultsSchema = zod_1.z.object({
258
- AutoAddPermissionsForNewEntities: zod_1.z.boolean().default(true),
256
+ const newEntityPermissionDefaultsSchema = z.object({
257
+ AutoAddPermissionsForNewEntities: z.boolean().default(true),
259
258
  Permissions: entityPermissionSchema.array().default([
260
259
  { RoleName: 'UI', CanRead: true, CanCreate: false, CanUpdate: false, CanDelete: false },
261
260
  { RoleName: 'Developer', CanRead: true, CanCreate: true, CanUpdate: true, CanDelete: false },
262
261
  { RoleName: 'Integration', CanRead: true, CanCreate: true, CanUpdate: true, CanDelete: true },
263
262
  ]),
264
263
  });
265
- const newEntityNameRulesBySchema = zod_1.z.object({
266
- SchemaName: zod_1.z.string(),
267
- EntityNamePrefix: zod_1.z.string().default(''),
268
- EntityNameSuffix: zod_1.z.string().default(''),
264
+ const newEntityNameRulesBySchema = z.object({
265
+ SchemaName: z.string(),
266
+ EntityNamePrefix: z.string().default(''),
267
+ EntityNameSuffix: z.string().default(''),
269
268
  });
270
- const newEntityDefaultsSchema = zod_1.z.object({
271
- TrackRecordChanges: zod_1.z.boolean().default(true),
272
- AuditRecordAccess: zod_1.z.boolean().default(false),
273
- AuditViewRuns: zod_1.z.boolean().default(false),
274
- AllowAllRowsAPI: zod_1.z.boolean().default(false),
275
- AllowCreateAPI: zod_1.z.boolean().default(true),
276
- AllowUpdateAPI: zod_1.z.boolean().default(true),
277
- AllowDeleteAPI: zod_1.z.boolean().default(true),
278
- AllowUserSearchAPI: zod_1.z.boolean().default(true),
279
- CascadeDeletes: zod_1.z.boolean().default(false),
280
- UserViewMaxRows: zod_1.z.number().default(1000),
281
- AddToApplicationWithSchemaName: zod_1.z.boolean().default(true),
282
- IncludeFirstNFieldsAsDefaultInView: zod_1.z.number().default(5),
269
+ const newEntityDefaultsSchema = z.object({
270
+ TrackRecordChanges: z.boolean().default(true),
271
+ AuditRecordAccess: z.boolean().default(false),
272
+ AuditViewRuns: z.boolean().default(false),
273
+ AllowAllRowsAPI: z.boolean().default(false),
274
+ AllowCreateAPI: z.boolean().default(true),
275
+ AllowUpdateAPI: z.boolean().default(true),
276
+ AllowDeleteAPI: z.boolean().default(true),
277
+ AllowUserSearchAPI: z.boolean().default(true),
278
+ CascadeDeletes: z.boolean().default(false),
279
+ UserViewMaxRows: z.number().default(1000),
280
+ AddToApplicationWithSchemaName: z.boolean().default(true),
281
+ IncludeFirstNFieldsAsDefaultInView: z.number().default(5),
283
282
  PermissionDefaults: newEntityPermissionDefaultsSchema,
284
283
  NameRulesBySchema: newEntityNameRulesBySchema.array().default([]),
285
284
  });
286
- const newEntityRelationshipDefaultsSchema = zod_1.z.object({
287
- AutomaticallyCreateRelationships: zod_1.z.boolean().default(true),
288
- CreateOneToManyRelationships: zod_1.z.boolean().default(true),
285
+ const newEntityRelationshipDefaultsSchema = z.object({
286
+ AutomaticallyCreateRelationships: z.boolean().default(true),
287
+ CreateOneToManyRelationships: z.boolean().default(true),
289
288
  });
290
- const configInfoSchema = zod_1.z.object({
289
+ const configInfoSchema = z.object({
291
290
  newUserSetup: newUserSetupSchema.nullish(),
292
291
  settings: settingInfoSchema.array().default([
293
292
  { name: 'mj_core_schema', value: '__mj' },
294
293
  { name: 'skip_database_generation', value: false },
295
294
  { name: 'auto_index_foreign_keys', value: true },
296
295
  ]),
297
- excludeSchemas: zod_1.z.string().array().default(['sys', 'staging']),
296
+ excludeSchemas: z.string().array().default(['sys', 'staging']),
298
297
  excludeTables: tableInfoSchema.array().default([
299
298
  { schema: '%', table: 'sys%' },
300
299
  { schema: '%', table: 'flyway_schema_history' }
@@ -336,7 +335,7 @@ const configInfoSchema = zod_1.z.object({
336
335
  { workingDirectory: '../MJAPI', command: 'npm', args: ['start'], timeout: 30000, when: 'after' },
337
336
  ]),
338
337
  /** Path to JSON file containing soft PK/FK definitions for tables without database constraints */
339
- additionalSchemaInfo: zod_1.z.string().optional(),
338
+ additionalSchemaInfo: z.string().optional(),
340
339
  logging: logInfoSchema,
341
340
  newEntityDefaults: newEntityDefaultsSchema,
342
341
  newSchemaDefaults: newSchemaDefaultsSchema,
@@ -344,21 +343,21 @@ const configInfoSchema = zod_1.z.object({
344
343
  newEntityRelationshipDefaults: newEntityRelationshipDefaultsSchema,
345
344
  SQLOutput: sqlOutputConfigSchema,
346
345
  forceRegeneration: forceRegenerationConfigSchema,
347
- dbHost: zod_1.z.string(),
348
- dbPort: zod_1.z.coerce.number().int().positive().default(1433),
349
- codeGenLogin: zod_1.z.string(),
350
- codeGenPassword: zod_1.z.string(),
351
- dbDatabase: zod_1.z.string(),
352
- dbInstanceName: zod_1.z.string().nullish(),
353
- dbTrustServerCertificate: zod_1.z.coerce
346
+ dbHost: z.string(),
347
+ dbPort: z.coerce.number().int().positive().default(1433),
348
+ codeGenLogin: z.string(),
349
+ codeGenPassword: z.string(),
350
+ dbDatabase: z.string(),
351
+ dbInstanceName: z.string().nullish(),
352
+ dbTrustServerCertificate: z.coerce
354
353
  .boolean()
355
354
  .default(false)
356
355
  .transform((v) => (v ? 'Y' : 'N')),
357
- outputCode: zod_1.z.string().nullish(),
358
- mjCoreSchema: zod_1.z.string().default('__mj'),
359
- graphqlPort: zod_1.z.coerce.number().int().positive().default(4000),
360
- entityPackageName: zod_1.z.string().default('mj_generatedentities'),
361
- verboseOutput: zod_1.z.boolean().optional().default(false),
356
+ outputCode: z.string().nullish(),
357
+ mjCoreSchema: z.string().default('__mj'),
358
+ graphqlPort: z.coerce.number().int().positive().default(4000),
359
+ entityPackageName: z.string().default('mj_generatedentities'),
360
+ verboseOutput: z.boolean().optional().default(false),
362
361
  });
363
362
  /**
364
363
  * Default CodeGen configuration - provides sensible defaults for all CodeGen settings.
@@ -366,7 +365,7 @@ const configInfoSchema = zod_1.z.object({
366
365
  *
367
366
  * Database connection settings come from environment variables.
368
367
  */
369
- exports.DEFAULT_CODEGEN_CONFIG = {
368
+ export const DEFAULT_CODEGEN_CONFIG = {
370
369
  // Database connection settings (from environment variables)
371
370
  dbHost: process.env.DB_HOST ?? 'localhost',
372
371
  dbPort: 1433,
@@ -374,7 +373,7 @@ exports.DEFAULT_CODEGEN_CONFIG = {
374
373
  codeGenLogin: process.env.CODEGEN_DB_USERNAME ?? '',
375
374
  codeGenPassword: process.env.CODEGEN_DB_PASSWORD ?? '',
376
375
  dbInstanceName: process.env.DB_INSTANCE_NAME,
377
- dbTrustServerCertificate: (0, config_1.parseBooleanEnv)(process.env.DB_TRUST_SERVER_CERTIFICATE) ? 'Y' : 'N',
376
+ dbTrustServerCertificate: parseBooleanEnv(process.env.DB_TRUST_SERVER_CERTIFICATE) ? 'Y' : 'N',
378
377
  mjCoreSchema: '__mj',
379
378
  graphqlPort: 4000,
380
379
  verboseOutput: false,
@@ -478,6 +477,11 @@ exports.DEFAULT_CODEGEN_CONFIG = {
478
477
  description: 'Use AI to parse check constraints and generate a description as well as sub-class Validate() methods that reflect the logic of the constraint.',
479
478
  enabled: true,
480
479
  },
480
+ {
481
+ name: 'VirtualEntityFieldDecoration',
482
+ description: 'Use AI to analyze SQL view definitions for virtual entities and identify primary keys, foreign keys, and field descriptions.',
483
+ enabled: true,
484
+ },
481
485
  ],
482
486
  },
483
487
  SQLOutput: {
@@ -501,14 +505,14 @@ exports.DEFAULT_CODEGEN_CONFIG = {
501
505
  /**
502
506
  * Current working directory for the code generation process
503
507
  */
504
- exports.currentWorkingDirectory = process.cwd();
508
+ export let currentWorkingDirectory = process.cwd();
505
509
  /**
506
510
  * Merge user config with DEFAULT_CODEGEN_CONFIG.
507
511
  * Database settings come from user config or environment variables.
508
512
  */
509
513
  const mergedConfig = configSearchResult?.config
510
- ? (0, config_1.mergeConfigs)(exports.DEFAULT_CODEGEN_CONFIG, configSearchResult.config)
511
- : exports.DEFAULT_CODEGEN_CONFIG;
514
+ ? mergeConfigs(DEFAULT_CODEGEN_CONFIG, configSearchResult.config)
515
+ : DEFAULT_CODEGEN_CONFIG;
512
516
  /** Parse and validate the merged configuration */
513
517
  const configParsing = configInfoSchema.safeParse(mergedConfig);
514
518
  // Don't log errors at module load - commands that need config will validate explicitly
@@ -518,67 +522,65 @@ const configParsing = configInfoSchema.safeParse(mergedConfig);
518
522
  /**
519
523
  * Parsed configuration object with fallback to empty object if parsing fails
520
524
  */
521
- exports.configInfo = configParsing.data ?? {};
525
+ export const configInfo = configParsing.data ?? {};
522
526
  /**
523
527
  * Destructured commonly used configuration values
524
528
  */
525
- exports.mjCoreSchema = exports.configInfo.mjCoreSchema, exports.dbDatabase = exports.configInfo.dbDatabase;
529
+ export const { mjCoreSchema, dbDatabase } = configInfo;
526
530
  /**
527
531
  * Initializes configuration from the specified working directory
528
532
  * @param cwd The current working directory to search for config files
529
533
  * @returns Parsed configuration object
530
534
  * @throws Error if no configuration is found
531
535
  */
532
- function initializeConfig(cwd) {
533
- exports.currentWorkingDirectory = cwd;
536
+ export function initializeConfig(cwd) {
537
+ currentWorkingDirectory = cwd;
534
538
  // Merge user config with DEFAULT_CODEGEN_CONFIG
535
- const userConfigResult = explorer.search(exports.currentWorkingDirectory);
539
+ const userConfigResult = explorer.search(currentWorkingDirectory);
536
540
  const mergedConfig = userConfigResult?.config
537
- ? (0, config_1.mergeConfigs)(exports.DEFAULT_CODEGEN_CONFIG, userConfigResult.config)
538
- : exports.DEFAULT_CODEGEN_CONFIG;
541
+ ? mergeConfigs(DEFAULT_CODEGEN_CONFIG, userConfigResult.config)
542
+ : DEFAULT_CODEGEN_CONFIG;
539
543
  const maybeConfig = configInfoSchema.safeParse(mergedConfig);
540
544
  // Don't log errors - let the calling code handle validation failures
541
545
  // if (!maybeConfig.success) {
542
546
  // LogError('Error parsing config file', null, JSON.stringify(maybeConfig.error.issues, null, 2));
543
547
  // }
544
- const config = maybeConfig.success ? maybeConfig.data : exports.configInfo;
548
+ const config = maybeConfig.success ? maybeConfig.data : configInfo;
545
549
  if (config === undefined) {
546
550
  throw new Error('No configuration found');
547
551
  }
548
552
  return config;
549
553
  }
550
- exports.initializeConfig = initializeConfig;
551
554
  /**
552
555
  * Gets the output directory for a specific generation type
553
556
  * @param type The type of output (e.g., 'SQL', 'Angular')
554
557
  * @param useLocalDirectoryIfMissing Whether to use a local directory if config is missing
555
558
  * @returns The output directory path or null if not found
556
559
  */
557
- function outputDir(type, useLocalDirectoryIfMissing) {
558
- const outputInfo = exports.configInfo.output.find((o) => o.type.trim().toUpperCase() === type.trim().toUpperCase());
560
+ export function outputDir(type, useLocalDirectoryIfMissing) {
561
+ const outputInfo = configInfo.output.find((o) => o.type.trim().toUpperCase() === type.trim().toUpperCase());
559
562
  if (outputInfo) {
560
- if (outputInfo.appendOutputCode && outputInfo.appendOutputCode === true && exports.configInfo.outputCode)
561
- return path_1.default.join(exports.currentWorkingDirectory, outputInfo.directory, exports.configInfo.outputCode);
563
+ if (outputInfo.appendOutputCode && outputInfo.appendOutputCode === true && configInfo.outputCode)
564
+ return path.join(currentWorkingDirectory, outputInfo.directory, configInfo.outputCode);
562
565
  else
563
- return path_1.default.join(exports.currentWorkingDirectory, outputInfo.directory);
566
+ return path.join(currentWorkingDirectory, outputInfo.directory);
564
567
  }
565
568
  else {
566
569
  if (useLocalDirectoryIfMissing) {
567
- (0, status_logging_1.logStatus)('>>> No output directory found for type: ' + type + ' within config file, using local directory instead');
568
- return path_1.default.join(exports.currentWorkingDirectory, 'output', type);
570
+ logStatus('>>> No output directory found for type: ' + type + ' within config file, using local directory instead');
571
+ return path.join(currentWorkingDirectory, 'output', type);
569
572
  }
570
573
  else
571
574
  return null;
572
575
  }
573
576
  }
574
- exports.outputDir = outputDir;
575
577
  /**
576
578
  * Gets the output options for a specific generation type
577
579
  * @param type The type of output
578
580
  * @returns Array of output options or null if not found
579
581
  */
580
- function outputOptions(type) {
581
- const outputInfo = exports.configInfo.output.find((o) => o.type.trim().toUpperCase() === type.trim().toUpperCase());
582
+ export function outputOptions(type) {
583
+ const outputInfo = configInfo.output.find((o) => o.type.trim().toUpperCase() === type.trim().toUpperCase());
582
584
  if (outputInfo) {
583
585
  return outputInfo.options;
584
586
  }
@@ -586,7 +588,6 @@ function outputOptions(type) {
586
588
  return null;
587
589
  }
588
590
  }
589
- exports.outputOptions = outputOptions;
590
591
  /**
591
592
  * Gets a specific output option value for a generation type
592
593
  * @param type The type of output
@@ -594,8 +595,8 @@ exports.outputOptions = outputOptions;
594
595
  * @param defaultValue Default value if option is not found
595
596
  * @returns The option value or default value
596
597
  */
597
- function outputOptionValue(type, optionName, defaultValue) {
598
- const outputInfo = exports.configInfo.output?.find((o) => o.type.trim().toUpperCase() === type.trim().toUpperCase());
598
+ export function outputOptionValue(type, optionName, defaultValue) {
599
+ const outputInfo = configInfo.output?.find((o) => o.type.trim().toUpperCase() === type.trim().toUpperCase());
599
600
  if (outputInfo && outputInfo.options) {
600
601
  const theOption = outputInfo.options.find((o) => o.name.trim().toUpperCase() === optionName.trim().toUpperCase());
601
602
  if (theOption)
@@ -607,53 +608,48 @@ function outputOptionValue(type, optionName, defaultValue) {
607
608
  return defaultValue;
608
609
  }
609
610
  }
610
- exports.outputOptionValue = outputOptionValue;
611
611
  /**
612
612
  * Gets commands configured to run at a specific time
613
613
  * @param when When the commands should run (e.g., 'before', 'after')
614
614
  * @returns Array of commands to execute
615
615
  */
616
- function commands(when) {
617
- return exports.configInfo.commands.filter((c) => c.when.trim().toUpperCase() === when.trim().toUpperCase());
616
+ export function commands(when) {
617
+ return configInfo.commands.filter((c) => c.when.trim().toUpperCase() === when.trim().toUpperCase());
618
618
  }
619
- exports.commands = commands;
620
619
  /**
621
620
  * Gets custom SQL scripts configured to run at a specific time
622
621
  * @param when When the scripts should run
623
622
  * @returns Array of SQL scripts to execute
624
623
  */
625
- function customSqlScripts(when) {
626
- return exports.configInfo.customSQLScripts.filter((c) => c.when.trim().toUpperCase() === when.trim().toUpperCase());
624
+ export function customSqlScripts(when) {
625
+ return configInfo.customSQLScripts.filter((c) => c.when.trim().toUpperCase() === when.trim().toUpperCase());
627
626
  }
628
- exports.customSqlScripts = customSqlScripts;
629
627
  /**
630
628
  * Gets a specific setting by name
631
629
  * @param settingName The name of the setting to retrieve
632
630
  * @returns The setting object
633
631
  */
634
- function getSetting(settingName) {
635
- return exports.configInfo.settings.find((s) => s.name.trim().toUpperCase() === settingName.trim().toUpperCase());
632
+ export function getSetting(settingName) {
633
+ return configInfo.settings.find((s) => s.name.trim().toUpperCase() === settingName.trim().toUpperCase());
636
634
  }
637
- exports.getSetting = getSetting;
638
635
  /**
639
636
  * Gets the value of a specific setting
640
637
  * @param settingName The name of the setting
641
638
  * @param defaultValue Default value if setting is not found
642
639
  * @returns The setting value or default value
643
640
  */
644
- function getSettingValue(settingName, defaultValue) {
641
+ export function getSettingValue(settingName, defaultValue) {
645
642
  const setting = getSetting(settingName);
646
643
  if (setting)
647
644
  return setting.value;
648
645
  else
649
646
  return defaultValue;
650
647
  }
651
- exports.getSettingValue = getSettingValue;
652
648
  /**
653
649
  * Checks if automatic indexing of foreign keys is enabled
654
650
  * @returns True if auto-indexing is enabled, false otherwise
655
651
  */
656
- function autoIndexForeignKeys() {
652
+ export function autoIndexForeignKeys() {
657
653
  const keyName = 'auto_index_foreign_keys';
658
654
  const setting = getSetting(keyName);
659
655
  if (setting)
@@ -661,17 +657,15 @@ function autoIndexForeignKeys() {
661
657
  else
662
658
  return false;
663
659
  }
664
- exports.autoIndexForeignKeys = autoIndexForeignKeys;
665
660
  /**
666
661
  * Maximum length allowed for database index names
667
662
  */
668
- exports.MAX_INDEX_NAME_LENGTH = 128;
663
+ export const MAX_INDEX_NAME_LENGTH = 128;
669
664
  /**
670
665
  * Gets the MemberJunction core schema name from configuration
671
666
  * @returns The core schema name (typically '__mj')
672
667
  */
673
- function mj_core_schema() {
668
+ export function mj_core_schema() {
674
669
  return getSetting('mj_core_schema').value;
675
670
  }
676
- exports.mj_core_schema = mj_core_schema;
677
671
  //# sourceMappingURL=config.js.map