@memberjunction/codegen-lib 6.1.0-edge.2 → 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 (133) hide show
  1. package/LICENSE +180 -4
  2. package/README.md +89 -43
  3. package/dist/Angular/angular-codegen.d.ts +0 -8
  4. package/dist/Angular/angular-codegen.d.ts.map +1 -1
  5. package/dist/Angular/angular-codegen.js +32 -22
  6. package/dist/Angular/angular-codegen.js.map +1 -1
  7. package/dist/Angular/entity-data-grid-related-entity-component.js +2 -2
  8. package/dist/Angular/entity-data-grid-related-entity-component.js.map +1 -1
  9. package/dist/Angular/related-entity-components.d.ts +1 -1
  10. package/dist/Angular/related-entity-components.js +1 -1
  11. package/dist/Config/config.d.ts +118 -1
  12. package/dist/Config/config.d.ts.map +1 -1
  13. package/dist/Config/config.js +202 -8
  14. package/dist/Config/config.js.map +1 -1
  15. package/dist/Database/__tests__/exclude-schema-permissions.test.d.ts +2 -0
  16. package/dist/Database/__tests__/exclude-schema-permissions.test.d.ts.map +1 -0
  17. package/dist/Database/__tests__/exclude-schema-permissions.test.js +32 -0
  18. package/dist/Database/__tests__/exclude-schema-permissions.test.js.map +1 -0
  19. package/dist/Database/codeGenDatabaseProvider.d.ts +178 -2
  20. package/dist/Database/codeGenDatabaseProvider.d.ts.map +1 -1
  21. package/dist/Database/codeGenDatabaseProvider.js +175 -10
  22. package/dist/Database/codeGenDatabaseProvider.js.map +1 -1
  23. package/dist/Database/heal-schema-params.d.ts +33 -0
  24. package/dist/Database/heal-schema-params.d.ts.map +1 -0
  25. package/dist/Database/heal-schema-params.js +51 -0
  26. package/dist/Database/heal-schema-params.js.map +1 -0
  27. package/dist/Database/manage-metadata.d.ts +301 -2
  28. package/dist/Database/manage-metadata.d.ts.map +1 -1
  29. package/dist/Database/manage-metadata.js +1242 -96
  30. package/dist/Database/manage-metadata.js.map +1 -1
  31. package/dist/Database/materializationAnalysis.d.ts +241 -0
  32. package/dist/Database/materializationAnalysis.d.ts.map +1 -0
  33. package/dist/Database/materializationAnalysis.js +415 -0
  34. package/dist/Database/materializationAnalysis.js.map +1 -0
  35. package/dist/Database/materializationBroadRender.d.ts +67 -0
  36. package/dist/Database/materializationBroadRender.d.ts.map +1 -0
  37. package/dist/Database/materializationBroadRender.js +104 -0
  38. package/dist/Database/materializationBroadRender.js.map +1 -0
  39. package/dist/Database/materializationDrift.d.ts +59 -0
  40. package/dist/Database/materializationDrift.d.ts.map +1 -0
  41. package/dist/Database/materializationDrift.js +85 -0
  42. package/dist/Database/materializationDrift.js.map +1 -0
  43. package/dist/Database/materializationParamClassifier.d.ts +92 -0
  44. package/dist/Database/materializationParamClassifier.d.ts.map +1 -0
  45. package/dist/Database/materializationParamClassifier.js +224 -0
  46. package/dist/Database/materializationParamClassifier.js.map +1 -0
  47. package/dist/Database/materializationParamVerifier.d.ts +71 -0
  48. package/dist/Database/materializationParamVerifier.d.ts.map +1 -0
  49. package/dist/Database/materializationParamVerifier.js +302 -0
  50. package/dist/Database/materializationParamVerifier.js.map +1 -0
  51. package/dist/Database/materializationSqlAst.d.ts +78 -0
  52. package/dist/Database/materializationSqlAst.d.ts.map +1 -0
  53. package/dist/Database/materializationSqlAst.js +142 -0
  54. package/dist/Database/materializationSqlAst.js.map +1 -0
  55. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts +93 -56
  56. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts.map +1 -1
  57. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js +399 -247
  58. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js.map +1 -1
  59. package/dist/Database/providers/postgresql/__tests__/PostgreSQLCodeGenProvider.materialization.test.d.ts +2 -0
  60. package/dist/Database/providers/postgresql/__tests__/PostgreSQLCodeGenProvider.materialization.test.d.ts.map +1 -0
  61. package/dist/Database/providers/postgresql/__tests__/PostgreSQLCodeGenProvider.materialization.test.js +119 -0
  62. package/dist/Database/providers/postgresql/__tests__/PostgreSQLCodeGenProvider.materialization.test.js.map +1 -0
  63. package/dist/Database/providers/postgresql/__tests__/PostgreSQLHierarchyFunctions.test.d.ts +2 -0
  64. package/dist/Database/providers/postgresql/__tests__/PostgreSQLHierarchyFunctions.test.d.ts.map +1 -0
  65. package/dist/Database/providers/postgresql/__tests__/PostgreSQLHierarchyFunctions.test.js +155 -0
  66. package/dist/Database/providers/postgresql/__tests__/PostgreSQLHierarchyFunctions.test.js.map +1 -0
  67. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.d.ts +2 -0
  68. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.d.ts.map +1 -0
  69. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.js +110 -0
  70. package/dist/Database/providers/postgresql/__tests__/SoftPrimaryKeyIndex.test.js.map +1 -0
  71. package/dist/Database/providers/postgresql/metadataSupportObjects.js +78 -10
  72. package/dist/Database/providers/postgresql/metadataSupportObjects.js.map +1 -1
  73. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts +72 -1
  74. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts.map +1 -1
  75. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js +322 -0
  76. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js.map +1 -1
  77. package/dist/Database/providers/sqlserver/__tests__/BaseViewEmissionGoldenMaster.test.d.ts +2 -0
  78. package/dist/Database/providers/sqlserver/__tests__/BaseViewEmissionGoldenMaster.test.d.ts.map +1 -0
  79. package/dist/Database/providers/sqlserver/__tests__/BaseViewEmissionGoldenMaster.test.js +547 -0
  80. package/dist/Database/providers/sqlserver/__tests__/BaseViewEmissionGoldenMaster.test.js.map +1 -0
  81. package/dist/Database/providers/sqlserver/__tests__/BaseViewRegenDecision.test.d.ts +2 -0
  82. package/dist/Database/providers/sqlserver/__tests__/BaseViewRegenDecision.test.d.ts.map +1 -0
  83. package/dist/Database/providers/sqlserver/__tests__/BaseViewRegenDecision.test.js +721 -0
  84. package/dist/Database/providers/sqlserver/__tests__/BaseViewRegenDecision.test.js.map +1 -0
  85. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.materialization.test.d.ts +2 -0
  86. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.materialization.test.d.ts.map +1 -0
  87. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.materialization.test.js +78 -0
  88. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.materialization.test.js.map +1 -0
  89. package/dist/Database/providers/sqlserver/__tests__/SQLServerHierarchyTVF.test.d.ts +2 -0
  90. package/dist/Database/providers/sqlserver/__tests__/SQLServerHierarchyTVF.test.d.ts.map +1 -0
  91. package/dist/Database/providers/sqlserver/__tests__/SQLServerHierarchyTVF.test.js +155 -0
  92. package/dist/Database/providers/sqlserver/__tests__/SQLServerHierarchyTVF.test.js.map +1 -0
  93. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.d.ts +2 -0
  94. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.d.ts.map +1 -0
  95. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.js +195 -0
  96. package/dist/Database/providers/sqlserver/__tests__/SoftPrimaryKeyIndex.test.js.map +1 -0
  97. package/dist/Database/schema-filters.d.ts +23 -0
  98. package/dist/Database/schema-filters.d.ts.map +1 -0
  99. package/dist/Database/schema-filters.js +42 -0
  100. package/dist/Database/schema-filters.js.map +1 -0
  101. package/dist/Database/schema-scope.d.ts.map +1 -1
  102. package/dist/Database/schema-scope.js +4 -0
  103. package/dist/Database/schema-scope.js.map +1 -1
  104. package/dist/Database/sql_codegen.d.ts +39 -5
  105. package/dist/Database/sql_codegen.d.ts.map +1 -1
  106. package/dist/Database/sql_codegen.js +176 -67
  107. package/dist/Database/sql_codegen.js.map +1 -1
  108. package/dist/EntityNameScanner/EntityNameScanner.d.ts.map +1 -1
  109. package/dist/EntityNameScanner/EntityNameScanner.js +33 -2
  110. package/dist/EntityNameScanner/EntityNameScanner.js.map +1 -1
  111. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts +8 -4
  112. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts.map +1 -1
  113. package/dist/Manifest/GenerateClassRegistrationsManifest.js +63 -20
  114. package/dist/Manifest/GenerateClassRegistrationsManifest.js.map +1 -1
  115. package/dist/Misc/action_subclasses_codegen.d.ts.map +1 -1
  116. package/dist/Misc/action_subclasses_codegen.js +4 -4
  117. package/dist/Misc/action_subclasses_codegen.js.map +1 -1
  118. package/dist/Misc/entity_subclasses_codegen.d.ts +61 -0
  119. package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
  120. package/dist/Misc/entity_subclasses_codegen.js +437 -158
  121. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  122. package/dist/Misc/graphql_server_codegen.d.ts +4 -58
  123. package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
  124. package/dist/Misc/graphql_server_codegen.js +22 -236
  125. package/dist/Misc/graphql_server_codegen.js.map +1 -1
  126. package/dist/Misc/sql_logging.d.ts +25 -0
  127. package/dist/Misc/sql_logging.d.ts.map +1 -1
  128. package/dist/Misc/sql_logging.js +51 -8
  129. package/dist/Misc/sql_logging.js.map +1 -1
  130. package/dist/Misc/system_integrity.d.ts.map +1 -1
  131. package/dist/Misc/system_integrity.js +5 -0
  132. package/dist/Misc/system_integrity.js.map +1 -1
  133. package/package.json +30 -30
