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

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 (136) hide show
  1. package/README.md +20 -0
  2. package/dist/Angular/angular-codegen.d.ts +9 -6
  3. package/dist/Angular/angular-codegen.d.ts.map +1 -1
  4. package/dist/Angular/angular-codegen.js +80 -51
  5. package/dist/Angular/angular-codegen.js.map +1 -1
  6. package/dist/Angular/join-grid-related-entity-component.d.ts.map +1 -1
  7. package/dist/Angular/join-grid-related-entity-component.js +5 -2
  8. package/dist/Angular/join-grid-related-entity-component.js.map +1 -1
  9. package/dist/Angular/related-entity-components.d.ts +11 -0
  10. package/dist/Angular/related-entity-components.d.ts.map +1 -1
  11. package/dist/Angular/related-entity-components.js +23 -0
  12. package/dist/Angular/related-entity-components.js.map +1 -1
  13. package/dist/Angular/timeline-related-entity-component.d.ts.map +1 -1
  14. package/dist/Angular/timeline-related-entity-component.js +3 -2
  15. package/dist/Angular/timeline-related-entity-component.js.map +1 -1
  16. package/dist/Config/config.d.ts +216 -12
  17. package/dist/Config/config.d.ts.map +1 -1
  18. package/dist/Config/config.js +88 -6
  19. package/dist/Config/config.js.map +1 -1
  20. package/dist/Config/schema-output.d.ts +33 -0
  21. package/dist/Config/schema-output.d.ts.map +1 -0
  22. package/dist/Config/schema-output.js +52 -0
  23. package/dist/Config/schema-output.js.map +1 -0
  24. package/dist/Database/codeGenDatabaseProvider.d.ts +68 -1
  25. package/dist/Database/codeGenDatabaseProvider.d.ts.map +1 -1
  26. package/dist/Database/codeGenDatabaseProvider.js +142 -3
  27. package/dist/Database/codeGenDatabaseProvider.js.map +1 -1
  28. package/dist/Database/dbSchema.js +2 -1
  29. package/dist/Database/dbSchema.js.map +1 -1
  30. package/dist/Database/decision-metadata-format.d.ts +124 -0
  31. package/dist/Database/decision-metadata-format.d.ts.map +1 -0
  32. package/dist/Database/decision-metadata-format.js +279 -0
  33. package/dist/Database/decision-metadata-format.js.map +1 -0
  34. package/dist/Database/decision-metadata-writer.d.ts +48 -0
  35. package/dist/Database/decision-metadata-writer.d.ts.map +1 -0
  36. package/dist/Database/decision-metadata-writer.js +482 -0
  37. package/dist/Database/decision-metadata-writer.js.map +1 -0
  38. package/dist/Database/entity-field-change-tracking.d.ts +53 -0
  39. package/dist/Database/entity-field-change-tracking.d.ts.map +1 -0
  40. package/dist/Database/entity-field-change-tracking.js +120 -0
  41. package/dist/Database/entity-field-change-tracking.js.map +1 -0
  42. package/dist/Database/entity-level-tree-cycles.d.ts.map +1 -1
  43. package/dist/Database/entity-level-tree-cycles.js +3 -2
  44. package/dist/Database/entity-level-tree-cycles.js.map +1 -1
  45. package/dist/Database/exclude-tables.d.ts +26 -0
  46. package/dist/Database/exclude-tables.d.ts.map +1 -0
  47. package/dist/Database/exclude-tables.js +38 -0
  48. package/dist/Database/exclude-tables.js.map +1 -0
  49. package/dist/Database/field-metadata-lock.d.ts +47 -0
  50. package/dist/Database/field-metadata-lock.d.ts.map +1 -0
  51. package/dist/Database/field-metadata-lock.js +159 -0
  52. package/dist/Database/field-metadata-lock.js.map +1 -0
  53. package/dist/Database/manage-metadata.d.ts +142 -42
  54. package/dist/Database/manage-metadata.d.ts.map +1 -1
  55. package/dist/Database/manage-metadata.js +625 -287
  56. package/dist/Database/manage-metadata.js.map +1 -1
  57. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts +2 -2
  58. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.d.ts.map +1 -1
  59. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js +90 -41
  60. package/dist/Database/providers/postgresql/PostgreSQLCodeGenProvider.js.map +1 -1
  61. package/dist/Database/providers/postgresql/metadataSupportObjects.js +31 -8
  62. package/dist/Database/providers/postgresql/metadataSupportObjects.js.map +1 -1
  63. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts +3 -1
  64. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.d.ts.map +1 -1
  65. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js +58 -23
  66. package/dist/Database/providers/sqlserver/SQLServerCodeGenProvider.js.map +1 -1
  67. package/dist/Database/providers/sqlserver/__tests__/BaseViewEmissionGoldenMaster.test.js +15 -2
  68. package/dist/Database/providers/sqlserver/__tests__/BaseViewEmissionGoldenMaster.test.js.map +1 -1
  69. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.js +17 -0
  70. package/dist/Database/providers/sqlserver/__tests__/SQLServerCodeGenProvider.test.js.map +1 -1
  71. package/dist/Database/sql_codegen.d.ts +24 -0
  72. package/dist/Database/sql_codegen.d.ts.map +1 -1
  73. package/dist/Database/sql_codegen.js +108 -29
  74. package/dist/Database/sql_codegen.js.map +1 -1
  75. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts +22 -0
  76. package/dist/Manifest/GenerateClassRegistrationsManifest.d.ts.map +1 -1
  77. package/dist/Manifest/GenerateClassRegistrationsManifest.js +115 -7
  78. package/dist/Manifest/GenerateClassRegistrationsManifest.js.map +1 -1
  79. package/dist/Misc/action_subclasses_codegen.js +2 -2
  80. package/dist/Misc/action_subclasses_codegen.js.map +1 -1
  81. package/dist/Misc/advanced_generation.d.ts +7 -5
  82. package/dist/Misc/advanced_generation.d.ts.map +1 -1
  83. package/dist/Misc/advanced_generation.js +34 -23
  84. package/dist/Misc/advanced_generation.js.map +1 -1
  85. package/dist/Misc/codegen-reporter.d.ts +5 -0
  86. package/dist/Misc/codegen-reporter.d.ts.map +1 -1
  87. package/dist/Misc/codegen-reporter.js +9 -2
  88. package/dist/Misc/codegen-reporter.js.map +1 -1
  89. package/dist/Misc/emit-stats.d.ts +28 -0
  90. package/dist/Misc/emit-stats.d.ts.map +1 -0
  91. package/dist/Misc/emit-stats.js +43 -0
  92. package/dist/Misc/emit-stats.js.map +1 -0
  93. package/dist/Misc/entity_subclasses_codegen.d.ts +20 -2
  94. package/dist/Misc/entity_subclasses_codegen.d.ts.map +1 -1
  95. package/dist/Misc/entity_subclasses_codegen.js +120 -51
  96. package/dist/Misc/entity_subclasses_codegen.js.map +1 -1
  97. package/dist/Misc/file-write.d.ts +15 -0
  98. package/dist/Misc/file-write.d.ts.map +1 -0
  99. package/dist/Misc/file-write.js +33 -0
  100. package/dist/Misc/file-write.js.map +1 -0
  101. package/dist/Misc/graphql_server_codegen.d.ts +12 -2
  102. package/dist/Misc/graphql_server_codegen.d.ts.map +1 -1
  103. package/dist/Misc/graphql_server_codegen.js +72 -16
  104. package/dist/Misc/graphql_server_codegen.js.map +1 -1
  105. package/dist/Misc/remote_operations_codegen.d.ts.map +1 -1
  106. package/dist/Misc/remote_operations_codegen.js +4 -3
  107. package/dist/Misc/remote_operations_codegen.js.map +1 -1
  108. package/dist/Misc/runCommand.d.ts +5 -0
  109. package/dist/Misc/runCommand.d.ts.map +1 -1
  110. package/dist/Misc/runCommand.js +43 -17
  111. package/dist/Misc/runCommand.js.map +1 -1
  112. package/dist/Misc/schema-emit.d.ts +123 -0
  113. package/dist/Misc/schema-emit.d.ts.map +1 -0
  114. package/dist/Misc/schema-emit.js +221 -0
  115. package/dist/Misc/schema-emit.js.map +1 -0
  116. package/dist/Misc/sql_logging.d.ts +63 -8
  117. package/dist/Misc/sql_logging.d.ts.map +1 -1
  118. package/dist/Misc/sql_logging.js +169 -42
  119. package/dist/Misc/sql_logging.js.map +1 -1
  120. package/dist/Misc/util.d.ts +12 -0
  121. package/dist/Misc/util.d.ts.map +1 -1
  122. package/dist/Misc/util.js +71 -8
  123. package/dist/Misc/util.js.map +1 -1
  124. package/dist/index.d.ts +8 -0
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +8 -0
  127. package/dist/index.js.map +1 -1
  128. package/dist/plugins/index.d.ts +3 -0
  129. package/dist/plugins/index.d.ts.map +1 -1
  130. package/dist/plugins/index.js +28 -1
  131. package/dist/plugins/index.js.map +1 -1
  132. package/dist/runCodeGen.d.ts +20 -2
  133. package/dist/runCodeGen.d.ts.map +1 -1
  134. package/dist/runCodeGen.js +186 -33
  135. package/dist/runCodeGen.js.map +1 -1
  136. package/package.json +29 -29
