@zintrust/d1-migrator 0.4.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.
- package/README.md +871 -0
- package/dist/cli/DataMigrator.d.ts +104 -0
- package/dist/cli/DataMigrator.d.ts.map +1 -0
- package/dist/cli/DataMigrator.js +431 -0
- package/dist/cli/MigrateToD1Command.d.ts +52 -0
- package/dist/cli/MigrateToD1Command.d.ts.map +1 -0
- package/dist/cli/MigrateToD1Command.js +600 -0
- package/dist/cli/ProgressTracker.d.ts +32 -0
- package/dist/cli/ProgressTracker.d.ts.map +1 -0
- package/dist/cli/ProgressTracker.js +95 -0
- package/dist/cli/SchemaAnalyzer.d.ts +130 -0
- package/dist/cli/SchemaAnalyzer.d.ts.map +1 -0
- package/dist/cli/SchemaAnalyzer.js +660 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/schema/SchemaBuilder.d.ts +51 -0
- package/dist/schema/SchemaBuilder.d.ts.map +1 -0
- package/dist/schema/SchemaBuilder.js +165 -0
- package/dist/schema/TypeConverter.d.ts +35 -0
- package/dist/schema/TypeConverter.d.ts.map +1 -0
- package/dist/schema/TypeConverter.js +187 -0
- package/dist/schema/Validator.d.ts +74 -0
- package/dist/schema/Validator.d.ts.map +1 -0
- package/dist/schema/Validator.js +225 -0
- package/dist/types.d.ts +145 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/utils/CheckpointManager.d.ts +48 -0
- package/dist/utils/CheckpointManager.d.ts.map +1 -0
- package/dist/utils/CheckpointManager.js +191 -0
- package/dist/utils/DataValidator.d.ts +46 -0
- package/dist/utils/DataValidator.d.ts.map +1 -0
- package/dist/utils/DataValidator.js +139 -0
- package/package.json +37 -0
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Data Validator
|
|
3
|
+
* Integrity checks and validation for migrated data
|
|
4
|
+
*/
|
|
5
|
+
import { Logger } from '@zintrust/core';
|
|
6
|
+
/**
|
|
7
|
+
* DataValidator - Sealed namespace for data integrity validation
|
|
8
|
+
* Provides comprehensive validation of migrated data
|
|
9
|
+
*/
|
|
10
|
+
export const DataValidator = Object.freeze({
|
|
11
|
+
/**
|
|
12
|
+
* Validate data integrity between source and target
|
|
13
|
+
*/
|
|
14
|
+
async validateDataIntegrity(sourceCount, targetCount, tableName) {
|
|
15
|
+
const isValid = sourceCount === targetCount;
|
|
16
|
+
if (isValid) {
|
|
17
|
+
Logger.info(`Data integrity check passed for table ${tableName}: ${targetCount} rows`);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
Logger.warn(`Data integrity check failed for table ${tableName}: source=${sourceCount}, target=${targetCount}`);
|
|
21
|
+
}
|
|
22
|
+
return isValid;
|
|
23
|
+
},
|
|
24
|
+
/**
|
|
25
|
+
* Generate checksum for data validation
|
|
26
|
+
*/
|
|
27
|
+
async generateChecksum(data) {
|
|
28
|
+
const crypto = await import('node:crypto');
|
|
29
|
+
const dataString = JSON.stringify(data);
|
|
30
|
+
return crypto.createHash('sha256').update(dataString).digest('hex');
|
|
31
|
+
},
|
|
32
|
+
/**
|
|
33
|
+
* Validate data checksums
|
|
34
|
+
*/
|
|
35
|
+
async validateChecksum(sourceData, targetData, tableName) {
|
|
36
|
+
const sourceChecksum = await DataValidator.generateChecksum(sourceData);
|
|
37
|
+
const targetChecksum = await DataValidator.generateChecksum(targetData);
|
|
38
|
+
const isValid = sourceChecksum === targetChecksum;
|
|
39
|
+
if (isValid) {
|
|
40
|
+
Logger.info(`Checksum validation passed for table ${tableName}`);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
Logger.warn(`Checksum validation failed for table ${tableName}`);
|
|
44
|
+
Logger.debug(`Source checksum: ${sourceChecksum}`);
|
|
45
|
+
Logger.debug(`Target checksum: ${targetChecksum}`);
|
|
46
|
+
}
|
|
47
|
+
return isValid;
|
|
48
|
+
},
|
|
49
|
+
/**
|
|
50
|
+
* Comprehensive data validation
|
|
51
|
+
*/
|
|
52
|
+
async validateTable(sourceData, targetData, tableName) {
|
|
53
|
+
const sourceCount = sourceData.length;
|
|
54
|
+
const targetCount = targetData.length;
|
|
55
|
+
const countMatch = await DataValidator.validateDataIntegrity(sourceCount, targetCount, tableName);
|
|
56
|
+
const checksumMatch = await DataValidator.validateChecksum(sourceData, targetData, tableName);
|
|
57
|
+
const errors = [];
|
|
58
|
+
if (!countMatch) {
|
|
59
|
+
errors.push(`Row count mismatch: source=${sourceCount}, target=${targetCount}`);
|
|
60
|
+
}
|
|
61
|
+
if (!checksumMatch) {
|
|
62
|
+
errors.push('Data checksum mismatch detected');
|
|
63
|
+
}
|
|
64
|
+
const result = {
|
|
65
|
+
table: tableName,
|
|
66
|
+
sourceCount,
|
|
67
|
+
targetCount,
|
|
68
|
+
checksumMatch,
|
|
69
|
+
errors,
|
|
70
|
+
};
|
|
71
|
+
if (errors.length === 0) {
|
|
72
|
+
Logger.info(`Table validation passed: ${tableName}`);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
Logger.error(`Table validation failed: ${tableName}`, errors);
|
|
76
|
+
}
|
|
77
|
+
return result;
|
|
78
|
+
},
|
|
79
|
+
/**
|
|
80
|
+
* Validate schema compatibility
|
|
81
|
+
*/
|
|
82
|
+
validateSchemaCompatibility(sourceSchema, targetSchema, tableName) {
|
|
83
|
+
const errors = [];
|
|
84
|
+
// Basic schema validation - can be extended based on requirements
|
|
85
|
+
if (!sourceSchema || !targetSchema) {
|
|
86
|
+
errors.push('Schema information is missing');
|
|
87
|
+
}
|
|
88
|
+
// Add more specific schema validation logic here
|
|
89
|
+
// For now, just basic structure validation
|
|
90
|
+
const valid = errors.length === 0;
|
|
91
|
+
if (valid) {
|
|
92
|
+
Logger.info(`Schema compatibility validated for table ${tableName}`);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
Logger.warn(`Schema compatibility issues detected for table ${tableName}:`, errors);
|
|
96
|
+
}
|
|
97
|
+
return { valid, errors };
|
|
98
|
+
},
|
|
99
|
+
/**
|
|
100
|
+
* Sanitize table name for D1 compatibility
|
|
101
|
+
*/
|
|
102
|
+
sanitizeTableName(tableName) {
|
|
103
|
+
// D1/SQLite has specific naming requirements
|
|
104
|
+
let sanitized = tableName.toLowerCase().replaceAll(/[^a-z0-9_-]/g, '_'); // Replace invalid chars with underscore
|
|
105
|
+
// Remove leading and trailing underscores (safer than regex)
|
|
106
|
+
while (sanitized.startsWith('_')) {
|
|
107
|
+
sanitized = sanitized.slice(1);
|
|
108
|
+
}
|
|
109
|
+
while (sanitized.endsWith('_')) {
|
|
110
|
+
sanitized = sanitized.slice(0, -1);
|
|
111
|
+
}
|
|
112
|
+
return sanitized.substring(0, 64); // SQLite limit
|
|
113
|
+
},
|
|
114
|
+
/**
|
|
115
|
+
* Validate column type conversion
|
|
116
|
+
*/
|
|
117
|
+
validateColumnType(sourceType, targetType, tableName, columnName) {
|
|
118
|
+
// Define type compatibility matrix
|
|
119
|
+
const compatibleTypes = {
|
|
120
|
+
varchar: ['text', 'varchar'],
|
|
121
|
+
text: ['text', 'varchar', 'longtext'],
|
|
122
|
+
int: ['integer', 'int', 'bigint'],
|
|
123
|
+
bigint: ['integer', 'bigint'],
|
|
124
|
+
decimal: ['real', 'decimal', 'double'],
|
|
125
|
+
datetime: ['text', 'datetime'],
|
|
126
|
+
boolean: ['integer', 'boolean'],
|
|
127
|
+
};
|
|
128
|
+
const normalizedTargetType = targetType.toLowerCase();
|
|
129
|
+
const normalizedSourceType = sourceType.toLowerCase();
|
|
130
|
+
const validTargetTypes = compatibleTypes[normalizedSourceType];
|
|
131
|
+
const isValid = validTargetTypes?.includes(normalizedTargetType) || false;
|
|
132
|
+
let warning;
|
|
133
|
+
if (!isValid) {
|
|
134
|
+
warning = `Type conversion may cause data loss: ${sourceType} -> ${targetType} in ${tableName}.${columnName}`;
|
|
135
|
+
Logger.warn(warning);
|
|
136
|
+
}
|
|
137
|
+
return { valid: isValid, warning };
|
|
138
|
+
},
|
|
139
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zintrust/d1-migrator",
|
|
3
|
+
"version": "0.4.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=20.0.0"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"@zintrust/core": "^0.4.0"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsc -p tsconfig.json",
|
|
28
|
+
"prepublishOnly": "npm run build"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@zintrust/db-mysql": "0.4.0",
|
|
32
|
+
"@zintrust/db-postgres": "0.4.0",
|
|
33
|
+
"@zintrust/db-sqlite": "0.4.0",
|
|
34
|
+
"@zintrust/db-sqlserver": "0.4.0",
|
|
35
|
+
"@zintrust/db-d1": "0.4.0"
|
|
36
|
+
}
|
|
37
|
+
}
|