package/LICENSE CHANGED
@@ -1,7 +1,183 @@
1
- ISC License
1
+ Business Source License 1.1
2
2
 
3
- Copyright (c) 2023 MemberJunction
3
+ License text copyright (c) 2024 MariaDB plc, All Rights Reserved.
4
+ "Business Source License" is a trademark of MariaDB plc.
4
5
 
5
- Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
6
+ -----------------------------------------------------------------------------
6
7
 
7
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
8
+ Parameters
9
+
10
+ Licensor: Blue Cypress, Inc.
11
+
12
+ Licensed Work: MemberJunction.
13
+ The Licensed Work is (c) 2023-2026 Blue Cypress, Inc.
14
+
15
+ Additional Use Grant: Subject to the terms of this License, Licensor grants
16
+ you the following additional rights to make Production
17
+ Use of the Licensed Work.
18
+
19
+ 1. Internal Use
20
+
21
+ You may make production use of the Licensed Work for
22
+ your own internal business or organizational operations.
23
+
24
+ 2. Nonprofit Use
25
+
26
+ If you are a Nonprofit, you may make production use of
27
+ the Licensed Work for the operations and activities of
28
+ your Organizational Family.
29
+
30
+ 3. MemberJunction Certified Program Use
31
+
32
+ If you are authorized by Licensor under the
33
+ MemberJunction Certified Program to provide professional
34
+ services using the Licensed Work, you may make
35
+ production use of the Licensed Work in providing such
36
+ professional services to a client, provided that:
37
+
38
+ (a) the Licensed Work is deployed in, and the applicable
39
+ production use occurs within, an environment owned,
40
+ leased, licensed, subscribed to, or otherwise controlled
41
+ by that client; and
42
+
43
+ (b) the production use is for that client's own internal
44
+ business or organizational operations or is otherwise
45
+ independently permitted to that client under this
46
+ Additional Use Grant.
47
+
48
+ 4. Definitions Applicable to the Additional Use Grant
49
+
50
+ "Affiliate" means, with respect to a specified Person,
51
+ any other Person that directly or indirectly Controls,
52
+ is Controlled by, or is under common Control with such
53
+ specified Person.
54
+
55
+ "Control" (including the terms "Controls," "Controlled
56
+ by," and "under common Control with") means the direct
57
+ or indirect possession of the power to direct or cause
58
+ the direction of the management and policies of a
59
+ Person, whether through ownership of voting interests,
60
+ by contract, or otherwise.
61
+
62
+ "Organizational Family" means, with respect to a Person,
63
+ (a) such Person and its Affiliates, and (b) any
64
+ nonprofit organization, governmental entity, chapter,
65
+ division, local affiliate, regional affiliate, state
66
+ affiliate, national affiliate, or other entity that is
67
+ formally affiliated with such Person through governing
68
+ documents, a charter, bylaws, a membership agreement, or
69
+ another written organizational instrument, and is
70
+ recognized under such documents as part of the same
71
+ organizational structure.
72
+
73
+ "Nonprofit" means a Person recognized by the Internal
74
+ Revenue Service as exempt from federal income taxation
75
+ under Section 501(c)(3), 501(c)(4), 501(c)(5), or
76
+ 501(c)(6) of the Internal Revenue Code, or a foreign
77
+ organization recognized under substantially equivalent
78
+ laws.
79
+
80
+ A Person claiming eligibility as a Nonprofit shall, upon
81
+ Licensor's reasonable request, provide documentation
82
+ reasonably sufficient to demonstrate that it qualifies
83
+ as a Nonprofit. If such Person materially misrepresents,
84
+ or is unable to demonstrate, its qualification as a
85
+ Nonprofit, the rights granted to such Person under
86
+ Section 2 of this Additional Use Grant shall terminate.
87
+
88
+ "MemberJunction Certified Program" means Licensor's
89
+ then-current program for certifying and authorizing a
90
+ Person to provide professional services using the
91
+ Licensed Work.
92
+
93
+ "Person" means any individual, corporation, limited
94
+ liability company, partnership, association, nonprofit
95
+ organization, governmental entity, or other legal or
96
+ organizational entity.
97
+
98
+ Change Date: Four (4) years from the date the Licensed Work is first
99
+ made available.
100
+
101
+ Change License: MIT License.
102
+
103
+ For information about alternative licensing arrangements for the Licensed
104
+ Work, please contact Blue Cypress, Inc.
105
+
106
+ -----------------------------------------------------------------------------
107
+
108
+ Terms
109
+
110
+ The Licensor hereby grants you the right to copy, modify, create derivative
111
+ works, redistribute, and make non-production use of the Licensed Work. The
112
+ Licensor may make an Additional Use Grant, above, permitting limited
113
+ production use.
114
+
115
+ Effective on the Change Date, or the fourth anniversary of the first publicly
116
+ available distribution of a specific version of the Licensed Work under this
117
+ License, whichever comes first, the Licensor hereby grants you rights under
118
+ the terms of the Change License, and the rights granted in the paragraph
119
+ above terminate.
120
+
121
+ If your use of the Licensed Work does not comply with the requirements
122
+ currently in effect as described in this License, you must purchase a
123
+ commercial license from the Licensor, its affiliated entities, or authorized
124
+ resellers, or you must refrain from using the Licensed Work.
125
+
126
+ All copies of the original and modified Licensed Work, and derivative works
127
+ of the Licensed Work, are subject to this License. This License applies
128
+ separately for each version of the Licensed Work and the Change Date may vary
129
+ for each version of the Licensed Work released by Licensor.
130
+
131
+ You must conspicuously display this License on each original or modified copy
132
+ of the Licensed Work. If you receive the Licensed Work in original or
133
+ modified form from a third party, the terms and conditions set forth in this
134
+ License apply to your use of that work.
135
+
136
+ Any use of the Licensed Work in violation of this License will automatically
137
+ terminate your rights under this License for the current and all other
138
+ versions of the Licensed Work.
139
+
140
+ This License does not grant you any right in any trademark or logo of
141
+ Licensor or its affiliates (provided that you may use a trademark or logo of
142
+ Licensor as expressly required by this License).
143
+
144
+ TO THE EXTENT PERMITTED BY APPLICABLE LAW, THE LICENSED WORK IS PROVIDED ON
145
+ AN "AS IS" BASIS. LICENSOR HEREBY DISCLAIMS ALL WARRANTIES AND CONDITIONS,
146
+ EXPRESS OR IMPLIED, INCLUDING (WITHOUT LIMITATION) WARRANTIES OF
147
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, AND
148
+ TITLE.
149
+
150
+ MariaDB hereby grants you permission to use this License's text to license
151
+ your works, and to refer to it using the trademark "Business Source License",
152
+ as long as you comply with the Covenants of Licensor below.
153
+
154
+ -----------------------------------------------------------------------------
155
+
156
+ Covenants of Licensor
157
+
158
+ In consideration of the right to use this License's text and the "Business
159
+ Source License" name and trademark, Licensor covenants to MariaDB, and to all
160
+ other recipients of the licensed work to be provided by Licensor:
161
+
162
+ 1. To specify as the Change License the GPL Version 2.0 or any later version,
163
+ or a license that is compatible with GPL Version 2.0 or a later version,
164
+ where "compatible" means that software provided under the Change License
165
+ can be included in a program with software provided under GPL Version 2.0
166
+ or a later version. Licensor may specify additional Change Licenses without
167
+ limitation.
168
+
169
+ 2. To either: (a) specify an additional grant of rights to use that does not
170
+ impose any additional restriction on the right granted in this License, as
171
+ the Additional Use Grant; or (b) insert the text "None".
172
+
173
+ 3. To specify a Change Date.
174
+
175
+ 4. Not to modify this License in any other way.
176
+
177
+ -----------------------------------------------------------------------------
178
+
179
+ Notice
180
+
181
+ The Business Source License (this document, or the "License") is not an Open
182
+ Source license. However, the Licensed Work will eventually be made available
183
+ under an Open Source License, as stated in this License.
package/README.md CHANGED
@@ -70,8 +70,8 @@ flowchart TD
70
70
  - **AI-Powered Intelligence**: Uses AI prompts to translate CHECK constraints into Zod schemas, generate semantic form layouts, identify name fields, and create entity descriptions
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
- - **Recursive Hierarchy Support**: Automatically detects self-referential foreign keys and generates CTE-based `Root{FieldName}` columns in views
74
- - **Cascade Delete Generation**: Produces cursor-based cascade delete procedures that call child entity stored procedures, respecting business logic at every level
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. 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:
@@ -436,31 +466,48 @@ export const AIPromptSchema = z.object({
436
466
  });
437
467
  ```
438
468
 
439
- ### SQL Views with Recursive Hierarchy Support
469
+ ### SQL Views & Hierarchy Traversal Engine
440
470
 
441
- For tables with self-referential foreign keys, CodeGen automatically generates recursive CTEs:
471
+ For tables with self-referential foreign keys configured as hierarchies (`EntityField.Configuration` setting `{ "Hierarchy": { "IsHierarchy": true } }`) and single-column primary keys, CodeGen automatically generates a 4-routine Table-Valued Function (TVF) suite and projects enriched hierarchy columns into base views via `OUTER APPLY` (T-SQL) or `LEFT JOIN LATERAL` (PostgreSQL):
442
472
 
443
473
  ```sql
444
- -- Auto-detected: Task.ParentTaskID references Task.ID
445
- CREATE VIEW [vwTasks] AS
446
- WITH CTE_RootParentTaskID AS (
447
- SELECT [ID], [ID] AS [RootParentTaskID]
448
- FROM [__mj].[Task]
449
- WHERE [ParentTaskID] IS NULL
450
-
451
- UNION ALL
452
-
453
- SELECT child.[ID], parent.[RootParentTaskID]
454
- FROM [__mj].[Task] child
455
- INNER JOIN CTE_RootParentTaskID parent
456
- ON child.[ParentTaskID] = parent.[ID]
457
- )
458
- SELECT t.*, cte.[RootParentTaskID]
459
- FROM [__mj].[Task] AS t
460
- LEFT OUTER JOIN CTE_RootParentTaskID cte ON t.[ID] = cte.[ID]
474
+ -- Generated Base View with Hierarchy Columns (T-SQL)
475
+ SELECT
476
+ c.*,
477
+ hier_ParentID.RootID AS [RootParentID],
478
+ hier_ParentID.Depth AS [ParentIDDepth],
479
+ hier_ParentID.Path AS [ParentIDPath],
480
+ hier_ParentID.IsLeaf AS [ParentIDIsLeaf],
481
+ hier_ParentID.ChildCount AS [ParentIDChildCount]
482
+ FROM [sales].[Category] AS c
483
+ OUTER APPLY [sales].[fnCategoryParentID_GetHierarchyMeta]([c].[ID], [c].[ParentID]) AS hier_ParentID
461
484
  ```
462
485
 
463
- The CTE is zero-overhead: the SQL optimizer eliminates it entirely when the root column is not selected.
486
+ ```sql
487
+ -- Generated Base View with Hierarchy Columns (PostgreSQL)
488
+ SELECT
489
+ c.*,
490
+ hier_ParentID."RootID" AS "RootParentID",
491
+ hier_ParentID."Depth" AS "ParentIDDepth",
492
+ hier_ParentID."Path" AS "ParentIDPath",
493
+ hier_ParentID."IsLeaf" AS "ParentIDIsLeaf",
494
+ hier_ParentID."ChildCount" AS "ParentIDChildCount"
495
+ FROM "sales"."Category" AS c
496
+ LEFT JOIN LATERAL "sales"."fn_category_parent_id_get_hierarchy_meta"(c."ID", c."ParentID") AS hier_ParentID ON true
497
+ ```
498
+
499
+ The inline TVF join is **zero-overhead**: relational query optimizers prune it completely when hierarchy columns are not selected.
500
+
501
+ Additionally, generated entity subclasses in TypeScript automatically receive strongly-typed hierarchy traversal helper methods:
502
+
503
+ ```typescript
504
+ // Auto-generated on entity subclasses with recursive FKs
505
+ const descendants = await category.GetDescendants(maxDepth);
506
+ const ancestors = await category.GetAncestors();
507
+ const children = await category.GetChildren();
508
+ ```
509
+
510
+ See the [Recursive Foreign Keys & Hierarchy Traversal Guide](../../guides/RECURSIVE_FOREIGN_KEYS_AND_HIERARCHIES_GUIDE.md) for complete details.
464
511
 
465
512
  ### Angular Form Components
466
513
 
@@ -675,27 +722,21 @@ FROM [orders].[vwOrderHeadersGenerated] g;
675
722
  `RunView`, visible in Explorer — and is returned by `spCreate`/`spUpdate`/`spDelete`, because those
676
723
  select from `BaseView`.
677
724
 
678
- ### SQL Server only
679
-
680
- **Layering is rejected on PostgreSQL.** CodeGen throws when it encounters an entity with
681
- `GeneratedBaseViewName` set on a PG install, naming the entity and both views.
725
+ ### PostgreSQL — restar the outer view; ship it via pg-migrate
682
726
 
683
- The reason is that PG cannot deliver the feature's whole point. Everything above depends on the
684
- outer view's `SELECT g.*` being re-resolved after the inner view regenerates — that is what makes a
685
- late-added foreign key appear on its own. SQL Server does that with `sp_refreshview`. PostgreSQL
686
- expands `*` into a fixed column list at creation and freezes it, has no refresh equivalent, and
687
- 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.
688
730
 
689
- The resulting behaviour would not even be consistently broken. Adding a column — the common case —
690
- leaves the outer view stale, because `CREATE OR REPLACE` on the inner view never touches dependents.
691
- Renaming a column or changing its type raises `42P16`, which sends CodeGen down its
692
- capture/`DROP CASCADE`/replay path; that incidentally recreates the outer view, which then *does*
693
- pick the new columns up. Same feature, opposite outcomes, decided by which kind of schema change
694
- happened to land that day. Since silent staleness is the exact failure layering exists to eliminate,
695
- 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.
696
737
 
697
- On PostgreSQL, use a fully custom base view (`BaseViewGenerated = 0`, `GeneratedBaseViewName` left
698
- `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.
699
740
 
700
741
  ### Setting it up
701
742
 
@@ -704,8 +745,10 @@ On PostgreSQL, use a fully custom base view (`BaseViewGenerated = 0`, `Generated
704
745
  `metadata/entities/.layered-base-views.json`.
705
746
  2. Run CodeGen. It writes the inner view.
706
747
  3. Create your `BaseView` in a migration that runs **after** CodeGen output, since it selects from the
707
- inner view — and may reference generated root-ID functions.
708
- 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.
709
752
 
710
753
  > ### ⚠️ Adopting layering on an EXISTING entity needs `forceRegeneration`
711
754
  >
@@ -880,7 +923,7 @@ The `CodeGenDatabaseProvider` is the abstract base class that encapsulates **all
880
923
  | Triggers | `generateTimestampTrigger` | Timestamp auto-update triggers |
881
924
  | Indexes | `generateForeignKeyIndexes` | Foreign key index generation |
882
925
  | Full-Text Search | `generateFullTextSearch` | Platform-specific FTS infrastructure |
883
- | Root ID Functions | `generateRootIDFunction`, `generateRootFieldSelect`, `generateRootFieldJoin` | Recursive hierarchy root ID calculation |
926
+ | Hierarchy TVFs & Views | `generateHierarchyMetaFunction`, `generateDescendantsFunction`, `generateAncestorsFunction`, `generateRootIDFunction`, `generateHierarchyFieldSelect`, `generateHierarchyFieldJoin` | Recursive hierarchy TVF suite & view join generation |
884
927
  | Permissions | `generateViewPermissions`, `generateCRUDPermissions`, `generateFullTextSearchPermissions` | GRANT statements per entity role |
885
928
  | Cascade Deletes | `generateSingleCascadeOperation` | Cascade delete/update-to-NULL operations |
886
929
  | Timestamp Columns | `generateTimestampColumns` | Adding __mj_CreatedAt/__mj_UpdatedAt columns |
@@ -974,6 +1017,9 @@ Generates an import manifest that prevents tree-shaking of `@RegisterClass` deco
974
1017
  | `outputDir(type, fallback)` | Get the configured output directory for a generator type |
975
1018
  | `getSettingValue(name, default)` | Get a named setting value from configuration |
976
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 |
977
1023
 
978
1024
  ## Dependencies
979
1025
 
@@ -283,14 +283,6 @@ export declare class AngularClientGeneratorBase {
283
283
  * @returns HTML string for all collapsible panels
284
284
  */
285
285
  protected innerCollapsiblePanelsHTML(additionalSections: AngularFormSectionInfo[], relatedEntitySections: AngularFormSectionInfo[]): string;
286
- /**
287
- * @deprecated Use innerCollapsiblePanelsHTML instead
288
- * Generates the HTML for the tab strip containing all form sections
289
- * @param additionalSections Array of field-based form sections
290
- * @param relatedEntitySections Array of related entity sections
291
- * @returns HTML string for the complete tab strip
292
- */
293
- protected innerTabStripHTML(additionalSections: AngularFormSectionInfo[], relatedEntitySections: AngularFormSectionInfo[]): string;
294
286
  /**
295
287
  * Generates HTML without a splitter layout for entities without a top area
296
288
  * @param topArea HTML for the top area section (expected to be empty)
@@ -1 +1 @@
1
- {"version":3,"file":"angular-codegen.d.ts","sourceRoot":"","sources":["../../src/Angular/angular-codegen.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"angular-codegen.d.ts","sourceRoot":"","sources":["../../src/Angular/angular-codegen.ts"],"names":[],"mappings":"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"}
@@ -3,9 +3,23 @@ import { logError, logStatus } from '../Misc/status_logging.js';
3
3
  import { UUIDsEqual } from '@memberjunction/global';
4
4
  import fs from 'fs';
5
5
  import path from 'path';
6
- import { mjCoreSchema, outputOptionValue, resolveEntityPackageName } from '../Config/config.js';
6
+ import { mjCoreSchema, outputOptionValue, configInfo, resolveEntityPackageName } from '../Config/config.js';
7
7
  import { RelatedEntityDisplayComponentGeneratorBase } from './related-entity-components.js';
8
8
  import { sortBySequenceAndCreatedAt, sortRelatedEntities } from '../Misc/util.js';
9
+ /**
10
+ * Schemas whose entities should not appear as related-entity form tabs.
11
+ *
12
+ * `excludeSchemas` defaults include `__mj` so CodeGen does not emit core
13
+ * entity *files* into a downstream package. Those entities still exist at
14
+ * runtime via `@memberjunction/core-entities`, so filtering them here
15
+ * silently dropped core-entity tabs for every default config.
16
+ */
17
+ function schemasExcludedFromGeneratedForms() {
18
+ const core = String(mjCoreSchema ?? '__mj').toLowerCase();
19
+ return new Set((configInfo.excludeSchemas || [])
20
+ .map(s => s.toLowerCase())
21
+ .filter(s => s !== core && s !== '__mj'));
22
+ }
9
23
  /**
10
24
  * Represents metadata about an Angular form section that is generated for an entity
11
25
  */
@@ -723,8 +737,18 @@ ${indentedFormHTML}
723
737
  // IS-A child entity IDs — these are shown in the toolbar breadcrumb and
724
738
  // can only have 0 or 1 records (disjoint subtypes), so a grid panel is redundant
725
739
  const isaChildIDs = new Set(entity.ChildEntities.map(c => c.ID));
740
+ const excludedSchemas = schemasExcludedFromGeneratedForms();
726
741
  // Sort related entities deterministically using the shared sort with cascading tiebreakers
727
- const sortedRelatedEntities = sortRelatedEntities(entity.RelatedEntities.filter(re => re.DisplayInForm && !isaChildIDs.has(re.RelatedEntityID)));
742
+ const sortedRelatedEntities = sortRelatedEntities(entity.RelatedEntities.filter(re => {
743
+ if (!re.DisplayInForm || isaChildIDs.has(re.RelatedEntityID)) {
744
+ return false;
745
+ }
746
+ const targetEntity = md.Entities.find(e => UUIDsEqual(e.ID, re.RelatedEntityID));
747
+ if (targetEntity && excludedSchemas.has(targetEntity.SchemaName.toLowerCase())) {
748
+ return false;
749
+ }
750
+ return true;
751
+ }));
728
752
  let index = startIndex;
729
753
  for (const relatedEntity of sortedRelatedEntities) {
730
754
  const tabName = this.generateRelatedEntityTabName(relatedEntity, sortedRelatedEntities);
@@ -816,13 +840,17 @@ ${componentCodeWithIndent}
816
840
  if (!organicKeys || organicKeys.length === 0) {
817
841
  return tabs;
818
842
  }
843
+ const excludedSchemas = schemasExcludedFromGeneratedForms();
819
844
  let index = startIndex;
820
845
  for (const organicKey of organicKeys) {
821
846
  for (const relatedEntity of organicKey.RelatedEntities) {
847
+ const re = md.Entities.find(e => UUIDsEqual(e.ID, relatedEntity.RelatedEntityID));
848
+ if (re && excludedSchemas.has(re.SchemaName.toLowerCase())) {
849
+ continue;
850
+ }
822
851
  const tabName = relatedEntity.DisplayName || relatedEntity.RelatedEntity;
823
852
  // Determine icon from the related entity
824
853
  let iconClass = 'fa fa-link';
825
- const re = md.Entities.find(e => UUIDsEqual(e.ID, relatedEntity.RelatedEntityID));
826
854
  if (re && re.Icon && re.Icon.length > 0) {
827
855
  iconClass = re.Icon;
828
856
  }
@@ -835,7 +863,7 @@ ${componentCodeWithIndent}
835
863
  const template = `<mj-explorer-entity-data-grid
836
864
  [Params]="BuildOrganicKeyViewParamsByNames('${organicKey.Name.replace(/'/g, "\\'")}','${relatedEntity.RelatedEntity.replace(/'/g, "\\'")}')"
