Member Junction
    Preparing search index...

    Main entry point for the MemberJunction CodeGen Library.

    This package provides comprehensive code generation capabilities for the MemberJunction platform, including:

    Configuration Management:

    • Configuration file parsing and validation
    • Database connection management

    Database Operations:

    • Schema introspection and metadata management
    • SQL script generation (views, procedures, indexes)
    • Database schema JSON export

    Code Generation:

    • TypeScript entity classes with Zod validation
    • Angular components and forms
    • GraphQL resolvers and schemas
    • Action subclasses for business logic

    Utilities:

    • Status logging and error handling
    • Command execution
    • System integrity checks
    import { RunCodeGenBase, initializeConfig } from '@memberjunction/codegen-lib';

    // Initialize configuration
    const config = initializeConfig(process.cwd());

    // Run code generation
    const codeGen = new RunCodeGenBase();
    await codeGen.Run();
    • Initializes configuration from the specified working directory

      Parameters

      • cwd: string

        The current working directory to search for config files

      Returns {
          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;
          allowCrossSchemaCascadeDeletes: boolean;
          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";
          entityImportPackages?: Record<string, string>;
          entityNaming: {
              additionalDomainWords: string[];
              normalizeAllCaps: boolean;
              normalizeFieldNames: boolean;
              splitCompoundWords: boolean;
          };
          entityPackageName: string
          | Record<string, string>;
          excludeSchemas: string[];
          excludeTables: ExcludeTableEntry[];
          fileEmit: {
              concurrency: number;
              dirtySchemaOnly: boolean;
              parallel: boolean;
              perSchema: boolean;
              sqlEntityBatchSize: number;
              writeIfChanged: boolean;
          };
          forceRegeneration: {
              allStoredProcedures: boolean;
              baseViews: boolean;
              enabled: boolean;
              entityWhereClause?: string;
              fullTextSearch: boolean;
              indexes: boolean;
              spCreate: boolean;
              spDelete: boolean;
              spUpdate: boolean;
          };
          graphqlPort: number;
          includeSchemas?: string[];
          integrityChecks: { enabled: boolean; entityFieldsSequenceCheck: boolean };
          logging: { console: boolean; log: boolean; logFile: string };
          metadataDirectory?: 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;
          schemaOutput?: {
              Angular?: string;
              EntitySubClasses?: string;
              GraphQLServer?: string;
              schema: string;
              skip?: ("EntitySubClasses" | "GraphQLServer" | "Angular" | "SQL")[];
          }[];
          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;
      }

      Parsed configuration object

      • 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
      • allowCrossSchemaCascadeDeletes: boolean

        When true, CodeGen cascade-delete SQL walks FKs pointing at the entity in EVERY schema in metadata. Default false: only same-schema children. Turning this on (and CascadeDeletes on an entity) will bake consumer schemas into a publisher's delete proc — a dangerous escape hatch. Leave off for Open Apps.

      • 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"
      • OptionalentityImportPackages?: Record<string, string>

        Schema → npm package map for peer entity classes this emit does not generate (cross-schema embedded records and related-record collections).

        This is a different knob from entityPackageName and includeSchemas:

        • includeSchemas — what this run generates
        • string entityPackageName — the npm package this run writes those classes into
        • Record entityPackageName — install-time host map; those schemas are also skipped for local generation (getExternalEntitySchemas). Do not overload it on an Open App under development: listing a sibling schema there would skip generating this app if you also listed your own schema, and converting a custom string entityPackageName into a Record silently re-routes every unmapped schema.
        • entityImportPackages — where to import { PeerEntity } from when the peer's schema is not in this file

        Publishers (Open Apps under development) use string entityPackageName + includeSchemas and must list sibling app schemas here. Hosts that already use Record entityPackageName do not need this — that map is the fallback after this one. Case-insensitive schema keys. Mapping a foreign schema to this emit's own package is an error (that would self-import a class this file does not emit).

        resolveEntityImportPackage

      • 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: ExcludeTableEntry[]
      • fileEmit: {
            concurrency: number;
            dirtySchemaOnly: boolean;
            parallel: boolean;
            perSchema: boolean;
            sqlEntityBatchSize: number;
            writeIfChanged: boolean;
        }

        File-emit behaviour for entity subclasses and GraphQL resolvers. Schema is the incremental unit — see guides/CODEGEN_LARGE_SCHEMA_GUIDE.md.

        • concurrency: number

          Max schemas assembled at once when parallel is true. Default 8.

        • dirtySchemaOnly: boolean

          Rebuild only schemas that contain a new/modified entity (plus any schema whose file is missing). --skipdb file-only runs ignore this and rebuild every schema, still gated by write-if-changed. Default true.

        • parallel: boolean

          Assemble independent schema files in parallel. Default true.

        • perSchema: boolean

          Emit one TypeScript file per schema plus a barrel. Default true.

        • sqlEntityBatchSize: number

          SQL Server per-entity SQL generation width. PostgreSQL stays serial (1) regardless — catalog deadlocks under parallel phased DDL. Default 8.

        • writeIfChanged: boolean

          Skip the disk write when generated bytes are identical. Default true.

      • 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
      • OptionalincludeSchemas?: string[]

        Opt-in POSITIVE scope list. When set (non-empty), CodeGen processes ONLY these schemas — every other schema present in the DATABASE is treated as excluded, including schemas MJ has never seen before. It is pure sugar over excludeSchemas: it is resolved into excludeSchemas (see applyIncludeSchemaScope) before metadata management and again before file generation, so nothing downstream changes. In-scope ⇔ named in includeSchemas AND not in excludeSchemas (include shrinks the addressable space; exclude overlays on top). No hidden auto-includes — a schema, including the MJ core schema, is in scope ONLY if listed explicitly. Leave undefined/empty for the classic exclude-only behavior (unchanged).

        Primary use: scope an Open App's CodeGen to just its own schema without hand-maintaining an exclude list naming every other installed app — a list that is O(N²) to maintain and, more importantly, cannot name schemas the app does not know about (such as a client's own schemas in a deployed instance).

        The in-memory compile into excludeSchemas is for THIS CodeGen run only (which entities to generate). Heal stored-procedure EXEC statements logged into migrations use authored excludeSchemas plus @IncludedSchemaNames from this list — they must not snapshot sibling apps that happened to be installed on the publisher database.

      • 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

      • OptionalmetadataDirectory?: string

        Root directory containing metadata files for sync (e.g. './metadata')

      • 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
      • OptionalschemaOutput?: {
            Angular?: string;
            EntitySubClasses?: string;
            GraphQLServer?: string;
            schema: string;
            skip?: ("EntitySubClasses" | "GraphQLServer" | "Angular" | "SQL")[];
        }[]

        Route (or skip) generated artifacts for matching schemas to a directory other than the default output.* entry. First match wins.

      • 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 true

        • 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

      Error if no configuration is found