@memberjunction/codegen-lib 6.1.0-edge.3 → 6.1.0-edge.4

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 (65) hide show
  1. package/README.md +50 -21
  2. package/dist/Config/config.d.ts +118 -1
  3. package/dist/Config/config.d.ts.map +1 -1
  4. package/dist/Config/config.js +202 -8
  5. package/dist/Config/config.js.map +1 -1
  6. package/dist/Database/__tests__/exclude-schema-permissions.test.d.ts +2 -0
  7. package/dist/Database/__tests__/exclude-schema-permissions.test.d.ts.map +1 -0
  8. package/dist/Database/__tests__/exclude-schema-permissions.test.js +32 -0
  9. package/dist/Database/__tests__/exclude-schema-permissions.test.js.map +1 -0
  10. package/dist/Database/codeGenDatabaseProvider.d.ts +77 -2
  11. package/dist/Database/codeGenDatabaseProvider.d.ts.map +1 -1
  12. package/dist/Database/codeGenDatabaseProvider.js +98 -0
  13. package/dist/Database/codeGenDatabaseProvider.js.map +1 -1
  14. package/dist/Database/heal-schema-params.d.ts +33 -0
  15. package/dist/Database/heal-schema-params.d.ts.map +1 -0
  16. package/dist/Database/heal-schema-params.js +51 -0
  17. package/dist/Database/heal-schema-params.js.map +1 -0
  18. package/dist/Database/manage-metadata.d.ts +9 -0
  19. package/dist/Database/manage-metadata.d.ts.map +1 -1
  20. package/dist/Database/manage-metadata.js +66 -51
  21. package/dist/Database/manage-metadata.js.map +1 -1
  22. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts +25 -35
  23. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts.map +1 -1
  24. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js +97 -51
  25. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js.map +1 -1
  26. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.d.ts +2 -0
  27. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.d.ts.map +1 -0
  28. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.js +110 -0
  29. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.js.map +1 -0
  30. package/dist/Database/providers/postgresql/metadataSupportObjects.js +78 -10
  31. package/dist/Database/providers/postgresql/metadataSupportObjects.js.map +1 -1
  32. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts +12 -0
  33. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts.map +1 -1
  34. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js +28 -0
  35. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js.map +1 -1
  36. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.d.ts +2 -0
  37. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.d.ts.map +1 -0
  38. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.js +195 -0
  39. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.js.map +1 -0
  40. package/dist/Database/schema-filters.d.ts +23 -0
  41. package/dist/Database/schema-filters.d.ts.map +1 -0
  42. package/dist/Database/schema-filters.js +42 -0
  43. package/dist/Database/schema-filters.js.map +1 -0
  44. package/dist/Database/schema-scope.d.ts.map +1 -1
  45. package/dist/Database/schema-scope.js +4 -0
  46. package/dist/Database/schema-scope.js.map +1 -1
  47. package/dist/Database/sql_codegen.d.ts +18 -0
  48. package/dist/Database/sql_codegen.d.ts.map +1 -1
  49. package/dist/Database/sql_codegen.js +92 -41
  50. package/dist/Database/sql_codegen.js.map +1 -1
  51. package/dist/EntityNameScanner/EntityNameScanner.d.ts.map +1 -1
  52. package/dist/EntityNameScanner/EntityNameScanner.js +33 -2
  53. package/dist/EntityNameScanner/EntityNameScanner.js.map +1 -1
  54. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts +8 -4
  55. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts.map +1 -1
  56. package/dist/Manifest/GenerateClassRegistrationsManifest.js +63 -20
  57. package/dist/Manifest/GenerateClassRegistrationsManifest.js.map +1 -1
  58. package/dist/Misc/entity_subclasses_codegen.d.ts +22 -5
  59. package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
  60. package/dist/Misc/entity_subclasses_codegen.js +96 -30
  61. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  62. package/dist/Misc/system_integrity.d.ts.map +1 -1
  63. package/dist/Misc/system_integrity.js +5 -0
  64. package/dist/Misc/system_integrity.js.map +1 -1
  65. package/package.json +29 -29
package/README.md CHANGED
@@ -71,7 +71,7 @@ flowchart TD
71
71
  - **Extensible Architecture**: Every generator (`SQLCodeGenBase`, `EntitySubClassGeneratorBase`, `AngularClientGeneratorBase`, etc.) can be subclassed and overridden via MJ's class factory
72
72
  - **Zod Validation Schemas**: Generates Zod schemas from SQL CHECK constraints with proper union types and refinements
73
73
  - **Recursive Foreign Key & Hierarchy Traversal Engine**: Automatically detects self-referential foreign keys and generates a 4-routine TVF suite (`GetHierarchyMeta`, `GetDescendants`, `GetAncestors`, `GetRootID`), 5 computed base-view columns (`Root<Field>`, `<Field>Depth`, `<Field>Path`, `<Field>IsLeaf`, `<Field>ChildCount`), and strongly typed TypeScript entity traversal methods (`GetDescendants()`, `GetAncestors()`, `GetChildren()`). See the [Recursive Foreign Keys & Hierarchy Traversal Guide](../../guides/RECURSIVE_FOREIGN_KEYS_AND_HIERARCHIES_GUIDE.md).