837
865
  [AllowLoad]="${allowLoadCheck}"
838
- [ShowToolbar]="false"
866
+ [ShowToolbar]="true"
839
867
  (Navigate)="OnFormNavigate($event)"
840
868
  ${afterDataLoadEvent}
841
869
  >
@@ -1119,24 +1147,6 @@ ${this.innerCollapsiblePanelsHTML(additionalSections, relatedEntitySections)}
1119
1147
  parts.push(slot('after-related'));
1120
1148
  return parts.join('\n');
1121
1149
  }
1122
- /**
1123
- * @deprecated Use innerCollapsiblePanelsHTML instead
1124
- * Generates the HTML for the tab strip containing all form sections
1125
- * @param additionalSections Array of field-based form sections
1126
- * @param relatedEntitySections Array of related entity sections
1127
- * @returns HTML string for the complete tab strip
1128
- */
1129
- innerTabStripHTML(additionalSections, relatedEntitySections) {
1130
- // come up with the overall order by looking for the tabs that have DisplayLocation === 'Before Field Tabs' and put those, in sequence order
1131
- // ahead of the additionalSections, then do the additionalSections, and then do the relatedEntitySections
1132
- const relatedEntityBeforeFieldTabs = relatedEntitySections.filter(s => s.RelatedEntityDisplayLocation === 'Before Field Tabs');
1133
- const relatedEntityAfterFieldTabs = relatedEntitySections.filter(s => s.RelatedEntityDisplayLocation === 'After Field Tabs');
1134
- return ` <mj-tabstrip (TabSelected)="onTabSelect($event)" (ResizeContainer)="InvokeManualResize()">
1135
- ${relatedEntityBeforeFieldTabs ? relatedEntityBeforeFieldTabs.map(s => s.TabCode).join('\n') : ''}
1136
- ${additionalSections ? additionalSections.filter(s => s.Type !== GeneratedFormSectionType.Top).map(s => s.TabCode).join('\n ') : ''}
1137
- ${relatedEntityAfterFieldTabs ? relatedEntityAfterFieldTabs.map(s => s.TabCode).join('\n') : ''}
1138
- </mj-tabstrip>`;
1139
- }
1140
1150
  /**
1141
1151
  * Generates HTML without a splitter layout for entities without a top area
1142
1152
  * @param topArea HTML for the top area section (expected to be empty)