@memberjunction/integration-schema-builder 0.0.1 → 5.9.0

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 (42) hide show
  1. package/dist/AccessControl.d.ts +26 -0
  2. package/dist/AccessControl.d.ts.map +1 -0
  3. package/dist/AccessControl.js +68 -0
  4. package/dist/AccessControl.js.map +1 -0
  5. package/dist/DDLGenerator.d.ts +37 -0
  6. package/dist/DDLGenerator.d.ts.map +1 -0
  7. package/dist/DDLGenerator.js +155 -0
  8. package/dist/DDLGenerator.js.map +1 -0
  9. package/dist/MetadataEmitter.d.ts +23 -0
  10. package/dist/MetadataEmitter.d.ts.map +1 -0
  11. package/dist/MetadataEmitter.js +52 -0
  12. package/dist/MetadataEmitter.js.map +1 -0
  13. package/dist/MigrationFileWriter.d.ts +25 -0
  14. package/dist/MigrationFileWriter.d.ts.map +1 -0
  15. package/dist/MigrationFileWriter.js +67 -0
  16. package/dist/MigrationFileWriter.js.map +1 -0
  17. package/dist/SchemaBuilder.d.ts +27 -0
  18. package/dist/SchemaBuilder.d.ts.map +1 -0
  19. package/dist/SchemaBuilder.js +177 -0
  20. package/dist/SchemaBuilder.js.map +1 -0
  21. package/dist/SchemaEvolution.d.ts +27 -0
  22. package/dist/SchemaEvolution.d.ts.map +1 -0
  23. package/dist/SchemaEvolution.js +91 -0
  24. package/dist/SchemaEvolution.js.map +1 -0
  25. package/dist/SoftFKConfigEmitter.d.ts +53 -0
  26. package/dist/SoftFKConfigEmitter.d.ts.map +1 -0
  27. package/dist/SoftFKConfigEmitter.js +140 -0
  28. package/dist/SoftFKConfigEmitter.js.map +1 -0
  29. package/dist/TypeMapper.d.ts +25 -0
  30. package/dist/TypeMapper.d.ts.map +1 -0
  31. package/dist/TypeMapper.js +72 -0
  32. package/dist/TypeMapper.js.map +1 -0
  33. package/dist/index.d.ts +10 -0
  34. package/dist/index.d.ts.map +1 -0
  35. package/dist/index.js +11 -0
  36. package/dist/index.js.map +1 -0
  37. package/dist/interfaces.d.ts +182 -0
  38. package/dist/interfaces.d.ts.map +1 -0
  39. package/dist/interfaces.js +8 -0
  40. package/dist/interfaces.js.map +1 -0
  41. package/package.json +28 -7
  42. package/README.md +0 -45