74
- - **Cascade Delete Generation**: Produces cursor-based cascade delete procedures that call child entity stored procedures, respecting business logic at every level
74
+ - **Cascade Delete Generation**: Produces cursor-based cascade delete procedures that call child entity stored procedures, respecting business logic at every level. Default is **intra-schema only**; `allowCrossSchemaCascadeDeletes` (off) is required to walk FKs in other schemas.
75
75
  - **Force Regeneration**: Surgically regenerate specific SQL objects for specific entities without requiring schema changes
76
76
  - **Class Registration Manifests**: Prevents tree-shaking of `@RegisterClass`-decorated classes by generating static import manifests
77
77
  - **SQL Migration Logging**: Outputs all generated SQL as Flyway-compatible migration files with schema placeholder support
@@ -317,10 +317,40 @@ All configuration is validated at startup using Zod schemas, with clear error me
317
317
  | `SQLOutput` | Controls Flyway migration file generation from SQL logging |
318
318
  | `commands` | Shell commands to run before/after generation (typically package builds) |
319
319
  | `excludeSchemas` / `excludeTables` | Filter schemas and tables from metadata discovery |
320
+ | `includeSchemas` | Opt-in positive scope: generate only these schemas (resolved into `excludeSchemas` **for this run**). Heal SQL logged into migrations uses `@IncludedSchemaNames` from this list plus authored `excludeSchemas` — never a snapshot of sibling apps on the publisher DB. |
321
+ | `allowCrossSchemaCascadeDeletes` | Default **false**. Cascade-delete SQL is intra-schema only. `true` restores the old walk of every FK pointing at the entity, including other Open Apps. Dangerous; leave off. |
322
+ | `entityPackageName` | String: npm package this emit writes. Record: install-time host map (those schemas are also skipped for local generation) |
323
+ | `entityImportPackages` | Schema → npm map for peer classes this emit does **not** generate (embeds + related-record collections). See below. |
320
324
  | `entityNaming` | Controls ALL CAPS normalization and compound word splitting for entity/field names |
321
325
  | `additionalSchemaInfo` | Path to JSON file with soft PK/FK definitions and schema prefix rules |
322
326
  | `dbPlatform` | Database backend selector. See **Database Platform Selection** below. |
323
327
 
328
+ ### Peer entity imports (`entityImportPackages`)
329
+
330
+ Embedded records and related-record collections type the generated subclass against the **related** entity class (`DeclareEmbeddedRecord<AddressEntity>`, `DeclareRelatedRecords<PersonEntity>`). When that class is not emitted in the current file, CodeGen must `import` it from the npm package that owns it.
331
+
332
+ Those are three different knobs. Do not overload `entityPackageName`:
333
+
334
+ | Knob | Meaning |
335
+ |------|---------|
336
+ | `includeSchemas` | What this run **generates** |
337
+ | string `entityPackageName` | The npm package this run **writes** those classes into |
338
+ | Record `entityPackageName` | Install-time **host** map. Listed schemas are also skipped for local generation (`getExternalEntitySchemas`). Converting a publisher's string `entityPackageName` into this Record silently re-routes every unmapped schema. |
339
+ | `entityImportPackages` | Schema → npm map for peers this run does **not** generate |
340
+
341
+ Open App **publishers** (the repo that develops the app) use the string form plus `includeSchemas`, and must list sibling apps here:
342
+
343
+ ```javascript
344
+ entityPackageName: '@mj-biz-apps/orders-entities',
345
+ includeSchemas: ['__mj_BizAppsOrders'],
346
+ entityImportPackages: {
347
+ '__mj_BizAppsCommon': '@mj-biz-apps/common-entities',
348
+ '__mj_BizAppsAccounting': '@mj-biz-apps/accounting-entities',
349
+ },
350
+ ```
351
+
352
+ Resolution: core schema (`__mj`) → `@memberjunction/core-entities`; same schema as the owning entity → this emit's package; then `entityImportPackages`; then Record `entityPackageName` (host fallback). An unmapped foreign schema **throws** — CodeGen will not self-import this emit's package (that was the Orders `import { mjBizAppsCommonAddressEntity } from '@mj-biz-apps/orders-entities'` bug). Mapping a foreign schema to this emit's own package is also an error. Imports are grouped: one `import { A, B } from 'pkg'` line per package.
353
+
324
354
  ### Database Platform Selection (`dbPlatform`)
325
355
 
326
356
  CodeGenLib accepts a single canonical `dbPlatform` field with two values:
@@ -692,27 +722,21 @@ FROM [orders].[vwOrderHeadersGenerated] g;
692
722
  `RunView`, visible in Explorer — and is returned by `spCreate`/`spUpdate`/`spDelete`, because those
693
723
  select from `BaseView`.
694
724
 
695
- ### SQL Server only
696
-
697
- **Layering is rejected on PostgreSQL.** CodeGen throws when it encounters an entity with
698
- `GeneratedBaseViewName` set on a PG install, naming the entity and both views.
725
+ ### PostgreSQL — restar the outer view; ship it via pg-migrate
699
726
 
