Member Junction
    Preparing search index...

    Function applyPlatformDependentEnvVars

    • Apply PG_-prefixed env-var precedence after the user's mj.config.cjs has been merged into the config. Closes a gap left by resolveConnEnv: that helper is locked to _IS_PG_DEFAULT (env-only), so a user who sets dbPlatform: 'postgresql' in mj.config.cjs (no DB_PLATFORM env var) but supplies the host via PG_HOST would have PG_HOST silently ignored and connect to localhost. The pre-refactor code used process.env.PG_HOST ?? configInfo.dbHost unconditionally inside setupPostgreSQLDataSource(), so PG always won — this helper restores that behavior at the config layer.

      Mutates config in place. PG_* env vars only override fields the user did NOT explicitly set in mj.config.cjs (passed via userConfig); explicit user values always win. A console.warn records the precedence whenever a PG_* env var and its DB_* counterpart are both set and differ.

      Parameters

      • config: {
            additionalSchemaInfo?: string;
            advancedGeneration?:
                | {
                    allowFullTextSearchAutoUpdate: boolean;
                    batchSize: number;
                    enableAdvancedGeneration: boolean;
                    features: {
                        description?: string
                        | null;
                        enabled: boolean;
                        name: string;
                        options?: { name: string; value?: unknown }[] | null;
                        systemPrompt?: string | null;
                        userMessage?: string | null;
                    }[];
                }
                | null;
            codeGenLogin: string;
            codeGenPassword: string;
            codegenPool?: {
                connectionTimeoutMillis?: number;
                idleTimeoutMillis?: number;
                max?: number;
                min?: number;
                ssl?: boolean
                | Record<string, unknown>;
                statementTimeoutMs?: number;
            };
            commands: {
                args: string[];
                command: string;
                timeout?: number
                | null;
                when: string;
                workingDirectory: string;
            }[];
            customSQLScripts: { scriptFile: string; when: string }[];
            dbDatabase: string;
            dbHost: string;
            dbInstanceName?: string | null;
            dbPlatform: "sqlserver" | "postgresql";
            dbPort: number;
            dbRequestTimeout?: number;
            dbSchemaJSONOutput: {
                bundles: {
                    excludeEntities: string[];
                    excludeSchemas: string[];
                    name: string;
                    schemas: string[];
                }[];
                excludeEntities: string[];
                excludeSchemas: string[];
            };
            dbTrustServerCertificate: "Y"
            | "N";
            entityNaming: {
                additionalDomainWords: string[];
                normalizeAllCaps: boolean;
                normalizeFieldNames: boolean;
                splitCompoundWords: boolean;
            };
            entityPackageName: string
            | Record<string, string>;
            excludeSchemas: string[];
            excludeTables: { schema: string; table: string }[];
            forceRegeneration: {
                allStoredProcedures: boolean;
                baseViews: boolean;
                enabled: boolean;
                entityWhereClause?: string;
                fullTextSearch: boolean;
                indexes: boolean;
                spCreate: boolean;
                spDelete: boolean;
                spUpdate: boolean;
            };
            graphqlPort: number;
            integrityChecks: { enabled: boolean; entityFieldsSequenceCheck: boolean };
            logging: { console: boolean; log: boolean; logFile: string };
            metadataInsertBatchSize: number;
            mjCoreSchema: string;
            newEntityDefaults: {
                AddToApplicationWithSchemaName: boolean;
                AllowAllRowsAPI: boolean;
                AllowCaching: boolean;
                AllowCachingBySchema: { AllowCaching: boolean; SchemaName: string }[];
                AllowCreateAPI: boolean;
                AllowDeleteAPI: boolean;
                AllowUpdateAPI: boolean;
                AllowUserSearchAPI: boolean;
                AuditRecordAccess: boolean;
                AuditViewRuns: boolean;
                CascadeDeletes: boolean;
                IncludeFirstNFieldsAsDefaultInView: number;
                NameRulesBySchema: {
                    EntityNamePrefix: string;
                    EntityNameSuffix: string;
                    SchemaName: string;
                }[];
                PermissionDefaults: {
                    AutoAddPermissionsForNewEntities: boolean;
                    Permissions: {
                        CanCreate: boolean;
                        CanDelete: boolean;
                        CanRead: boolean;
                        CanUpdate: boolean;
                        RoleName: string;
                    }[];
                };
                TrackRecordChanges: boolean;
                UserViewMaxRows: number;
            };
            newEntityRelationshipDefaults: {
                AutomaticallyCreateRelationships: boolean;
                CreateOneToManyRelationships: boolean;
            };
            newSchemaDefaults: {
                ApplicationRoleDefaults: {
                    AutoAddRolesForNewApplications: boolean;
                    Roles: { CanAccess: boolean; CanAdmin: boolean; RoleName: string }[];
                };
                CreateNewApplicationWithSchemaName: boolean;
            };
            newUserSetup?: | {
                CreateUserApplicationRecords: boolean;
                Email: string;
                FirstName: string;
                LastName: string;
                Roles: string[];
                UserApplications: string[];
                UserName: string;
            }
            | null;
            output: {
                appendOutputCode?: boolean;
                directory: string;
                options?: { name: string; value?: any }[];
                type: string;
            }[];
            outputCode?: string
            | null;
            settings: { name: string; value?: any }[];
            SQLOutput: {
                appendToFile: boolean;
                convertCoreSchemaToFlywayMigrationFile: boolean;
                enabled: boolean;
                fileName?: string;
                folderPath: string;
                omitRecurringScriptsFromLog: boolean;
                schemaPlaceholders?: { placeholder: string; schema: string }[];
            };
            startup?: { mode?: "full"
            | "task" };
            verboseOutput: boolean;
        }
        • OptionaladditionalSchemaInfo?: string

          Path to JSON file containing soft PK/FK definitions for tables without database constraints

        • OptionaladvancedGeneration?:
              | {
                  allowFullTextSearchAutoUpdate: boolean;
                  batchSize: number;
                  enableAdvancedGeneration: boolean;
                  features: {
                      description?: string
                      | null;
                      enabled: boolean;
                      name: string;
                      options?: { name: string; value?: unknown }[] | null;
                      systemPrompt?: string | null;
                      userMessage?: string | null;
                  }[];
              }
              | null
        • codeGenLogin: string
        • codeGenPassword: string
        • OptionalcodegenPool?: {
              connectionTimeoutMillis?: number;
              idleTimeoutMillis?: number;
              max?: number;
              min?: number;
              ssl?: boolean | Record<string, unknown>;
              statementTimeoutMs?: number;
          }

          Optional CodeGen-time database connection pool configuration.

          Per-provider applicability — not all fields apply to both providers today:

          Field SQL Server PostgreSQL
          statementTimeoutMs ✅ mssql requestTimeout ✅ libpq -c statement_timeout
          max / min / idleTimeoutMillis / connectionTimeoutMillis ❌ ignored pg.Pool config
          ssl ❌ ignored (SQL Server uses dbTrustServerCertificate + mssql's own SSL) pg.Pool ssl

          The PG-only pool-sizing knobs reflect the asymmetry between mssql and pg.Pool configurability today; they'll converge in a follow-up. When omitted, each driver's own defaults apply (mssql: 10 max; PGConnectionManager: 20 max, 2 min).

          For runtime (MJAPI) pool settings, see @memberjunction/server's databaseSettings.connectionPool — that is a separate, long-lived service pool and is independent of CodeGen.

          • OptionalconnectionTimeoutMillis?: number

            PostgreSQL only today. New-connection acquisition timeout in ms.

          • OptionalidleTimeoutMillis?: number

            PostgreSQL only today. Idle timeout in ms before a pooled connection is closed.

          • Optionalmax?: number

            PostgreSQL only today. Max pool connections; pg.Pool default 20 when unset.

          • Optionalmin?: number

            PostgreSQL only today. Min idle connections kept open; pg.Pool default 2.

          • Optionalssl?: boolean | Record<string, unknown>

            PostgreSQL only. SSL configuration for the codegen pool. Defaults to false (matches the pre-multi-provider-refactor inline pg.Pool behavior that ran codegen plaintext locally). Set to true for managed PostgreSQL with default trust (e.g. AWS Aurora rds.force_ssl=1); pass an object for full control (e.g. { rejectUnauthorized: true, ca: <CA bundle> }).

            Note: the runtime MJAPI pool (databaseSettings.connectionPool) has its own SSL handling that defaults ON in NODE_ENV=production — this field only governs the short-lived codegen pool.

          • OptionalstatementTimeoutMs?: number

            Per-statement timeout in milliseconds, applied to both providers:

            • SQL Server: mapped to mssql's requestTimeout on the pool config. Takes precedence over the legacy top-level dbRequestTimeout when both are set; falls back to dbRequestTimeout (and ultimately mssql's 120000ms default) when unset.
            • PostgreSQL: applied via the libpq startup option -c statement_timeout=<ms> (carried in pg's connection startup packet), so every backend — including the verify-SELECT-1 connection — honors it from the very first query. When unset, PostgreSQL applies no statement timeout (its default).
        • commands: {
              args: string[];
              command: string;
              timeout?: number | null;
              when: string;
              workingDirectory: string;
          }[]
        • customSQLScripts: { scriptFile: string; when: string }[]
        • dbDatabase: string
        • dbHost: string
        • OptionaldbInstanceName?: string | null
        • dbPlatform: "sqlserver" | "postgresql"

          Database platform: 'sqlserver' or 'postgresql'.

        • dbPort: number
        • OptionaldbRequestTimeout?: number

          Legacy — SQL Server request timeout in milliseconds applied to the CodeGen connection pool. Set in mj.config.cjs or via the MJ_CODEGEN_REQUEST_TIMEOUT environment variable when long-running CodeGen steps (e.g. spUpdateExistingEntityFieldsFromSchema) exceed the default of 120000 (2 minutes).

          Prefer the cross-platform codegenPool.statementTimeoutMs for new configs — it applies to both SQL Server (as requestTimeout) and PostgreSQL (as the per-connection statement_timeout GUC). When both are set on a SQL Server install, codegenPool.statementTimeoutMs wins; dbRequestTimeout remains as a backward-compatible fallback so existing configs keep working unchanged.

        • dbSchemaJSONOutput: {
              bundles: {
                  excludeEntities: string[];
                  excludeSchemas: string[];
                  name: string;
                  schemas: string[];
              }[];
              excludeEntities: string[];
              excludeSchemas: string[];
          }
        • dbTrustServerCertificate: "Y" | "N"
        • entityNaming: {
              additionalDomainWords: string[];
              normalizeAllCaps: boolean;
              normalizeFieldNames: boolean;
              splitCompoundWords: boolean;
          }

          Entity and field name normalization settings for ALL CAPS database identifiers

          • additionalDomainWords: string[]

            Additional domain-specific words for the compound word splitter

          • normalizeAllCaps: boolean

            Normalize ALL CAPS table/entity names to Title Case (e.g., PAYMENT -> Payment). Default: true

          • normalizeFieldNames: boolean

            Normalize ALL CAPS column/field names the same way. Default: true

          • splitCompoundWords: boolean

            Split compound ALL CAPS words using dictionary matching (e.g., INDIVIDUALDESIGNATION -> Individual Designation). Default: true

        • entityPackageName: string | Record<string, string>
        • excludeSchemas: string[]
        • excludeTables: { schema: string; table: string }[]
        • forceRegeneration: {
              allStoredProcedures: boolean;
              baseViews: boolean;
              enabled: boolean;
              entityWhereClause?: string;
              fullTextSearch: boolean;
              indexes: boolean;
              spCreate: boolean;
              spDelete: boolean;
              spUpdate: boolean;
          }
          • allStoredProcedures: boolean

            Force regeneration of all stored procedures

          • baseViews: boolean

            Force regeneration of base views

          • enabled: boolean

            Force regeneration of all SQL objects even if no schema changes are detected

          • OptionalentityWhereClause?: string

            Optional SQL WHERE clause to filter entities for forced regeneration Example: "SchemaName = 'dbo' AND Name LIKE 'User%'"

          • fullTextSearch: boolean

            Force regeneration of full text search components

          • indexes: boolean

            Force regeneration of indexes for foreign keys

          • spCreate: boolean

            Force regeneration of spCreate procedures

          • spDelete: boolean

            Force regeneration of spDelete procedures

          • spUpdate: boolean

            Force regeneration of spUpdate procedures

        • graphqlPort: number
        • integrityChecks: { enabled: boolean; entityFieldsSequenceCheck: boolean }
        • logging: { console: boolean; log: boolean; logFile: string }
          • console: boolean

            Whether to also log to console

          • log: boolean

            Whether logging is enabled

          • logFile: string

            File path for log output

        • metadataInsertBatchSize: number

          Number of metadata INSERT statements CodeGen joins into a single batched round-trip when syncing newly-discovered entity fields into the metadata tables (createNewEntityFieldsFromSchema). Each row's INSERT SQL is unchanged and conflict-guarded; this knob only controls how many are terminated, joined, and sent — plus logged to the migration file — per DB round-trip.

          Larger values mean fewer round-trips but a larger SQL string per batch; smaller values trade throughput for smaller batches. These are independent statements (not a multi-row VALUES), so no SQL Server row/parameter limit bounds the value. Defaults to 250, a good balance on large-schema installs (thousands of tables). Applies to both SQL Server and PostgreSQL.

        • mjCoreSchema: string
        • newEntityDefaults: {
              AddToApplicationWithSchemaName: boolean;
              AllowAllRowsAPI: boolean;
              AllowCaching: boolean;
              AllowCachingBySchema: { AllowCaching: boolean; SchemaName: string }[];
              AllowCreateAPI: boolean;
              AllowDeleteAPI: boolean;
              AllowUpdateAPI: boolean;
              AllowUserSearchAPI: boolean;
              AuditRecordAccess: boolean;
              AuditViewRuns: boolean;
              CascadeDeletes: boolean;
              IncludeFirstNFieldsAsDefaultInView: number;
              NameRulesBySchema: {
                  EntityNamePrefix: string;
                  EntityNameSuffix: string;
                  SchemaName: string;
              }[];
              PermissionDefaults: {
                  AutoAddPermissionsForNewEntities: boolean;
                  Permissions: {
                      CanCreate: boolean;
                      CanDelete: boolean;
                      CanRead: boolean;
                      CanUpdate: boolean;
                      RoleName: string;
                  }[];
              };
              TrackRecordChanges: boolean;
              UserViewMaxRows: number;
          }
          • AddToApplicationWithSchemaName: boolean
          • AllowAllRowsAPI: boolean
          • AllowCaching: boolean
          • AllowCachingBySchema: { AllowCaching: boolean; SchemaName: string }[]

            Per-schema overrides for the AllowCaching default. When CodeGen creates a new Entity row, the schema is matched (case-insensitive) against this list and the matching entry's AllowCaching value wins over the global AllowCaching default. Schema names support the ${mj_core_schema} placeholder. Defaults to enabling caching for the MJ core schema.

          • AllowCreateAPI: boolean
          • AllowDeleteAPI: boolean
          • AllowUpdateAPI: boolean
          • AllowUserSearchAPI: boolean
          • AuditRecordAccess: boolean
          • AuditViewRuns: boolean
          • CascadeDeletes: boolean
          • IncludeFirstNFieldsAsDefaultInView: number
          • NameRulesBySchema: { EntityNamePrefix: string; EntityNameSuffix: string; SchemaName: string }[]
          • PermissionDefaults: {
                AutoAddPermissionsForNewEntities: boolean;
                Permissions: {
                    CanCreate: boolean;
                    CanDelete: boolean;
                    CanRead: boolean;
                    CanUpdate: boolean;
                    RoleName: string;
                }[];
            }
          • TrackRecordChanges: boolean
          • UserViewMaxRows: number
        • newEntityRelationshipDefaults: {
              AutomaticallyCreateRelationships: boolean;
              CreateOneToManyRelationships: boolean;
          }
        • newSchemaDefaults: {
              ApplicationRoleDefaults: {
                  AutoAddRolesForNewApplications: boolean;
                  Roles: { CanAccess: boolean; CanAdmin: boolean; RoleName: string }[];
              };
              CreateNewApplicationWithSchemaName: boolean;
          }
        • OptionalnewUserSetup?:
              | {
                  CreateUserApplicationRecords: boolean;
                  Email: string;
                  FirstName: string;
                  LastName: string;
                  Roles: string[];
                  UserApplications: string[];
                  UserName: string;
              }
              | null
        • output: {
              appendOutputCode?: boolean;
              directory: string;
              options?: { name: string; value?: any }[];
              type: string;
          }[]
        • OptionaloutputCode?: string | null
        • settings: { name: string; value?: any }[]
        • SQLOutput: {
              appendToFile: boolean;
              convertCoreSchemaToFlywayMigrationFile: boolean;
              enabled: boolean;
              fileName?: string;
              folderPath: string;
              omitRecurringScriptsFromLog: boolean;
              schemaPlaceholders?: { placeholder: string; schema: string }[];
          }
          • appendToFile: boolean

            If set to true, then we append to the existing file, if one exists, otherwise we create a new file.

          • convertCoreSchemaToFlywayMigrationFile: boolean

            If true, all mention of the core schema within the log file will be replaced with the flyway schema, ${flyway:defaultSchema}

          • enabled: boolean

            Whether or not sql statements generated while managing metadata should be written to a file

          • OptionalfileName?: string

            Optional, the file name that will be written WITHIN the folderPath specified.

          • folderPath: string

            The path of the folder to use when logging is enabled. If provided, a file will be created with the format "CodeGen_Run_yyyy-mm-dd_hh-mm-ss.sql"

          • omitRecurringScriptsFromLog: boolean

            If true, scripts that are being emitted via SQL logging that are marked by CodeGen as recurring will be SKIPPED. Defaults to false

          • OptionalschemaPlaceholders?: { placeholder: string; schema: string }[]

            Optional array of schema-to-placeholder mappings for Flyway migrations. Each mapping specifies a database schema name and its corresponding Flyway placeholder. If not provided, defaults to replacing the MJ core schema with ${flyway:defaultSchema}.

            Example: [ { schema: '__mj', placeholder: '${mjSchema}' }, { schema: '__BCSaaS', placeholder: '${flyway:defaultSchema}' } ]

        • Optionalstartup?: { mode?: "full" | "task" }

          Startup mode for engine pre-warm during CodeGen's provider bootstrap: 'full' pre-warms all

          engines; 'task' (CodeGen's entry-point default) skips pre-warm — engines lazy-load on first touch. Because mj.config.cjs is shared by every process in a repo, the MJ_STARTUP_MODE env var overrides this per invocation (highest precedence).

        • verboseOutput: boolean
      • userConfig: Partial<ConfigInfo>

      Returns void