@@ -0,0 +1,177 @@
1
+ import { DDLGenerator } from './DDLGenerator.js';
2
+ import { MigrationFileWriter } from './MigrationFileWriter.js';
3
+ import { SoftFKConfigEmitter } from './SoftFKConfigEmitter.js';
4
+ import { MetadataEmitter } from './MetadataEmitter.js';
5
+ import { SchemaEvolution } from './SchemaEvolution.js';
6
+ import { IsIntegrationWriteAllowed } from './AccessControl.js';
7
+ /**
8
+ * Main entry point for the Integration Schema Builder.
9
+ * Coordinates DDL generation, soft FK emission, metadata emission, and evolution diffs.
10
+ */
11
+ export class SchemaBuilder {
12
+ constructor() {
13
+ this.DDL = new DDLGenerator();
14
+ this.MigrationWriter = new MigrationFileWriter();
15
+ this.SoftFKEmitter = new SoftFKConfigEmitter();
16
+ this.MetaEmitter = new MetadataEmitter();
17
+ this.Evolution = new SchemaEvolution();
18
+ }
19
+ /**
20
+ * Build all artifacts for a set of integration target tables.
21
+ */
22
+ BuildSchema(input) {
23
+ const output = {
24
+ MigrationFiles: [],
25
+ AdditionalSchemaInfoUpdate: null,
26
+ MetadataFiles: [],
27
+ Warnings: [],
28
+ Errors: [],
29
+ };
30
+ // Step 1: Validate access control
31
+ const accessErrors = this.ValidateAccessControl(input);
32
+ if (accessErrors.length > 0) {
33
+ output.Errors.push(...accessErrors);
34
+ return output;
35
+ }
36
+ // Step 2: Pre-flight collision checks
37
+ const collisionWarnings = this.CheckCollisions(input);
38
+ output.Warnings.push(...collisionWarnings);
39
+ // Step 3: Separate new tables vs evolution
40
+ const { newConfigs, evolutionConfigs } = this.ClassifyConfigs(input);
41
+ // Step 4: Generate DDL — one migration file per integration
42
+ const now = new Date();
43
+ const ddlParts = [];
44
+ // Schema creation statements (deduplicate by schema name)
45
+ const schemasToCreate = this.GetUniqueSchemas(newConfigs);
46
+ for (const schemaName of schemasToCreate) {
47
+ ddlParts.push(this.DDL.GenerateCreateSchema(schemaName, input.Platform));
48
+ ddlParts.push(''); // blank line separator
49
+ }
50
+ // Table creation statements
51
+ for (const config of newConfigs) {
52
+ ddlParts.push(this.DDL.GenerateCreateTable(config, input.Platform));
53
+ ddlParts.push(''); // blank line separator
54
+ }
55
+ // Evolution statements (ALTER TABLE)
56
+ for (const { config, existing } of evolutionConfigs) {
57
+ const sourceObj = input.SourceSchema.Objects.find(o => o.ExternalName === config.SourceObjectName);
58
+ if (!sourceObj)
59
+ continue;
60
+ const diff = this.Evolution.DiffSchema(sourceObj, config, existing, input.Platform);
61
+ if (diff.AddedColumns.length === 0 && diff.ModifiedColumns.length === 0 && diff.RemovedColumns.length === 0) {
62
+ continue; // No changes
63
+ }
64
+ ddlParts.push(this.Evolution.GenerateEvolutionMigration(diff, config.SchemaName, config.TableName, input.Platform));
65
+ ddlParts.push(''); // blank line separator
66
+ }
67
+ // Emit a single migration file if there's any DDL
68
+ if (ddlParts.some(p => p.trim().length > 0)) {
69
+ const tableNames = [
70
+ ...newConfigs.map(c => c.TableName),
71
+ ...evolutionConfigs.map(({ config }) => config.TableName),
72
+ ];
73
+ const action = newConfigs.length > 0 ? 'CreateTables' : 'AlterTables';
74
+ const meta = this.MakeMigrationMeta(input, action, tableNames.join(', '));
75
+ const timestamps = this.MigrationWriter.GenerateTimestampSequence(1, now);
76
+ const filePath = this.MigrationWriter.GenerateMigrationFileName(input.SourceType, action, input.MJVersion, input.MigrationsDir, timestamps[0]);
77
+ output.MigrationFiles = [this.MigrationWriter.WrapInMigrationFile(ddlParts.join('\n'), meta, filePath)];
78
+ }
79
+ // Step 5: Generate soft PK and FK config
80
+ const allConfigs = [...newConfigs, ...evolutionConfigs.map(ec => ec.config)];
81
+ const allSoftFKs = this.CollectSoftFKs(input, evolutionConfigs);
82
+ // Always emit additionalSchemaInfo — every integration table needs a soft PK
83
+ if (allConfigs.length > 0) {
84
+ const existingConfig = this.SoftFKEmitter.ParseExistingConfig(null); // Caller provides existing content via input
85
+ // First add soft PKs (natural PK field names from source system)
86
+ const withPKs = this.SoftFKEmitter.MergeSoftPKs(existingConfig, allConfigs);
87
+ // Then merge in soft FKs
88
+ const merged = allSoftFKs.length > 0
89
+ ? this.SoftFKEmitter.MergeSchemaConfig(withPKs, allSoftFKs)
90
+ : withPKs;
91
+ output.AdditionalSchemaInfoUpdate = this.SoftFKEmitter.EmitConfigFile(input.AdditionalSchemaInfoPath, merged);
92
+ }
93
+ // Step 6: Generate metadata files for __mj entity targets
94
+ const mjTargets = input.TargetConfigs.filter(c => c.SchemaName === '__mj');
95
+ if (mjTargets.length > 0) {
96
+ const entityNames = mjTargets.map(c => c.EntityName);
97
+ output.MetadataFiles.push(this.MetaEmitter.EmitEntitySettingsFile(entityNames, input.MetadataDir));
98
+ output.MetadataFiles.push(this.MetaEmitter.EmitMjSyncConfig(input.MetadataDir));
99
+ }
100
+ return output;
101
+ }
102
+ ValidateAccessControl(input) {
103
+ const errors = [];
104
+ for (const config of input.TargetConfigs) {
105
+ if (config.SchemaName === '__mj') {
106
+ const settings = input.EntitySettingsForTargets[config.EntityName] ?? [];
107
+ const result = IsIntegrationWriteAllowed(config.EntityName, config.SchemaName, settings);
108
+ if (!result.Allowed) {
109
+ errors.push(result.Reason);
110
+ }
111
+ }
112
+ }
113
+ return errors;
114
+ }
115
+ CheckCollisions(input) {
116
+ const warnings = [];
117
+ const existingNames = new Set(input.ExistingTables.map(t => `${t.SchemaName}.${t.TableName}`.toLowerCase()));
118
+ for (const config of input.TargetConfigs) {
119
+ const key = `${config.SchemaName}.${config.TableName}`.toLowerCase();
120
+ if (existingNames.has(key)) {
121
+ // Not necessarily an error — could be an evolution scenario
122
+ warnings.push(`Table ${config.SchemaName}.${config.TableName} already exists — will generate ALTER TABLE if fields differ.`);
123
+ }
124
+ }
125
+ return warnings;
126
+ }
127
+ ClassifyConfigs(input) {
128
+ const existingMap = new Map();
129
+ for (const t of input.ExistingTables) {
130
+ existingMap.set(`${t.SchemaName}.${t.TableName}`.toLowerCase(), t);
131
+ }
132
+ const newConfigs = [];
133
+ const evolutionConfigs = [];
134
+ for (const config of input.TargetConfigs) {
135
+ const key = `${config.SchemaName}.${config.TableName}`.toLowerCase();
136
+ const existing = existingMap.get(key);
137
+ if (existing) {
138
+ evolutionConfigs.push({ config, existing });
139
+ }
140
+ else {
141
+ newConfigs.push(config);
142
+ }
143
+ }
144
+ return { newConfigs, evolutionConfigs };
145
+ }
146
+ GetUniqueSchemas(configs) {
147
+ const schemas = new Set();
148
+ for (const config of configs) {
149
+ schemas.add(config.SchemaName);
150
+ }
151
+ return Array.from(schemas);
152
+ }
153
+ CollectSoftFKs(input, evolutionConfigs) {
154
+ // From source relationships
155
+ const fromSource = this.SoftFKEmitter.GenerateConfigEntries(input.SourceSchema, input.TargetConfigs);
156
+ // From evolution (new FK columns)
157
+ for (const { config, existing } of evolutionConfigs) {
158
+ const sourceObj = input.SourceSchema.Objects.find(o => o.ExternalName === config.SourceObjectName);
159
+ if (!sourceObj)
160
+ continue;
161
+ const diff = this.Evolution.DiffSchema(sourceObj, config, existing, input.Platform);
162
+ const newFKs = this.Evolution.GenerateEvolutionSoftFKUpdates(diff, config);
163
+ fromSource.push(...newFKs);
164
+ }
165
+ return fromSource;
166
+ }
167
+ MakeMigrationMeta(input, action, objectName) {
168
+ return {
169
+ SourceType: input.SourceType,
170
+ ObjectName: objectName,
171
+ Action: action,
172
+ GeneratedBy: 'MJ Integration Schema Builder',
173
+ Timestamp: new Date().toISOString(),
174
+ };
175
+ }
176
+ }
177
+ //# sourceMappingURL=SchemaBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaBuilder.js","sourceRoot":"","sources":["../src/SchemaBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * SchemaEvolution — diff engine for detecting changes between source and existing schema.
3
+ * Compares source fields against existing table columns, produces incremental DDL.
4
+ */
5
+ import type { DatabasePlatform, ExistingTableInfo, SchemaDiff, SoftFKEntry, SourceObjectInfo, TargetTableConfig } from './interfaces.js';
6
+ /**
7
+ * Computes schema diffs and generates ALTER TABLE migration SQL.
8
+ */
9
+ export declare class SchemaEvolution {
10
+ private readonly DDL;
11
+ private readonly Mapper;
12
+ /**
13
+ * Diff a source object against an existing target table.
14
+ * Returns added, modified, and removed columns.
15
+ */
16
+ DiffSchema(source: SourceObjectInfo, targetConfig: TargetTableConfig, existing: ExistingTableInfo, platform: DatabasePlatform): SchemaDiff;
17
+ /**
18
+ * Generate ALTER TABLE SQL for a schema diff.
19
+ */
20
+ GenerateEvolutionMigration(diff: SchemaDiff, schemaName: string, tableName: string, platform: DatabasePlatform): string;
21
+ /**
22
+ * Identify new soft FK entries from a diff (for added FK columns).
23
+ */
24
+ GenerateEvolutionSoftFKUpdates(diff: SchemaDiff, targetConfig: TargetTableConfig): SoftFKEntry[];
25
+ private HasColumnChanged;
26
+ }
27
+ //# sourceMappingURL=SchemaEvolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaEvolution.d.ts","sourceRoot":"","sources":["../src/SchemaEvolution.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAER,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACV,WAAW,EACX,gBAAgB,EAEhB,iBAAiB,EACpB,MAAM,iBAAiB,CAAC;AAIzB;;GAEG;AACH,qBAAa,eAAe;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAsB;IAC1C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAE3C;;;OAGG;IACH,UAAU,CACN,MAAM,EAAE,gBAAgB,EACxB,YAAY,EAAE,iBAAiB,EAC/B,QAAQ,EAAE,iBAAiB,EAC3B,QAAQ,EAAE,gBAAgB,GAC3B,UAAU;IA6Cb;;OAEG;IACH,0BAA0B,CACtB,IAAI,EAAE,UAAU,EAChB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,gBAAgB,GAC3B,MAAM;IAkBT;;OAEG;IACH,8BAA8B,CAC1B,IAAI,EAAE,UAAU,EAChB,YAAY,EAAE,iBAAiB,GAChC,WAAW,EAAE;IAMhB,OAAO,CAAC,gBAAgB;CAS3B"}
@@ -0,0 +1,91 @@
1
+ import { DDLGenerator } from './DDLGenerator.js';
2
+ import { TypeMapper } from './TypeMapper.js';
3
+ /**
4
+ * Computes schema diffs and generates ALTER TABLE migration SQL.
5
+ */
6
+ export class SchemaEvolution {
7
+ constructor() {
8
+ this.DDL = new DDLGenerator();
9
+ this.Mapper = new TypeMapper();
10
+ }
11
+ /**
12
+ * Diff a source object against an existing target table.
13
+ * Returns added, modified, and removed columns.
14
+ */
15
+ DiffSchema(source, targetConfig, existing, platform) {
16
+ const existingNames = new Set(existing.Columns.map(c => c.Name.toLowerCase()));
17
+ const sourceColMap = new Map(targetConfig.Columns.map(c => [c.TargetColumnName.toLowerCase(), c]));
18
+ // Standard columns to ignore in the diff (managed by Schema Builder / CodeGen)
19
+ const standardCols = new Set(['id', 'sourcerecordid', 'sourcejson', 'syncstatus', 'lastsyncedat',
20
+ '__mj_createdat', '__mj_updatedat']);
21
+ const added = [];
22
+ const modified = [];
23
+ const removed = [];
24
+ // Find added and modified columns
25
+ for (const col of targetConfig.Columns) {
26
+ const lowerName = col.TargetColumnName.toLowerCase();
27
+ if (standardCols.has(lowerName))
28
+ continue;
29
+ if (!existingNames.has(lowerName)) {
30
+ added.push(col);
31
+ }
32
+ else {
33
+ const existingCol = existing.Columns.find(c => c.Name.toLowerCase() === lowerName);
34
+ if (existingCol && this.HasColumnChanged(existingCol, col)) {
35
+ modified.push({
36
+ ColumnName: col.TargetColumnName,
37
+ OldType: existingCol.SqlType,
38
+ NewType: col.TargetSqlType,
39
+ OldNullable: existingCol.IsNullable,
40
+ NewNullable: col.IsNullable,
41
+ });
42
+ }
43
+ }
44
+ }
45
+ // Find removed columns (in existing but not in source config)
46
+ for (const existingCol of existing.Columns) {
47
+ const lowerName = existingCol.Name.toLowerCase();
48
+ if (standardCols.has(lowerName))
49
+ continue;
50
+ if (!sourceColMap.has(lowerName)) {
51
+ removed.push(existingCol.Name);
52
+ }
53
+ }
54
+ return { AddedColumns: added, ModifiedColumns: modified, RemovedColumns: removed };
55
+ }
56
+ /**
57
+ * Generate ALTER TABLE SQL for a schema diff.
58
+ */
59
+ GenerateEvolutionMigration(diff, schemaName, tableName, platform) {
60
+ const statements = [];
61
+ for (const col of diff.AddedColumns) {
62
+ statements.push(this.DDL.GenerateAlterTableAddColumn(schemaName, tableName, col, platform));
63
+ }
64
+ for (const mod of diff.ModifiedColumns) {
65
+ statements.push(this.DDL.GenerateAlterTableAlterColumn(schemaName, tableName, mod, platform));
66
+ }
67
+ for (const colName of diff.RemovedColumns) {
68
+ statements.push(`-- DEPRECATED: Column [${colName}] no longer exists in source. Consider removing after grace period.`);
69
+ }
70
+ return statements.join('\n\n');
71
+ }
72
+ /**
73
+ * Identify new soft FK entries from a diff (for added FK columns).
74
+ */
75
+ GenerateEvolutionSoftFKUpdates(diff, targetConfig) {
76
+ // New FK entries come from added columns that have corresponding soft FK definitions
77
+ const addedNames = new Set(diff.AddedColumns.map(c => c.TargetColumnName));
78
+ return targetConfig.SoftForeignKeys.filter(fk => addedNames.has(fk.FieldName));
79
+ }
80
+ HasColumnChanged(existing, target) {
81
+ // Normalize types for comparison (case-insensitive, strip whitespace)
82
+ const normalizedExisting = existing.SqlType.toLowerCase().replace(/\s+/g, '');
83
+ const normalizedTarget = target.TargetSqlType.toLowerCase().replace(/\s+/g, '');
84
+ if (normalizedExisting !== normalizedTarget)
85
+ return true;
86
+ if (existing.IsNullable !== target.IsNullable)
87
+ return true;
88
+ return false;
89
+ }
90
+ }
91
+ //# sourceMappingURL=SchemaEvolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SchemaEvolution.js","sourceRoot":"","sources":["../src/SchemaEvolution.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * SoftFKConfigEmitter — reads/merges additionalSchemaInfo JSON for soft PKs and FKs.
3
+ * File-emission only — produces updated JSON content, never writes to disk directly.
4
+ */
5
+ import type { EmittedFile, SoftFKEntry, SourceSchemaInfo, TargetTableConfig } from './interfaces.js';
6
+ /** Shape of one table entry in additionalSchemaInfo. */
7
+ interface SchemaInfoTableEntry {
8
+ TableName: string;
9
+ PrimaryKey?: Array<{
10
+ FieldName: string;
11
+ Description?: string;
12
+ }>;
13
+ ForeignKeys?: Array<{
14
+ FieldName: string;
15
+ SchemaName: string;
16
+ RelatedTable: string;
17
+ RelatedField: string;
18
+ }>;
19
+ }
20
+ /** The top-level additionalSchemaInfo structure: schema name → table entries. */
21
+ type AdditionalSchemaInfo = Record<string, SchemaInfoTableEntry[]>;
22
+ /**
23
+ * Manages soft PK and FK definitions in the additionalSchemaInfo JSON file.
24
+ */
25
+ export declare class SoftFKConfigEmitter {
26
+ /**
27
+ * Parse existing additionalSchemaInfo JSON content.
28
+ * Returns empty object if content is empty/null.
29
+ */
30
+ ParseExistingConfig(jsonContent: string | null): AdditionalSchemaInfo;
31
+ /**
32
+ * Merge new soft FK entries into an existing config.
33
+ * Deduplicates — won't add the same FK twice.
34
+ */
35
+ MergeSchemaConfig(existing: AdditionalSchemaInfo, newEntries: SoftFKEntry[]): AdditionalSchemaInfo;
36
+ /**
37
+ * Add soft PK entries for integration tables.
38
+ * Uses the natural PK field name(s) from the source system. Supports composite PKs.
39
+ */
40
+ MergeSoftPKs(existing: AdditionalSchemaInfo, targetConfigs: TargetTableConfig[]): AdditionalSchemaInfo;
41
+ /**
42
+ * Extract soft FK entries from source schema relationships + target configs.
43
+ * Maps source relationship field names → target column names using the target config.
44
+ * FKs point to the natural PK field on target tables (first PK field for composite keys).
45
+ */
46
+ GenerateConfigEntries(sourceSchema: SourceSchemaInfo, targetConfigs: TargetTableConfig[]): SoftFKEntry[];
47
+ /**
48
+ * Produce an EmittedFile with the updated additionalSchemaInfo JSON.
49
+ */
50
+ EmitConfigFile(configPath: string, mergedConfig: AdditionalSchemaInfo): EmittedFile;
51
+ }
52
+ export {};
53
+ //# sourceMappingURL=SoftFKConfigEmitter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SoftFKConfigEmitter.d.ts","sourceRoot":"","sources":["../src/SoftFKConfigEmitter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAErG,wDAAwD;AACxD,UAAU,oBAAoB;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChE,WAAW,CAAC,EAAE,KAAK,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;KACxB,CAAC,CAAC;CACN;AAED,iFAAiF;AACjF,KAAK,oBAAoB,GAAG,MAAM,CAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAC;AAEnE;;GAEG;AACH,qBAAa,mBAAmB;IAC5B;;;OAGG;IACH,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,oBAAoB;IAOrE;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,UAAU,EAAE,WAAW,EAAE,GAAG,oBAAoB;IAyClG;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAAE,GAAG,oBAAoB;IA4BtG;;;;OAIG;IACH,qBAAqB,CACjB,YAAY,EAAE,gBAAgB,EAC9B,aAAa,EAAE,iBAAiB,EAAE,GACnC,WAAW,EAAE;IAyDhB;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,oBAAoB,GAAG,WAAW;CAOtF"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Manages soft PK and FK definitions in the additionalSchemaInfo JSON file.
3
+ */
4
+ export class SoftFKConfigEmitter {
5
+ /**
6
+ * Parse existing additionalSchemaInfo JSON content.
7
+ * Returns empty object if content is empty/null.
8
+ */
9
+ ParseExistingConfig(jsonContent) {
10
+ if (!jsonContent || jsonContent.trim() === '') {
11
+ return {};
12
+ }
13
+ return JSON.parse(jsonContent);
14
+ }
15
+ /**
16
+ * Merge new soft FK entries into an existing config.
17
+ * Deduplicates — won't add the same FK twice.
18
+ */
19
+ MergeSchemaConfig(existing, newEntries) {
20
+ const result = JSON.parse(JSON.stringify(existing));
21
+ for (const entry of newEntries) {
22
+ if (!result[entry.SchemaName]) {
23
+ result[entry.SchemaName] = [];
24
+ }
25
+ const schemaEntries = result[entry.SchemaName];
26
+ let tableEntry = schemaEntries.find(t => t.TableName === entry.TableName);
27
+ if (!tableEntry) {
28
+ tableEntry = { TableName: entry.TableName, ForeignKeys: [] };
29
+ schemaEntries.push(tableEntry);
30
+ }
31
+ if (!tableEntry.ForeignKeys) {
32
+ tableEntry.ForeignKeys = [];
33
+ }
34
+ // Deduplicate: skip if this exact FK already exists
35
+ const exists = tableEntry.ForeignKeys.some(fk => fk.FieldName === entry.FieldName &&
36
+ fk.SchemaName === entry.TargetSchemaName &&
37
+ fk.RelatedTable === entry.TargetTableName &&
38
+ fk.RelatedField === entry.TargetFieldName);
39
+ if (!exists) {
40
+ tableEntry.ForeignKeys.push({
41
+ FieldName: entry.FieldName,
42
+ SchemaName: entry.TargetSchemaName,
43
+ RelatedTable: entry.TargetTableName,
44
+ RelatedField: entry.TargetFieldName,
45
+ });
46
+ }
47
+ }
48
+ return result;
49
+ }
50
+ /**
51
+ * Add soft PK entries for integration tables.
52
+ * Uses the natural PK field name(s) from the source system. Supports composite PKs.
53
+ */
54
+ MergeSoftPKs(existing, targetConfigs) {
55
+ const result = JSON.parse(JSON.stringify(existing));
56
+ for (const config of targetConfigs) {
57
+ if (config.PrimaryKeyFields.length === 0)
58
+ continue;
59
+ if (!result[config.SchemaName]) {
60
+ result[config.SchemaName] = [];
61
+ }
62
+ const schemaEntries = result[config.SchemaName];
63
+ let tableEntry = schemaEntries.find(t => t.TableName === config.TableName);
64
+ if (!tableEntry) {
65
+ tableEntry = { TableName: config.TableName };
66
+ schemaEntries.push(tableEntry);
67
+ }
68
+ // Set soft PK to the natural PK field(s) from the source system
69
+ tableEntry.PrimaryKey = config.PrimaryKeyFields.map(fieldName => ({
70
+ FieldName: fieldName,
71
+ Description: `Primary key from source system`,
72
+ }));
73
+ }
74
+ return result;
75
+ }
76
+ /**
77
+ * Extract soft FK entries from source schema relationships + target configs.
78
+ * Maps source relationship field names → target column names using the target config.
79
+ * FKs point to the natural PK field on target tables (first PK field for composite keys).
80
+ */
81
+ GenerateConfigEntries(sourceSchema, targetConfigs) {
82
+ const entries = [];
83
+ // Also collect entries already defined directly on TargetTableConfig
84
+ for (const config of targetConfigs) {
85
+ if (config.SoftForeignKeys) {
86
+ entries.push(...config.SoftForeignKeys);
87
+ }
88
+ }
89
+ // Build a map of source object name → target config for FK resolution
90
+ const sourceToTarget = new Map();
91
+ for (const config of targetConfigs) {
92
+ sourceToTarget.set(config.SourceObjectName, config);
93
+ }
94
+ // Walk source relationships and map them to target columns
95
+ for (const sourceObj of sourceSchema.Objects) {
96
+ const targetConfig = sourceToTarget.get(sourceObj.ExternalName);
97
+ if (!targetConfig)
98
+ continue;
99
+ for (const rel of sourceObj.Relationships) {
100
+ const targetOfFK = sourceToTarget.get(rel.TargetObject);
101
+ if (!targetOfFK)
102
+ continue; // Target object not being imported
103
+ // Find the mapped column name for this FK field
104
+ const columnConfig = targetConfig.Columns.find(c => c.SourceFieldName === rel.FieldName);
105
+ const columnName = columnConfig ? columnConfig.TargetColumnName : rel.FieldName;
106
+ // FK points to the natural PK field on the target table
107
+ const targetPKField = targetOfFK.PrimaryKeyFields[0];
108
+ if (!targetPKField)
109
+ continue; // Target has no PK — skip FK
110
+ const entry = {
111
+ SchemaName: targetConfig.SchemaName,
112
+ TableName: targetConfig.TableName,
113
+ FieldName: columnName,
114
+ TargetSchemaName: targetOfFK.SchemaName,
115
+ TargetTableName: targetOfFK.TableName,
116
+ TargetFieldName: targetPKField,
117
+ };
118
+ // Deduplicate against already-added entries
119
+ const alreadyAdded = entries.some(e => e.SchemaName === entry.SchemaName &&
120
+ e.TableName === entry.TableName &&
121
+ e.FieldName === entry.FieldName);
122
+ if (!alreadyAdded) {
123
+ entries.push(entry);
124
+ }
125
+ }
126
+ }
127
+ return entries;
128
+ }
129
+ /**
130
+ * Produce an EmittedFile with the updated additionalSchemaInfo JSON.
131
+ */
132
+ EmitConfigFile(configPath, mergedConfig) {
133
+ return {
134
+ FilePath: configPath,
135
+ Content: JSON.stringify(mergedConfig, null, 4) + '\n',
136
+ Description: 'Updated additionalSchemaInfo with soft PK and FK definitions for integration tables',
137
+ };
138
+ }
139
+ }
140
+ //# sourceMappingURL=SoftFKConfigEmitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SoftFKConfigEmitter.js","sourceRoot":"","sources":["../src/SoftFKConfigEmitter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * TypeMapper — converts generic source types to platform-specific SQL types.
3
+ */
4
+ import type { DatabasePlatform, SourceFieldInfo, TypeMappingEntry } from './interfaces.js';
5
+ /**
6
+ * Maps generic source field types to platform-specific SQL types.
7
+ */
8
+ export declare class TypeMapper {
9
+ /**
10
+ * Convert a source field's type to the appropriate SQL type for the given platform.
11
+ */
12
+ MapSourceType(sourceType: string, platform: DatabasePlatform, field: SourceFieldInfo): string;
13
+ /**
14
+ * Get the MJ EntityField.Type value for a source type (informational only).
15
+ */
16
+ GetMJFieldType(sourceType: string): string;
17
+ /**
18
+ * Get all supported type mappings.
19
+ */
20
+ GetAllMappings(): ReadonlyArray<TypeMappingEntry>;
21
+ private ApplyPrecision;
22
+ private ApplyStringLength;
23
+ private ApplyDecimalPrecision;
24
+ }
25
+ //# sourceMappingURL=TypeMapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeMapper.d.ts","sourceRoot":"","sources":["../src/TypeMapper.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAiB3F;;GAEG;AACH,qBAAa,UAAU;IACnB;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,EAAE,eAAe,GAAG,MAAM;IAa7F;;OAEG;IACH,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAM1C;;OAEG;IACH,cAAc,IAAI,aAAa,CAAC,gBAAgB,CAAC;IAIjD,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,iBAAiB;IAYzB,OAAO,CAAC,qBAAqB;CAKhC"}
@@ -0,0 +1,72 @@
1
+ const TYPE_MAP = [
2
+ { SourceType: 'string', SqlServerType: 'NVARCHAR', PostgresType: 'VARCHAR', MJFieldType: 'nvarchar' },
3
+ { SourceType: 'text', SqlServerType: 'NVARCHAR(MAX)', PostgresType: 'TEXT', MJFieldType: 'nvarchar' },
4
+ { SourceType: 'integer', SqlServerType: 'INT', PostgresType: 'INTEGER', MJFieldType: 'int' },
5
+ { SourceType: 'bigint', SqlServerType: 'BIGINT', PostgresType: 'BIGINT', MJFieldType: 'bigint' },
6
+ { SourceType: 'decimal', SqlServerType: 'DECIMAL', PostgresType: 'NUMERIC', MJFieldType: 'decimal' },
7
+ { SourceType: 'boolean', SqlServerType: 'BIT', PostgresType: 'BOOLEAN', MJFieldType: 'bit' },
8
+ { SourceType: 'datetime', SqlServerType: 'DATETIMEOFFSET', PostgresType: 'TIMESTAMPTZ', MJFieldType: 'datetimeoffset' },
9
+ { SourceType: 'date', SqlServerType: 'DATE', PostgresType: 'DATE', MJFieldType: 'date' },
10
+ { SourceType: 'uuid', SqlServerType: 'UNIQUEIDENTIFIER', PostgresType: 'UUID', MJFieldType: 'uniqueidentifier' },
11
+ { SourceType: 'json', SqlServerType: 'NVARCHAR(MAX)', PostgresType: 'JSONB', MJFieldType: 'nvarchar' },
12
+ { SourceType: 'float', SqlServerType: 'FLOAT', PostgresType: 'DOUBLE PRECISION', MJFieldType: 'float' },
13
+ { SourceType: 'time', SqlServerType: 'TIME', PostgresType: 'TIME', MJFieldType: 'time' },
14
+ ];
15
+ /**
16
+ * Maps generic source field types to platform-specific SQL types.
17
+ */
18
+ export class TypeMapper {
19
+ /**
20
+ * Convert a source field's type to the appropriate SQL type for the given platform.
21
+ */
22
+ MapSourceType(sourceType, platform, field) {
23
+ const normalized = sourceType.toLowerCase().trim();
24
+ const entry = TYPE_MAP.find(t => t.SourceType === normalized);
25
+ if (!entry) {
26
+ // Unknown type — fall back to text
27
+ return platform === 'sqlserver' ? 'NVARCHAR(MAX)' : 'TEXT';
28
+ }
29
+ const baseType = platform === 'sqlserver' ? entry.SqlServerType : entry.PostgresType;
30
+ return this.ApplyPrecision(baseType, normalized, field, platform);
31
+ }
32
+ /**
33
+ * Get the MJ EntityField.Type value for a source type (informational only).
34
+ */
35
+ GetMJFieldType(sourceType) {
36
+ const normalized = sourceType.toLowerCase().trim();
37
+ const entry = TYPE_MAP.find(t => t.SourceType === normalized);
38
+ return entry ? entry.MJFieldType : 'nvarchar';
39
+ }
40
+ /**
41
+ * Get all supported type mappings.
42
+ */
43
+ GetAllMappings() {
44
+ return TYPE_MAP;
45
+ }
46
+ ApplyPrecision(baseType, sourceType, field, platform) {
47
+ if (sourceType === 'string') {
48
+ return this.ApplyStringLength(baseType, field, platform);
49
+ }
50
+ if (sourceType === 'decimal') {
51
+ return this.ApplyDecimalPrecision(baseType, field);
52
+ }
53
+ return baseType;
54
+ }
55
+ ApplyStringLength(baseType, field, platform) {
56
+ if (field.MaxLength != null && field.MaxLength > 0) {
57
+ // SQL Server NVARCHAR max is 4000 before switching to MAX; PG VARCHAR has no practical limit
58
+ if (platform === 'sqlserver' && field.MaxLength > 4000) {
59
+ return 'NVARCHAR(MAX)';
60
+ }
61
+ return `${baseType}(${field.MaxLength})`;
62
+ }
63
+ // Default string length
64
+ return `${baseType}(255)`;
65
+ }
66
+ ApplyDecimalPrecision(baseType, field) {
67
+ const precision = field.Precision ?? 18;
68
+ const scale = field.Scale ?? 2;
69
+ return `${baseType}(${precision},${scale})`;
70
+ }
71
+ }
72
+ //# sourceMappingURL=TypeMapper.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TypeMapper.js","sourceRoot":"","sources":["../src/TypeMapper.ts"],"names":[],"mappings":"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"}