700
- The reason is that PG cannot deliver the feature's whole point. Everything above depends on the
701
- outer view's `SELECT g.*` being re-resolved after the inner view regenerates — that is what makes a
702
- late-added foreign key appear on its own. SQL Server does that with `sp_refreshview`. PostgreSQL
703
- expands `*` into a fixed column list at creation and freezes it, has no refresh equivalent, and
704
- CodeGen does not own the outer view, so nothing recreates it.
727
+ The outer view is still **custom SQL**. A build engineer ships the PostgreSQL equivalent through
728
+ pg-migrate (same `SELECT g.*, extras FROM inner g` shape, with `||` / `LEFT JOIN LATERAL` instead of
729
+ T-SQL). CodeGen never overwrites that outer SQL.
705
730
 
706
- The resulting behaviour would not even be consistently broken. Adding a column — the common case —
707
- leaves the outer view stale, because `CREATE OR REPLACE` on the inner view never touches dependents.
708
- Renaming a column or changing its type raises `42P16`, which sends CodeGen down its
709
- capture/`DROP CASCADE`/replay path; that incidentally recreates the outer view, which then *does*
710
- pick the new columns up. Same feature, opposite outcomes, decided by which kind of schema change
711
- happened to land that day. Since silent staleness is the exact failure layering exists to eliminate,
712
- PG refuses it outright rather than shipping a documented footgun.
731
+ PostgreSQL expands `g.*` at `CREATE VIEW` and freezes the column list, and it has no
732
+ `sp_refreshview`. After CodeGen rewrites the inner view it **restars** the outer definition — rewrites
733
+ the deparsed `SELECT g.col1, g.col2, …, extras` back to `SELECT g.*, extras` — then
734
+ `CREATE OR REPLACE` (or, when a new inner column lands in the middle of `g.*` and PostgreSQL raises
735
+ `42P16`, capture / `DROP CASCADE` / recreate / replay dependent functions). Open App `mj migrate`
736
+ calls `spRebindLayeredOuterViewsInSchema` for the same rebind.
713
737
 
714
- On PostgreSQL, use a fully custom base view (`BaseViewGenerated = 0`, `GeneratedBaseViewName` left
715
- `NULL`) and accept that it must be hand-maintained as the schema changes.
738
+ Do not leave the outer as a one-time pg-migrate artifact and hope later inner regenerations show up.
739
+ Without the restar they will not.
716
740
 
717
741
  ### Setting it up
718
742
 