@@ -0,0 +1,120 @@
1
+ import { ordinalCompare } from '@memberjunction/global';
2
+ /** Columns the schema sync may rewrite. `Sequence` is deliberately absent: a renumber is not a change (FM3). */
3
+ export const TRACKED_FIELD_COLUMNS = [
4
+ 'Description',
5
+ 'Type',
6
+ 'Length',
7
+ 'Precision',
8
+ 'Scale',
9
+ 'AllowsNull',
10
+ 'DefaultValue',
11
+ 'AutoIncrement',
12
+ 'IsVirtual',
13
+ 'IsComputed',
14
+ 'RelatedEntityID',
15
+ 'RelatedEntityFieldName',
16
+ 'IsPrimaryKey',
17
+ 'IsUnique',
18
+ 'AllowUpdateAPI',
19
+ ];
20
+ /** Reasons that re-open DisplayName (§3.4). */
21
+ export const DISPLAYNAME_REOPEN_REASONS = new Set(['Description']);
22
+ /** Reasons that re-open the type-derived columns (§3.4). */
23
+ export const TYPE_REOPEN_REASONS = new Set(['Type', 'Length', 'Precision', 'Scale', 'AllowsNull']);
24
+ /**
25
+ * Normalizes a field value according to column comparison semantics:
26
+ * - Description, DefaultValue, RelatedEntityFieldName: trimmed strings, null ≡ ''
27
+ * - RelatedEntityID: trimmed, lowercased, null ≡ ''
28
+ * - Boolean/bit columns: coerced with Boolean()
29
+ * - Numbers: number or null
30
+ * - Strings: trimmed
31
+ */
32
+ export function normalizeSnapshotValue(column, value) {
33
+ if (column === 'Description' || column === 'DefaultValue' || column === 'RelatedEntityFieldName') {
34
+ if (value === null || value === undefined)
35
+ return '';
36
+ return String(value).trim();
37
+ }
38
+ if (column === 'RelatedEntityID') {
39
+ if (value === null || value === undefined)
40
+ return '';
41
+ return String(value).trim().toLowerCase();
42
+ }
43
+ if (column === 'AllowsNull' ||
44
+ column === 'AutoIncrement' ||
45
+ column === 'IsVirtual' ||
46
+ column === 'IsComputed' ||
47
+ column === 'IsPrimaryKey' ||
48
+ column === 'IsUnique' ||
49
+ column === 'AllowUpdateAPI') {
50
+ if (value === null || value === undefined)
51
+ return false;
52
+ if (typeof value === 'boolean')
53
+ return value;
54
+ if (typeof value === 'number')
55
+ return value !== 0;
56
+ if (typeof value === 'string') {
57
+ const s = value.trim().toLowerCase();
58
+ return s === '1' || s === 'true';
59
+ }
60
+ return Boolean(value);
61
+ }
62
+ if (column === 'Length' || column === 'Precision' || column === 'Scale') {
63
+ if (value === null || value === undefined || value === '')
64
+ return null;
65
+ const n = Number(value);
66
+ return isNaN(n) ? null : n;
67
+ }
68
+ if (column === 'Type') {
69
+ if (value === null || value === undefined)
70
+ return '';
71
+ return String(value).trim();
72
+ }
73
+ return value;
74
+ }
75
+ /**
76
+ * Compares before and after snapshots of EntityField rows.
77
+ * Rows keyed by ID. A row only in `after` is new this run and is not a change;
78
+ * `isNew` excludes the INSERT sites' rows too.
79
+ * A row only in `before` was deleted and is ignored.
80
+ * Returns changes sorted by entityName then fieldName using ordinalCompare.
81
+ */
82
+ export function diffEntityFieldSnapshots(before, after, isNew) {
83
+ const changes = [];
84
+ for (const [id, afterRow] of after) {
85
+ const beforeRow = before.get(id);
86
+ if (!beforeRow) {
87
+ // Present only in after -> newly inserted this run, not a modification
88
+ continue;
89
+ }
90
+ if (isNew(afterRow.EntityID, afterRow.Name)) {
91
+ // Explicitly registered as a new field this run
92
+ continue;
93
+ }
94
+ const reasons = [];
95
+ for (const col of TRACKED_FIELD_COLUMNS) {
96
+ const bVal = normalizeSnapshotValue(col, beforeRow[col]);
97
+ const aVal = normalizeSnapshotValue(col, afterRow[col]);
98
+ if (bVal !== aVal) {
99
+ reasons.push(col);
100
+ }
101
+ }
102
+ if (reasons.length > 0) {
103
+ changes.push({
104
+ entityID: afterRow.EntityID,
105
+ entityName: afterRow.EntityName,
106
+ fieldID: afterRow.ID,
107
+ fieldName: afterRow.Name,
108
+ reasons,
109
+ });
110
+ }
111
+ }
112
+ // Sort output by entityName, then fieldName, using ordinalCompare (C5)
113
+ return changes.sort((a, b) => {
114
+ const entityCmp = ordinalCompare(a.entityName, b.entityName);
115
+ if (entityCmp !== 0)
116
+ return entityCmp;
117
+ return ordinalCompare(a.fieldName, b.fieldName);
118
+ });
119
+ }
120
+ //# sourceMappingURL=entity-field-change-tracking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-field-change-tracking.js","sourceRoot":"","sources":["../../src/Database/entity-field-change-tracking.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"entity-level-tree-cycles.d.ts","sourceRoot":"","sources":["../../src/Database/entity-level-tree-cycles.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,EAAE,CAKlF"}
1
+ {"version":3,"file":"entity-level-tree-cycles.d.ts","sourceRoot":"","sources":["../../src/Database/entity-level-tree-cycles.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,MAAM,EAAE,EAAE,CAKlF"}
@@ -3,6 +3,7 @@
3
3
  * cyclical-dependency diagnostic. Kept free of any CodeGen/config imports so the logic is
4
4
  * trivially unit-testable with plain `Map` fixtures.
5
5
  */
6
+ import { ordinalCompare } from '@memberjunction/global';
6
7
  /**
7
8
  * Finds the true cyclical groups within a dependency graph by computing the strongly
8
9
  * connected components (Tarjan's algorithm) and returning only those with more than one
@@ -20,8 +21,8 @@
20
21
  export function FindTrueCycles(dependencyMap) {
21
22
  return computeStronglyConnectedComponents(dependencyMap)
22
23
  .filter(component => component.length > 1)
23
- .map(component => [...component].sort((a, b) => a.localeCompare(b)))
24
- .sort((a, b) => a[0].localeCompare(b[0]));
24
+ .map(component => [...component].sort((a, b) => ordinalCompare(a, b)))
25
+ .sort((a, b) => ordinalCompare(a[0], b[0]));
25
26
  }
26
27
  /**
27
28
  * Tarjan's strongly connected components over the given adjacency map.
@@ -1 +1 @@
1
- {"version":3,"file":"entity-level-tree-cycles.js","sourceRoot":"","sources":["../../src/Database/entity-level-tree-cycles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"entity-level-tree-cycles.js","sourceRoot":"","sources":["../../src/Database/entity-level-tree-cycles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Normalize `excludeTables` config entries into `{ schema, table }` pairs.
3
+ *
4
+ * The historical shape is an object. Operators on large brownfield databases also
5
+ * want a one-line string — `'Aptify.EntityRecordVersions'`, `'%.%History'`,
6
+ * `'%Audit%'` — so a 49-million-row audit table can be skipped without hunting
7
+ * through a JSON object. Both forms compile to the same LIKE/equals predicate
8
+ * that `createExcludeTablesAndSchemasFilter` already emits.
9
+ *
10
+ * String grammar:
11
+ * - `'schema.table'` → exact (or wildcard) schema + table. The last `.` splits.
12
+ * - `'%.%History'` → any schema, table LIKE `%History`
13
+ * - `'%Audit%'` → any schema (`%`), table LIKE `%Audit%`
14
+ * - `'EntityRecordVersions'` → any schema, that exact table name
15
+ */
16
+ export type ExcludeTableEntry = {
17
+ schema: string;
18
+ table: string;
19
+ };
20
+ /**
21
+ * Parse one `excludeTables` entry — object or `'schema.table'` / table-only string —
22
+ * into the `{ schema, table }` pair the SQL filter already understands. Wildcards
23
+ * (`%`) are preserved; they are not expanded here.
24
+ */
25
+ export declare function parseExcludeTableEntry(entry: string | ExcludeTableEntry): ExcludeTableEntry;
26
+ //# sourceMappingURL=exclude-tables.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclude-tables.d.ts","sourceRoot":"","sources":["../../src/Database/exclude-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,iBAAiB,GAAG,iBAAiB,CAgB3F"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Normalize `excludeTables` config entries into `{ schema, table }` pairs.
3
+ *
4
+ * The historical shape is an object. Operators on large brownfield databases also
5
+ * want a one-line string — `'Aptify.EntityRecordVersions'`, `'%.%History'`,
6
+ * `'%Audit%'` — so a 49-million-row audit table can be skipped without hunting
7
+ * through a JSON object. Both forms compile to the same LIKE/equals predicate
8
+ * that `createExcludeTablesAndSchemasFilter` already emits.
9
+ *
10
+ * String grammar:
11
+ * - `'schema.table'` → exact (or wildcard) schema + table. The last `.` splits.
12
+ * - `'%.%History'` → any schema, table LIKE `%History`
13
+ * - `'%Audit%'` → any schema (`%`), table LIKE `%Audit%`
14
+ * - `'EntityRecordVersions'` → any schema, that exact table name
15
+ */
16
+ /**
17
+ * Parse one `excludeTables` entry — object or `'schema.table'` / table-only string —
18
+ * into the `{ schema, table }` pair the SQL filter already understands. Wildcards
19
+ * (`%`) are preserved; they are not expanded here.
20
+ */
21
+ export function parseExcludeTableEntry(entry) {
22
+ if (typeof entry !== 'string') {
23
+ return { schema: entry.schema, table: entry.table };
24
+ }
25
+ const trimmed = entry.trim();
26
+ if (trimmed.length === 0) {
27
+ throw new Error('excludeTables entry cannot be empty');
28
+ }
29
+ const lastDot = trimmed.lastIndexOf('.');
30
+ if (lastDot > 0 && lastDot < trimmed.length - 1) {
31
+ return {
32
+ schema: trimmed.slice(0, lastDot).trim(),
33
+ table: trimmed.slice(lastDot + 1).trim(),
34
+ };
35
+ }
36
+ return { schema: '%', table: trimmed };
37
+ }
38
+ //# sourceMappingURL=exclude-tables.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exclude-tables.js","sourceRoot":"","sources":["../../src/Database/exclude-tables.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAiC;IACtE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC;IACtD,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IACD,MAAM,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,OAAO;YACL,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE;YACxC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE;SACzC,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Pure decision function for field metadata updates (Category, GeneratedFormSection,
3
+ * DisplayName, ExtendedType, CodeType).
4
+ *
5
+ * Implements the normative per-column lock table from plan §3.2.
6
+ * All decisions are pure functions of current field state, proposed values, and lock context.
7
+ */
8
+ export interface FieldLockContext {
9
+ isNewEntity: boolean;
10
+ isNewField: boolean;
11
+ descriptionReopened: boolean;
12
+ typeReopened: boolean;
13
+ existingCategories: ReadonlySet<string>;
14
+ }
15
+ export interface FieldMetadataState {
16
+ ID: string;
17
+ Name: string;
18
+ Category: string | null;
19
+ GeneratedFormSection: string | null;
20
+ DisplayName: string | null;
21
+ ExtendedType: string | null;
22
+ CodeType: string | null;
23
+ AutoUpdateCategory: boolean;
24
+ AutoUpdateDisplayName: boolean;
25
+ AutoUpdateExtendedType: boolean;
26
+ ValueListType?: string | null;
27
+ }
28
+ export interface FieldMetadataProposal {
29
+ category?: string | null;
30
+ displayName?: string | null;
31
+ extendedType?: string | null;
32
+ codeType?: string | null;
33
+ }
34
+ export type SkipReason = 'locked' | 'flag' | 'invalid' | 'unchanged' | 'blank-proposal';
35
+ export interface FieldMetadataUpdate {
36
+ Category?: string;
37
+ GeneratedFormSection?: 'Category';
38
+ DisplayName?: string;
39
+ ExtendedType?: string | null;
40
+ CodeType?: string | null;
41
+ skipped: Array<{
42
+ column: string;
43
+ reason: SkipReason;
44
+ }>;
45
+ }
46
+ export declare function computeFieldMetadataUpdate(field: FieldMetadataState, proposal: FieldMetadataProposal, ctx: FieldLockContext, validateExtendedType: (v: string) => string | null, sanitizeCodeType: (v: string | null | undefined, fieldName?: string, entityName?: string) => string | null | undefined): FieldMetadataUpdate;
47
+ //# sourceMappingURL=field-metadata-lock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-metadata-lock.d.ts","sourceRoot":"","sources":["../../src/Database/field-metadata-lock.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,WAAW,gBAAgB;IAC9B,WAAW,EAAE,OAAO,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,EAAE,OAAO,CAAC;IACtB,kBAAkB,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,kBAAkB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,sBAAsB,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACnC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,WAAW,GAAG,gBAAgB,CAAC;AAExF,MAAM,WAAW,mBAAmB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oBAAoB,CAAC,EAAE,UAAU,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,wBAAgB,0BAA0B,CACvC,KAAK,EAAE,kBAAkB,EACzB,QAAQ,EAAE,qBAAqB,EAC/B,GAAG,EAAE,gBAAgB,EACrB,oBAAoB,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,EAClD,gBAAgB,EAAE,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,GACtH,mBAAmB,CA4IrB"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Pure decision function for field metadata updates (Category, GeneratedFormSection,
3
+ * DisplayName, ExtendedType, CodeType).
4
+ *
5
+ * Implements the normative per-column lock table from plan §3.2.
6
+ * All decisions are pure functions of current field state, proposed values, and lock context.
7
+ */
8
+ export function computeFieldMetadataUpdate(field, proposal, ctx, validateExtendedType, sanitizeCodeType) {
9
+ const update = {
10
+ skipped: [],
11
+ };
12
+ // ──────────────────────────────────────────────────────────────────────────
13
+ // 1. Category & GeneratedFormSection
14
+ // ──────────────────────────────────────────────────────────────────────────
15
+ // Override category for system metadata audit fields (__mj_*)
16
+ const rawProposedCategory = field.Name.startsWith('__mj_')
17
+ ? 'System Metadata'
18
+ : proposal.category;
19
+ if (!field.AutoUpdateCategory) {
20
+ update.skipped.push({ column: 'Category', reason: 'flag' });
21
+ }
22
+ else {
23
+ const isCurrentCategoryBlank = !field.Category || field.Category.trim() === '';
24
+ const isAllowedToCategorize = isCurrentCategoryBlank || ctx.isNewEntity;
25
+ if (!isAllowedToCategorize) {
26
+ // Existing non-blank category on an existing entity: locked, never moves even between existing categories
27
+ update.skipped.push({ column: 'Category', reason: 'locked' });
28
+ }
29
+ else {
30
+ if (!rawProposedCategory || rawProposedCategory.trim() === '') {
31
+ update.skipped.push({ column: 'Category', reason: 'blank-proposal' });
32
+ }
33
+ else {
34
+ const trimmedProposed = rawProposedCategory.trim();
35
+ if (trimmedProposed === (field.Category ?? '').trim()) {
36
+ update.skipped.push({ column: 'Category', reason: 'unchanged' });
37
+ }
38
+ else {
39
+ update.Category = trimmedProposed;
40
+ // GeneratedFormSection is only emitted when Category is emitted
41
+ if (field.GeneratedFormSection !== 'Category') {
42
+ update.GeneratedFormSection = 'Category';
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ // ──────────────────────────────────────────────────────────────────────────
49
+ // 2. DisplayName
50
+ // ──────────────────────────────────────────────────────────────────────────
51
+ if (!field.AutoUpdateDisplayName) {
52
+ update.skipped.push({ column: 'DisplayName', reason: 'flag' });
53
+ }
54
+ else {
55
+ const isAllowedDisplayName = ctx.isNewEntity || ctx.isNewField || ctx.descriptionReopened;
56
+ if (!isAllowedDisplayName) {
57
+ update.skipped.push({ column: 'DisplayName', reason: 'locked' });
58
+ }
59
+ else {
60
+ if (!proposal.displayName || proposal.displayName.trim() === '') {
61
+ update.skipped.push({ column: 'DisplayName', reason: 'blank-proposal' });
62
+ }
63
+ else {
64
+ const trimmedProposal = proposal.displayName.trim();
65
+ if (trimmedProposal === (field.DisplayName ?? '').trim()) {
66
+ update.skipped.push({ column: 'DisplayName', reason: 'unchanged' });
67
+ }
68
+ else {
69
+ update.DisplayName = trimmedProposal;
70
+ }
71
+ }
72
+ }
73
+ }
74
+ // ──────────────────────────────────────────────────────────────────────────
75
+ // 3. ExtendedType
76
+ // ──────────────────────────────────────────────────────────────────────────
77
+ if (!field.AutoUpdateExtendedType) {
78
+ update.skipped.push({ column: 'ExtendedType', reason: 'flag' });
79
+ }
80
+ else {
81
+ const isAllowedExtendedType = ctx.isNewEntity || ctx.isNewField || ctx.typeReopened;
82
+ if (!isAllowedExtendedType) {
83
+ update.skipped.push({ column: 'ExtendedType', reason: 'locked' });
84
+ }
85
+ else {
86
+ if (proposal.extendedType === undefined) {
87
+ update.skipped.push({ column: 'ExtendedType', reason: 'blank-proposal' });
88
+ }
89
+ else if (proposal.extendedType === null ||
90
+ proposal.extendedType.trim() === '' ||
91
+ proposal.extendedType.trim().toLowerCase() === 'null') {
92
+ if (field.ExtendedType === null) {
93
+ update.skipped.push({ column: 'ExtendedType', reason: 'unchanged' });
94
+ }
95
+ else {
96
+ update.ExtendedType = null;
97
+ }
98
+ }
99
+ else {
100
+ const valid = validateExtendedType(proposal.extendedType.trim());
101
+ const normalizedValueListType = (field.ValueListType || '').trim().toLowerCase();
102
+ const isValueList = normalizedValueListType !== '' && normalizedValueListType !== 'none';
103
+ if (!valid || (valid === 'Code' && isValueList)) {
104
+ update.skipped.push({ column: 'ExtendedType', reason: 'invalid' });
105
+ }
106
+ else {
107
+ if (valid === field.ExtendedType) {
108
+ update.skipped.push({ column: 'ExtendedType', reason: 'unchanged' });
109
+ }
110
+ else {
111
+ update.ExtendedType = valid;
112
+ }
113
+ }
114
+ }
115
+ }
116
+ }
117
+ // ──────────────────────────────────────────────────────────────────────────
118
+ // 4. CodeType (governed by AutoUpdateExtendedType; D6)
119
+ // ──────────────────────────────────────────────────────────────────────────
120
+ if (!field.AutoUpdateExtendedType) {
121
+ update.skipped.push({ column: 'CodeType', reason: 'flag' });
122
+ }
123
+ else {
124
+ const isAllowedCodeType = ctx.isNewEntity || ctx.isNewField || ctx.typeReopened;
125
+ if (!isAllowedCodeType) {
126
+ update.skipped.push({ column: 'CodeType', reason: 'locked' });
127
+ }
128
+ else {
129
+ // Determine effective extended type after step 3
130
+ const effectiveExtendedType = 'ExtendedType' in update ? update.ExtendedType : field.ExtendedType;
131
+ if (effectiveExtendedType !== 'Code') {
132
+ // CodeType MUST be null when ExtendedType is not Code
133
+ if (field.CodeType === null) {
134
+ update.skipped.push({ column: 'CodeType', reason: 'unchanged' });
135
+ }
136
+ else {
137
+ update.CodeType = null;
138
+ }
139
+ }
140
+ else {
141
+ if (proposal.codeType === undefined) {
142
+ update.skipped.push({ column: 'CodeType', reason: 'blank-proposal' });
143
+ }
144
+ else {
145
+ const sanitized = sanitizeCodeType(proposal.codeType, field.Name);
146
+ const resolvedCodeType = sanitized ?? null;
147
+ if (resolvedCodeType === field.CodeType) {
148
+ update.skipped.push({ column: 'CodeType', reason: 'unchanged' });
149
+ }
150
+ else {
151
+ update.CodeType = resolvedCodeType;
152
+ }
153
+ }
154
+ }
155
+ }
156
+ }
157
+ return update;
158
+ }
159
+ //# sourceMappingURL=field-metadata-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"field-metadata-lock.js","sourceRoot":"","sources":["../../src/Database/field-metadata-lock.ts"],"names":[],"mappings":"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"}