@@ -721,8 +745,10 @@ On PostgreSQL, use a fully custom base view (`BaseViewGenerated = 0`, `Generated
721
745
  `metadata/entities/.layered-base-views.json`.
722
746
  2. Run CodeGen. It writes the inner view.
723
747
  3. Create your `BaseView` in a migration that runs **after** CodeGen output, since it selects from the
724
- inner view — and may reference generated root-ID functions.
725
- 4. Run CodeGen again so the new columns are discovered as `EntityField` rows.
748
+ inner view — and may reference generated root-ID functions. On PostgreSQL, ship the same wrapper
749
+ via pg-migrate (`LEFT JOIN LATERAL` / `||` instead of `OUTER APPLY` / `CONVERT`).
750
+ 4. Run CodeGen again so the new columns are discovered as `EntityField` rows. On PostgreSQL this
751
+ pass restars the outer view so `g.*` includes anything the inner view gained.
726
752
 
727
753
  > ### ⚠️ Adopting layering on an EXISTING entity needs `forceRegeneration`
728
754
  >
@@ -991,6 +1017,9 @@ Generates an import manifest that prevents tree-shaking of `@RegisterClass` deco
991
1017
  | `outputDir(type, fallback)` | Get the configured output directory for a generator type |
992
1018
  | `getSettingValue(name, default)` | Get a named setting value from configuration |
993
1019
  | `mj_core_schema()` | Get the MJ core schema name (typically `__mj`) |
1020
+ | `resolveEntityPackageName(schema)` | Package for a schema from `entityPackageName` (string form returns that string for every schema) |
1021
+ | `resolveEntityImportPackage(related, owning)` | Package to **import** a peer class from; throws if a foreign schema is unmapped |
1022
+ | `thisEmitEntityPackageName(owning)` | The npm package this CodeGen run writes |
994
1023
 
995
1024
  ## Dependencies
996
1025
 
@@ -966,8 +966,21 @@ declare const configInfoSchema: z.ZodObject<{
966
966
  * exclude list naming every other installed app — a list that is O(N²) to maintain and, more
967
967
  * importantly, cannot name schemas the app does not know about (such as a client's own schemas in
968
968
  * a deployed instance).
969
+ *
970
+ * The in-memory compile into `excludeSchemas` is for THIS CodeGen run only (which entities to
971
+ * generate). Heal stored-procedure EXEC statements logged into migrations use authored
972
+ * `excludeSchemas` plus `@IncludedSchemaNames` from this list — they must not snapshot sibling
973
+ * apps that happened to be installed on the publisher database.
969
974
  */
970
975
  includeSchemas: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
976
+ /**
977
+ * When true, CodeGen cascade-delete SQL walks FKs pointing at the entity in
978
+ * EVERY schema in metadata. Default false: only same-schema children.
979
+ * Turning this on (and CascadeDeletes on an entity) will bake consumer
980
+ * schemas into a publisher's delete proc — a dangerous escape hatch.
981
+ * Leave off for Open Apps.
982
+ */
983
+ allowCrossSchemaCascadeDeletes: z.ZodDefault<z.ZodBoolean>;
971
984
  excludeTables: z.ZodDefault<z.ZodArray<z.ZodObject<{
972
985
  /** Schema name (supports wildcards like '%') */
973
986
  schema: z.ZodString;
@@ -1685,6 +1698,31 @@ declare const configInfoSchema: z.ZodObject<{
1685
1698
  mjCoreSchema: z.ZodDefault<z.ZodString>;
1686
1699
  graphqlPort: z.ZodDefault<z.ZodNumber>;
1687
1700
  entityPackageName: z.ZodDefault<z.ZodUnion<[z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>]>>;
1701
+ /**
1702
+ * Schema → npm package map for **peer** entity classes this emit does not generate
1703
+ * (cross-schema embedded records and related-record collections).
1704
+ *
1705
+ * This is a different knob from {@link entityPackageName} and {@link includeSchemas}:
1706
+ *
1707
+ * - `includeSchemas` — what this run generates
1708
+ * - string `entityPackageName` — the npm package this run writes those classes into
1709
+ * - Record `entityPackageName` — install-time host map; those schemas are also skipped
1710
+ * for local generation ({@link getExternalEntitySchemas}). Do not overload it on an
1711
+ * Open App under development: listing a sibling schema there would skip generating
1712
+ * *this* app if you also listed your own schema, and converting a custom string
1713
+ * `entityPackageName` into a Record silently re-routes every unmapped schema.
1714
+ * - `entityImportPackages` — where to `import { PeerEntity }` from when the peer's
1715
+ * schema is not in this file
1716
+ *
1717
+ * Publishers (Open Apps under development) use string `entityPackageName` +
1718
+ * `includeSchemas` and must list sibling app schemas here. Hosts that already use
1719
+ * Record `entityPackageName` do not need this — that map is the fallback after this
1720
+ * one. Case-insensitive schema keys. Mapping a foreign schema to this emit's own
1721
+ * package is an error (that would self-import a class this file does not emit).
1722
+ *
1723
+ * @see resolveEntityImportPackage
1724
+ */
1725
+ entityImportPackages: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
1688
1726
  verboseOutput: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
1689
1727
  /**
1690
1728
  * Number of metadata `INSERT` statements CodeGen joins into a single batched
@@ -1707,6 +1745,7 @@ declare const configInfoSchema: z.ZodObject<{
1707
1745
  value?: any;
1708
1746
  }[];
1709
1747
  excludeSchemas: string[];
1748
+ allowCrossSchemaCascadeDeletes: boolean;
1710
1749
  excludeTables: {
1711
1750
  schema: string;
1712
1751
  table: string;
@@ -1881,6 +1920,7 @@ declare const configInfoSchema: z.ZodObject<{
1881
1920
  mode?: "full" | "task" | undefined;
1882
1921
  } | undefined;
1883
1922
  outputCode?: string | null | undefined;
1923
+ entityImportPackages?: Record<string, string> | undefined;
1884
1924
  }, {
1885
1925
  logging: {
1886
1926
  log?: boolean | undefined;
@@ -1988,6 +2028,7 @@ declare const configInfoSchema: z.ZodObject<{
1988
2028
  }[] | undefined;
1989
2029
  excludeSchemas?: string[] | undefined;
1990
2030
  includeSchemas?: string[] | undefined;
2031
+ allowCrossSchemaCascadeDeletes?: boolean | undefined;
1991
2032
  excludeTables?: {
1992
2033
  schema: string;
1993
2034
  table: string;
@@ -2059,6 +2100,7 @@ declare const configInfoSchema: z.ZodObject<{
2059
2100
  mjCoreSchema?: string | undefined;
2060
2101
  graphqlPort?: number | undefined;
2061
2102
  entityPackageName?: string | Record<string, string> | undefined;
2103
+ entityImportPackages?: Record<string, string> | undefined;
2062
2104
  verboseOutput?: boolean | undefined;
2063
2105
  metadataInsertBatchSize?: number | undefined;
2064
2106
  }>;
@@ -2106,6 +2148,7 @@ export declare const configInfo: {
2106
2148
  value?: any;
2107
2149
  }[];
2108
2150
  excludeSchemas: string[];
2151
+ allowCrossSchemaCascadeDeletes: boolean;
2109
2152
  excludeTables: {
2110
2153
  schema: string;
2111
2154
  table: string;
@@ -2280,6 +2323,7 @@ export declare const configInfo: {
2280
2323
  mode?: "full" | "task" | undefined;
2281
2324
  } | undefined;
2282
2325
  outputCode?: string | null | undefined;
2326
+ entityImportPackages?: Record<string, string> | undefined;
2283
2327
  };
2284
2328
  /**
2285
2329
  * Destructured commonly used configuration values
@@ -2355,18 +2399,91 @@ export declare function getSettingValue(settingName: string, defaultValue?: any)
2355
2399
  * @returns True if auto-indexing is enabled (the default), false only if explicitly disabled
2356
2400
  */
2357
2401
  export declare function autoIndexForeignKeys(): boolean;
2402
+ /**
2403
+ * Checks if automatic indexing of SOFT primary keys is enabled.
2404
+ *
2405
+ * **Defaults to `true` when the `auto_index_soft_primary_keys` setting is absent**, for the
2406
+ * same reason as {@link autoIndexForeignKeys} and then some: nothing else in the stack can
2407
+ * ever create these indexes.
2408
+ *
2409
+ * A soft primary key is a PK that exists only in metadata — `IsPrimaryKey` and
2410
+ * `IsSoftPrimaryKey` are both set, and the table carries NO `PRIMARY KEY` constraint and no
2411
+ * unique index. Integration tables are built this way deliberately: their keys are *inferred*
2412
+ * from naming and streamed-data statistics, so enforcing one would reject valid rows the
2413
+ * moment an inference is wrong.
2414
+ *
2415
+ * The cost of that choice is that the table is a heap, and MJ's own write path pays it on
2416
+ * every single record. A create calls `InnerLoad` on the key to see whether the record already
2417
+ * exists; a genuinely new record finds nothing; and a not-found lookup cannot short-circuit,
2418
+ * so it scans the ENTIRE table before concluding the row is absent. Every create scans the
2419
+ * whole table, the table grows, and the scan grows with it — the throughput of a sync decays
2420
+ * as it runs, which reads as "the vendor is slow" rather than "an index is missing".
2421
+ *
2422
+ * Three separate mechanisms each declined to cover this:
2423
+ * - the integration DDL generator emits the table with no index on the key columns
2424
+ * - {@link autoIndexForeignKeys} covers foreign keys only, and explicitly SKIPS primary keys
2425
+ * on the reasoning that "a primary key is already covered by its own index" — true for a
2426
+ * real PK, false by definition for a soft one
2427
+ * - the missing-index probe reads `sys.foreign_keys`, and these tables have no physical FK
2428
+ * constraints, so it can never flag them
2429
+ *
2430
+ * Hence a separate setting rather than reusing the FK flag: an operator who has opinions about
2431
+ * foreign-key indexing has not thereby expressed an opinion about the engine's own hot path.
2432
+ *
2433
+ * @returns True if soft-PK auto-indexing is enabled (the default), false only if explicitly disabled
2434
+ */
2435
+ export declare function autoIndexSoftPrimaryKeys(): boolean;
2358
2436
  /**
2359
2437
  * Resolves the entity package name for a given database schema.
2360
2438
  *
2361
2439
  * When `entityPackageName` is a plain string (legacy/default), all non-core schemas
2362
2440
  * use that single package. When it is a `Record<string, string>`, each schema is
2363
- * mapped to its own package (used by OpenApp projects with multiple installed apps).
2441
+ * mapped to its own package (used by OpenApp **hosts** with multiple installed apps).
2442
+ *
2443
+ * Do **not** use this for peer-class imports on generated subclasses (embeds,
2444
+ * related-record collections). String form returns this emit's package for every
2445
+ * schema, which is the self-import bug Open App publishers hit. Use
2446
+ * {@link resolveEntityImportPackage} for that.
2364
2447
  *
2365
2448
  * @param schemaName The database schema name of the entity
2366
2449
  * @param config Optional config override; falls back to the module-level configInfo
2367
2450
  * @returns The npm package name to use for importing entities from this schema
2368
2451
  */
2369
2452
  export declare function resolveEntityPackageName(schemaName: string, config?: ConfigInfo): string;
2453
+ /**
2454
+ * The npm package this CodeGen emit writes entity subclasses into.
2455
+ *
2456
+ * String `entityPackageName` is that package. Record form is the install-time host
2457
+ * map (those keys are also skipped for local generation); this emit's package is
2458
+ * the owning schema's entry, or `mj_generatedentities` when the owning schema is
2459
+ * not mapped.
2460
+ */
2461
+ export declare function thisEmitEntityPackageName(owningSchema: string, config?: ConfigInfo): string;
2462
+ /**
2463
+ * Resolves the npm package to import a **peer** entity class from — embeds and
2464
+ * related-record collections whose class is not being emitted in this file.
2465
+ *
2466
+ * Generation scope (`includeSchemas`) and this emit's package (string
2467
+ * `entityPackageName`) are deliberately not reused as the import map. A string
2468
+ * `entityPackageName` means "classes this run emits live in this package"; using
2469
+ * it for a foreign schema is how Open App publishers used to self-import
2470
+ * `@mj-biz-apps/orders-entities` for a Common Address embed.
2471
+ *
2472
+ * Resolution, in order:
2473
+ * 1. Core schema (`mjCoreSchema` / `__mj`) → `@memberjunction/core-entities`
2474
+ * 2. Same schema as the owning entity → this emit's package (same-schema peers
2475
+ * not in the current file, e.g. skipped PK-less entities)
2476
+ * 3. `entityImportPackages` schema → npm map (publisher / Open App under development)
2477
+ * 4. Record-form `entityPackageName` (install-time host map — fallback only)
2478
+ * 5. Otherwise throw. Never silently fall back to the local package for a
2479
+ * foreign schema, and never emit a self-import of this emit's package for a
2480
+ * foreign schema even if the map says so.
2481
+ *
2482
+ * @param relatedSchema Schema of the peer being imported
2483
+ * @param owningSchema Schema of the entity currently being generated
2484
+ * @param config Optional config override; falls back to module-level configInfo
2485
+ */
2486
+ export declare function resolveEntityImportPackage(relatedSchema: string, owningSchema: string, config?: ConfigInfo): string;
2370
2487
  /**
2371
2488
  * Returns all schema names that have an explicit external entity package mapping.
2372
2489
  * These schemas should be skipped during local entity subclass generation because
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/Config/config.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/Config/config.ts"],"names":[],"mappings":"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"}
@@ -355,8 +355,21 @@ const configInfoSchema = z.object({
355
355
  * exclude list naming every other installed app — a list that is O(N²) to maintain and, more
356
356
  * importantly, cannot name schemas the app does not know about (such as a client's own schemas in
357
357
  * a deployed instance).
358
+ *
359
+ * The in-memory compile into `excludeSchemas` is for THIS CodeGen run only (which entities to
360
+ * generate). Heal stored-procedure EXEC statements logged into migrations use authored
361
+ * `excludeSchemas` plus `@IncludedSchemaNames` from this list — they must not snapshot sibling
362
+ * apps that happened to be installed on the publisher database.
358
363
  */
359
364
  includeSchemas: z.string().array().optional(),
365
+ /**
366
+ * When true, CodeGen cascade-delete SQL walks FKs pointing at the entity in
367
+ * EVERY schema in metadata. Default false: only same-schema children.
368
+ * Turning this on (and CascadeDeletes on an entity) will bake consumer
369
+ * schemas into a publisher's delete proc — a dangerous escape hatch.
370
+ * Leave off for Open Apps.
371
+ */
372
+ allowCrossSchemaCascadeDeletes: z.boolean().default(false),
360
373
  excludeTables: tableInfoSchema.array().default([
361
374
  { schema: '%', table: 'sys%' },
362
375
  { schema: '%', table: 'flyway_schema_history' }
@@ -526,6 +539,31 @@ const configInfoSchema = z.object({
526
539
  z.string(),
527
540
  z.record(z.string(), z.string())
528
541
  ]).default('mj_generatedentities'),
542
+ /**
543
+ * Schema → npm package map for **peer** entity classes this emit does not generate
544
+ * (cross-schema embedded records and related-record collections).
545
+ *
546
+ * This is a different knob from {@link entityPackageName} and {@link includeSchemas}:
547
+ *
548
+ * - `includeSchemas` — what this run generates
549
+ * - string `entityPackageName` — the npm package this run writes those classes into
550
+ * - Record `entityPackageName` — install-time host map; those schemas are also skipped
551
+ * for local generation ({@link getExternalEntitySchemas}). Do not overload it on an
552
+ * Open App under development: listing a sibling schema there would skip generating
553
+ * *this* app if you also listed your own schema, and converting a custom string
554
+ * `entityPackageName` into a Record silently re-routes every unmapped schema.
555
+ * - `entityImportPackages` — where to `import { PeerEntity }` from when the peer's
556
+ * schema is not in this file
557
+ *
558
+ * Publishers (Open Apps under development) use string `entityPackageName` +
559
+ * `includeSchemas` and must list sibling app schemas here. Hosts that already use
560
+ * Record `entityPackageName` do not need this — that map is the fallback after this
561
+ * one. Case-insensitive schema keys. Mapping a foreign schema to this emit's own
562
+ * package is an error (that would self-import a class this file does not emit).
563
+ *
564
+ * @see resolveEntityImportPackage
565
+ */
566
+ entityImportPackages: z.record(z.string(), z.string()).optional(),
529
567
  verboseOutput: z.boolean().optional().default(false),
530
568
  /**
531
569
  * Number of metadata `INSERT` statements CodeGen joins into a single batched
@@ -866,9 +904,9 @@ export function initializeConfig(cwd) {
866
904
  // known about at the moment it built DEFAULT_CODEGEN_CONFIG.
867
905
  applyPlatformDependentEnvVars(config, userConfigResult?.config ?? {});
868
906
  // Update the module-level configInfo so that helpers like
869
- // resolveEntityPackageName() and getExternalEntitySchemas() see the
870
- // config from the correct working directory, not the stale one from
871
- // initial module load.
907
+ // resolveEntityPackageName(), resolveEntityImportPackage() and
908
+ // getExternalEntitySchemas() see the config from the correct working
909
+ // directory, not the stale one from initial module load.
872
910
  Object.assign(configInfo, config);
873
911
  return config;
874
912
  }
@@ -990,12 +1028,89 @@ export function autoIndexForeignKeys() {
990
1028
  else
991
1029
  return true;
992
1030
  }
1031
+ /**
1032
+ * Checks if automatic indexing of SOFT primary keys is enabled.
1033
+ *
1034
+ * **Defaults to `true` when the `auto_index_soft_primary_keys` setting is absent**, for the
1035
+ * same reason as {@link autoIndexForeignKeys} and then some: nothing else in the stack can
1036
+ * ever create these indexes.
1037
+ *
1038
+ * A soft primary key is a PK that exists only in metadata — `IsPrimaryKey` and
1039
+ * `IsSoftPrimaryKey` are both set, and the table carries NO `PRIMARY KEY` constraint and no
1040
+ * unique index. Integration tables are built this way deliberately: their keys are *inferred*
1041
+ * from naming and streamed-data statistics, so enforcing one would reject valid rows the
1042
+ * moment an inference is wrong.
1043
+ *
1044
+ * The cost of that choice is that the table is a heap, and MJ's own write path pays it on
1045
+ * every single record. A create calls `InnerLoad` on the key to see whether the record already
1046
+ * exists; a genuinely new record finds nothing; and a not-found lookup cannot short-circuit,
1047
+ * so it scans the ENTIRE table before concluding the row is absent. Every create scans the
1048
+ * whole table, the table grows, and the scan grows with it — the throughput of a sync decays
1049
+ * as it runs, which reads as "the vendor is slow" rather than "an index is missing".
1050
+ *
1051
+ * Three separate mechanisms each declined to cover this:
1052
+ * - the integration DDL generator emits the table with no index on the key columns
1053
+ * - {@link autoIndexForeignKeys} covers foreign keys only, and explicitly SKIPS primary keys
1054
+ * on the reasoning that "a primary key is already covered by its own index" — true for a
1055
+ * real PK, false by definition for a soft one
1056
+ * - the missing-index probe reads `sys.foreign_keys`, and these tables have no physical FK
1057
+ * constraints, so it can never flag them
1058
+ *
1059
+ * Hence a separate setting rather than reusing the FK flag: an operator who has opinions about
1060
+ * foreign-key indexing has not thereby expressed an opinion about the engine's own hot path.
1061
+ *
1062
+ * @returns True if soft-PK auto-indexing is enabled (the default), false only if explicitly disabled
1063
+ */
1064
+ export function autoIndexSoftPrimaryKeys() {
1065
+ const keyName = 'auto_index_soft_primary_keys';
1066
+ const setting = getSetting(keyName);
1067
+ if (setting)
1068
+ return setting.value;
1069
+ else
1070
+ return true;
1071
+ }
1072
+ /**
1073
+ * Case-insensitive lookup in a schema → npm package map. Empty values are treated as
1074
+ * missing so a typo `''` cannot silently emit `from ''`.
1075
+ */
1076
+ function lookupSchemaPackage(map, schemaName) {
1077
+ if (!map || typeof map !== 'object') {
1078
+ return undefined;
1079
+ }
1080
+ const lower = schemaName.toLowerCase();
1081
+ const match = Object.keys(map).find((k) => k.toLowerCase() === lower);
1082
+ if (!match) {
1083
+ return undefined;
1084
+ }
1085
+ const value = map[match];
1086
+ return typeof value === 'string' && value.trim().length > 0 ? value.trim() : undefined;
1087
+ }
1088
+ function coreSchemaFromConfig(cfg) {
1089
+ if (cfg.mjCoreSchema && String(cfg.mjCoreSchema).trim()) {
1090
+ return String(cfg.mjCoreSchema).trim();
1091
+ }
1092
+ try {
1093
+ const fromFn = typeof mj_core_schema === 'function' ? mj_core_schema() : mj_core_schema;
1094
+ if (fromFn && String(fromFn).trim()) {
1095
+ return String(fromFn).trim();
1096
+ }
1097
+ }
1098
+ catch {
1099
+ // settings missing in some unit tests
1100
+ }
1101
+ return '__mj';
1102
+ }
993
1103
  /**
994
1104
  * Resolves the entity package name for a given database schema.
995
1105
  *
996
1106
  * When `entityPackageName` is a plain string (legacy/default), all non-core schemas
997
1107
  * use that single package. When it is a `Record<string, string>`, each schema is
998
- * mapped to its own package (used by OpenApp projects with multiple installed apps).
1108
+ * mapped to its own package (used by OpenApp **hosts** with multiple installed apps).
1109
+ *
1110
+ * Do **not** use this for peer-class imports on generated subclasses (embeds,
1111
+ * related-record collections). String form returns this emit's package for every
1112
+ * schema, which is the self-import bug Open App publishers hit. Use
1113
+ * {@link resolveEntityImportPackage} for that.
999
1114
  *
1000
1115
  * @param schemaName The database schema name of the entity
1001
1116
  * @param config Optional config override; falls back to the module-level configInfo
@@ -1007,10 +1122,89 @@ export function resolveEntityPackageName(schemaName, config) {
1007
1122
  if (typeof epn === 'string') {
1008
1123
  return epn || 'mj_generatedentities';
1009
1124
  }
1010
- // Case-insensitive lookup: DB schema names may differ in casing from config keys
1011
- const lowerSchema = schemaName.toLowerCase();
1012
- const match = Object.keys(epn).find(k => k.toLowerCase() === lowerSchema);
1013
- return match ? epn[match] : 'mj_generatedentities';
1125
+ return lookupSchemaPackage(epn, schemaName) || 'mj_generatedentities';
1126
+ }
1127
+ /**
1128
+ * The npm package this CodeGen emit writes entity subclasses into.
1129
+ *
1130
+ * String `entityPackageName` is that package. Record form is the install-time host
1131
+ * map (those keys are also skipped for local generation); this emit's package is
1132
+ * the owning schema's entry, or `mj_generatedentities` when the owning schema is
1133
+ * not mapped.
1134
+ */
1135
+ export function thisEmitEntityPackageName(owningSchema, config) {
1136
+ const cfg = config ?? configInfo;
1137
+ const epn = cfg.entityPackageName;
1138
+ if (typeof epn === 'string') {
1139
+ return epn.trim() || 'mj_generatedentities';
1140
+ }
1141
+ return lookupSchemaPackage(epn, owningSchema) || 'mj_generatedentities';
1142
+ }
1143
+ /**
1144
+ * Resolves the npm package to import a **peer** entity class from — embeds and
1145
+ * related-record collections whose class is not being emitted in this file.
1146
+ *
1147
+ * Generation scope (`includeSchemas`) and this emit's package (string
1148
+ * `entityPackageName`) are deliberately not reused as the import map. A string
1149
+ * `entityPackageName` means "classes this run emits live in this package"; using
1150
+ * it for a foreign schema is how Open App publishers used to self-import
1151
+ * `@mj-biz-apps/orders-entities` for a Common Address embed.
1152
+ *
1153
+ * Resolution, in order:
1154
+ * 1. Core schema (`mjCoreSchema` / `__mj`) → `@memberjunction/core-entities`
1155
+ * 2. Same schema as the owning entity → this emit's package (same-schema peers
1156
+ * not in the current file, e.g. skipped PK-less entities)
1157
+ * 3. `entityImportPackages` schema → npm map (publisher / Open App under development)
1158
+ * 4. Record-form `entityPackageName` (install-time host map — fallback only)
1159
+ * 5. Otherwise throw. Never silently fall back to the local package for a
1160
+ * foreign schema, and never emit a self-import of this emit's package for a
1161
+ * foreign schema even if the map says so.
1162
+ *
1163
+ * @param relatedSchema Schema of the peer being imported
1164
+ * @param owningSchema Schema of the entity currently being generated
1165
+ * @param config Optional config override; falls back to module-level configInfo
1166
+ */
1167
+ export function resolveEntityImportPackage(relatedSchema, owningSchema, config) {
1168
+ const cfg = config ?? configInfo;
1169
+ const related = (relatedSchema ?? '').trim();
1170
+ const owning = (owningSchema ?? '').trim();
1171
+ if (!related) {
1172
+ throw new Error(`[CodeGen] entity import: related entity has an empty SchemaName while generating schema '${owning || '(unknown)'}'.`);
1173
+ }
1174
+ if (!owning) {
1175
+ throw new Error(`[CodeGen] entity import: owning entity has an empty SchemaName (related schema '${related}').`);
1176
+ }
1177
+ const core = coreSchemaFromConfig(cfg).toLowerCase();
1178
+ if (related.toLowerCase() === core) {
1179
+ return '@memberjunction/core-entities';
1180
+ }
1181
+ const localPackage = thisEmitEntityPackageName(owning, cfg);
1182
+ if (related.toLowerCase() === owning.toLowerCase()) {
1183
+ return localPackage;
1184
+ }
1185
+ const fromImportMap = lookupSchemaPackage(cfg.entityImportPackages, related);
1186
+ const epn = cfg.entityPackageName;
1187
+ const fromHostMap = typeof epn === 'object' && epn ? lookupSchemaPackage(epn, related) : undefined;
1188
+ const resolved = fromImportMap || fromHostMap;
1189
+ if (resolved) {
1190
+ if (resolved === localPackage) {
1191
+ throw new Error(`[CodeGen] entity import: schema '${related}' is mapped to '${resolved}', which is this emit's own package ` +
1192
+ `('${localPackage}') while generating '${owning}'. Foreign-schema peers must come from THEIR npm package. ` +
1193
+ `includeSchemas already decided this emit does not generate '${related}'. Do not list that schema in ` +
1194
+ `entityImportPackages (or entityPackageName) with this emit's package name.`);
1195
+ }
1196
+ return resolved;
1197
+ }
1198
+ const stringForm = typeof epn === 'string';
1199
+ throw new Error(`[CodeGen] entity import: cannot import entity classes from schema '${related}' while generating '${owning}'. ` +
1200
+ `'${related}' is not listed in entityImportPackages` +
1201
+ (stringForm
1202
+ ? ` (and entityPackageName is the string '${localPackage}', which is this emit's package — not a schema map)`
1203
+ : ` or the entityPackageName schema map`) +
1204
+ `. Add to mj.config.cjs:\n` +
1205
+ ` entityImportPackages: {\n '${related}': '<npm-package-that-exports-these-entity-classes>',\n }\n` +
1206
+ `includeSchemas controls what this emit generates. String entityPackageName is this emit's npm package. ` +
1207
+ `Do not map '${related}' to '${localPackage}'.`);
1014
1208
  }
1015
1209
  /**
1016
1210
  * Returns all schema names that have an explicit external entity package mapping.