@zintrust/d1-migrator 1.8.0 → 1.8.2
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/dist/build-manifest.json +21 -17
- package/dist/cli/DataMigrator.d.ts.map +1 -1
- package/dist/cli/DataMigrator.js +96 -43
- package/dist/cli/MigrateToD1Command.d.ts.map +1 -1
- package/dist/cli/MigrateToD1Command.js +151 -11
- package/dist/cli/SchemaAnalyzer.d.ts.map +1 -1
- package/dist/cli/SchemaAnalyzer.js +41 -2
- package/package.json +7 -7
package/dist/build-manifest.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/d1-migrator",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"buildDate": "2026-05-
|
|
3
|
+
"version": "1.7.1",
|
|
4
|
+
"buildDate": "2026-05-01T05:26:52.011Z",
|
|
5
5
|
"buildEnvironment": {
|
|
6
|
-
"node": "
|
|
7
|
-
"platform": "
|
|
8
|
-
"arch": "
|
|
6
|
+
"node": "v22.22.1",
|
|
7
|
+
"platform": "darwin",
|
|
8
|
+
"arch": "arm64"
|
|
9
9
|
},
|
|
10
10
|
"git": {
|
|
11
|
-
"commit": "
|
|
12
|
-
"branch": "
|
|
11
|
+
"commit": "ef4e9bec",
|
|
12
|
+
"branch": "release"
|
|
13
13
|
},
|
|
14
14
|
"package": {
|
|
15
15
|
"engines": {
|
|
@@ -27,17 +27,21 @@
|
|
|
27
27
|
]
|
|
28
28
|
},
|
|
29
29
|
"files": {
|
|
30
|
+
"build-manifest.json": {
|
|
31
|
+
"size": 5807,
|
|
32
|
+
"sha256": "eef551e3974318b0181db8f77c5abd60957797f792babcd8e365bd37f89b366a"
|
|
33
|
+
},
|
|
30
34
|
"cli/DataMigrator.d.ts": {
|
|
31
35
|
"size": 3355,
|
|
32
36
|
"sha256": "f7ce0a06282ab0d08a90cca9b0d2cc4ec5a8df91c9e65425aaf342ef005b5af6"
|
|
33
37
|
},
|
|
34
38
|
"cli/DataMigrator.d.ts.map": {
|
|
35
39
|
"size": 2120,
|
|
36
|
-
"sha256": "
|
|
40
|
+
"sha256": "be301eb96726a2611e9f739c5f57b536b24243413ad100effc7afce905d83e81"
|
|
37
41
|
},
|
|
38
42
|
"cli/DataMigrator.js": {
|
|
39
|
-
"size":
|
|
40
|
-
"sha256": "
|
|
43
|
+
"size": 18540,
|
|
44
|
+
"sha256": "8b0d02707f5d14a458b9a666ef8a27051e32396d61067896dcd486cc680506d2"
|
|
41
45
|
},
|
|
42
46
|
"cli/MigrateToD1Command.d.ts": {
|
|
43
47
|
"size": 1589,
|
|
@@ -85,7 +89,7 @@
|
|
|
85
89
|
},
|
|
86
90
|
"index.js": {
|
|
87
91
|
"size": 1262,
|
|
88
|
-
"sha256": "
|
|
92
|
+
"sha256": "7c4c60fe23d200e4b6eab36670b70d916e96dcd572d09c5ed386a4fc26c7dfab"
|
|
89
93
|
},
|
|
90
94
|
"register.d.ts": {
|
|
91
95
|
"size": 159,
|
|
@@ -100,16 +104,16 @@
|
|
|
100
104
|
"sha256": "949f1d93c92a2b9ec1e7d388b4723f8f7012e57eaded61589d205709f0f7a5fe"
|
|
101
105
|
},
|
|
102
106
|
"schema/SchemaBuilder.d.ts": {
|
|
103
|
-
"size":
|
|
104
|
-
"sha256": "
|
|
107
|
+
"size": 1443,
|
|
108
|
+
"sha256": "46c568eef17ab0b0b1a59cfef0bf06f85d06de6e6d5479429e6a566b43ec87a7"
|
|
105
109
|
},
|
|
106
110
|
"schema/SchemaBuilder.d.ts.map": {
|
|
107
|
-
"size":
|
|
108
|
-
"sha256": "
|
|
111
|
+
"size": 670,
|
|
112
|
+
"sha256": "6ee501ff68e7d23fbb14f3f24167606346826392c8782153920b5d27cbb3348f"
|
|
109
113
|
},
|
|
110
114
|
"schema/SchemaBuilder.js": {
|
|
111
|
-
"size":
|
|
112
|
-
"sha256": "
|
|
115
|
+
"size": 6087,
|
|
116
|
+
"sha256": "fc6ac1668fde7bf5f4d54492d41e7004ccde0a60cc93197ad228d5675248dd01"
|
|
113
117
|
},
|
|
114
118
|
"schema/TypeConverter.d.ts": {
|
|
115
119
|
"size": 989,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DataMigrator.d.ts","sourceRoot":"","sources":["../../src/cli/DataMigrator.ts"],"names":[],"mappings":"AACA;;;GAGG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACxE,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;
|
|
1
|
+
{"version":3,"file":"DataMigrator.d.ts","sourceRoot":"","sources":["../../src/cli/DataMigrator.ts"],"names":[],"mappings":"AACA;;;GAGG;AAWH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,eAAe,CAAC,cAAc,CAAC,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,GAAG,WAAW,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,eAAe,GAAG;IACrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,UAAU,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;CACxE,CAAC;AAEF,KAAK,0BAA0B,GAAG;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;CACtB,CAAC;AAkLF;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;wBACuB,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAqFtE;;OAEG;4BAC2B,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA4BzE;;OAEG;4BAC2B,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyCzE;;OAEG;0CAEiB,gBAAgB,oBAChB,gBAAgB,UAC1B,eAAe,GACtB,OAAO,CAAC,IAAI,CAAC;IAqChB;;OAEG;+BAC8B,gBAAgB,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,SAAS,EAAE,CAAA;KAAE,CAAC;IAiBpF;;OAEG;wBAEM,SAAS,oBACE,gBAAgB,oBAChB,gBAAgB,UAC1B,eAAe,GACtB,OAAO,CAAC;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IA4EtD;;OAEG;oCAEiB,gBAAgB,aACvB,MAAM,UACT,MAAM,aACH,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAkBrC;;OAEG;yBAEM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aACrB,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IA4CrC;;OAEG;iCAEiB,gBAAgB,aACvB,MAAM,QACX,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAC9B,OAAO,CAAC,MAAM,CAAC;IAkClB;;OAEG;gCACyB,eAAe,CAAC,cAAc,CAAC,aAAa,MAAM,GAAG,MAAM;IAavF;;OAEG;wCAEM,MAAM,UACL,MAAM,gBACA,MAAM,gBACN,MAAM,GACnB,0BAA0B;IAS7B;;OAEG;gCACyB,MAAM,GAAG,iBAAiB;IAetD;;OAEG;6BAES,iBAAiB,WAClB,OAAO,CAAC,iBAAiB,CAAC,GAClC,iBAAiB;EAGpB,CAAC"}
|
package/dist/cli/DataMigrator.js
CHANGED
|
@@ -10,6 +10,47 @@ import { SQLiteAdapter } from '@zintrust/db-sqlite';
|
|
|
10
10
|
import { SQLServerAdapter } from '@zintrust/db-sqlserver';
|
|
11
11
|
import { SchemaBuilder } from '../schema/SchemaBuilder.js';
|
|
12
12
|
import { SchemaAnalyzer } from './SchemaAnalyzer.js';
|
|
13
|
+
const redactConnectionString = (connectionString) => {
|
|
14
|
+
try {
|
|
15
|
+
const parsed = new URL(connectionString);
|
|
16
|
+
if (parsed.password.trim() !== '') {
|
|
17
|
+
parsed.password = '***';
|
|
18
|
+
}
|
|
19
|
+
return parsed.toString();
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
return connectionString;
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
const getErrorCause = (error) => {
|
|
26
|
+
if (error === null || typeof error !== 'object') {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
return error.cause;
|
|
30
|
+
};
|
|
31
|
+
const getErrorMessage = (error) => {
|
|
32
|
+
if (error instanceof Error) {
|
|
33
|
+
return error.message;
|
|
34
|
+
}
|
|
35
|
+
return String(error);
|
|
36
|
+
};
|
|
37
|
+
const getErrorChainMessages = (error) => {
|
|
38
|
+
const messages = [];
|
|
39
|
+
let current = error;
|
|
40
|
+
while (current !== undefined) {
|
|
41
|
+
const message = getErrorMessage(current);
|
|
42
|
+
if (message.trim() !== '') {
|
|
43
|
+
messages.push(message);
|
|
44
|
+
}
|
|
45
|
+
current = getErrorCause(current);
|
|
46
|
+
}
|
|
47
|
+
return [...new Set(messages)];
|
|
48
|
+
};
|
|
49
|
+
const describePasswordForLog = (password) => {
|
|
50
|
+
const hasSpecialCharacters = /[^a-zA-Z0-9]/.test(password);
|
|
51
|
+
const containsBang = password.includes('!');
|
|
52
|
+
return `len=${password.length}, special_chars=${hasSpecialCharacters}, contains_bang=${containsBang}`;
|
|
53
|
+
};
|
|
13
54
|
const normalizeNullLikeValue = (value) => {
|
|
14
55
|
if (typeof value !== 'string')
|
|
15
56
|
return value;
|
|
@@ -51,6 +92,47 @@ const parseSqliteDatabasePath = (connectionString) => {
|
|
|
51
92
|
return trimmed;
|
|
52
93
|
}
|
|
53
94
|
};
|
|
95
|
+
const createSourceAdapter = (config) => {
|
|
96
|
+
switch (config.sourceDriver) {
|
|
97
|
+
case 'mysql': {
|
|
98
|
+
const connectionDetails = parseConnectionDetails(config.sourceConnection, 3306, 'mysql', 'root');
|
|
99
|
+
Logger.info(`[DataMigrator] Source password diagnostics: ${describePasswordForLog(connectionDetails.password)}`);
|
|
100
|
+
return MySQLAdapter.create({
|
|
101
|
+
driver: 'mysql',
|
|
102
|
+
connectionString: config.sourceConnection,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
case 'postgresql': {
|
|
106
|
+
const connectionDetails = parseConnectionDetails(config.sourceConnection, 5432, 'postgres', 'postgres');
|
|
107
|
+
return PostgreSQLAdapter.create({
|
|
108
|
+
driver: 'postgresql',
|
|
109
|
+
host: connectionDetails.host,
|
|
110
|
+
port: connectionDetails.port,
|
|
111
|
+
database: connectionDetails.database,
|
|
112
|
+
username: connectionDetails.username,
|
|
113
|
+
password: connectionDetails.password,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
case 'sqlite':
|
|
117
|
+
return SQLiteAdapter.create({
|
|
118
|
+
driver: 'sqlite',
|
|
119
|
+
database: parseSqliteDatabasePath(config.sourceConnection),
|
|
120
|
+
});
|
|
121
|
+
case 'sqlserver': {
|
|
122
|
+
const connectionDetails = parseConnectionDetails(config.sourceConnection, 1433, 'master', 'sa');
|
|
123
|
+
return SQLServerAdapter.create({
|
|
124
|
+
driver: 'sqlserver',
|
|
125
|
+
host: connectionDetails.host,
|
|
126
|
+
port: connectionDetails.port,
|
|
127
|
+
database: connectionDetails.database,
|
|
128
|
+
username: connectionDetails.username,
|
|
129
|
+
password: connectionDetails.password,
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
default:
|
|
133
|
+
throw ErrorFactory.createValidationError(`Unsupported driver: ${config.sourceDriver}`);
|
|
134
|
+
}
|
|
135
|
+
};
|
|
54
136
|
const safelyDisconnect = async (label, connection) => {
|
|
55
137
|
try {
|
|
56
138
|
await connection?.adapter?.disconnect?.();
|
|
@@ -121,7 +203,9 @@ export const DataMigrator = Object.freeze({
|
|
|
121
203
|
return progress;
|
|
122
204
|
}
|
|
123
205
|
catch (error) {
|
|
124
|
-
|
|
206
|
+
const errorChain = getErrorChainMessages(error);
|
|
207
|
+
Logger.error(`Data migration failed: ${errorChain.join(' -> ')}`);
|
|
208
|
+
Logger.error('Data migration failure details:', error);
|
|
125
209
|
throw error;
|
|
126
210
|
}
|
|
127
211
|
finally {
|
|
@@ -133,49 +217,18 @@ export const DataMigrator = Object.freeze({
|
|
|
133
217
|
* Connect to source database
|
|
134
218
|
*/
|
|
135
219
|
async connectToSource(config) {
|
|
136
|
-
Logger.info(`Connecting to ${config.sourceDriver} database
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
adapter = PostgreSQLAdapter.create({
|
|
148
|
-
driver: 'postgresql',
|
|
149
|
-
host: connectionDetails.host,
|
|
150
|
-
port: connectionDetails.port,
|
|
151
|
-
database: connectionDetails.database,
|
|
152
|
-
username: connectionDetails.username,
|
|
153
|
-
password: connectionDetails.password,
|
|
154
|
-
});
|
|
155
|
-
break;
|
|
156
|
-
}
|
|
157
|
-
case 'sqlite':
|
|
158
|
-
adapter = SQLiteAdapter.create({
|
|
159
|
-
driver: 'sqlite',
|
|
160
|
-
database: parseSqliteDatabasePath(config.sourceConnection),
|
|
161
|
-
});
|
|
162
|
-
break;
|
|
163
|
-
case 'sqlserver': {
|
|
164
|
-
const connectionDetails = parseConnectionDetails(config.sourceConnection, 1433, 'master', 'sa');
|
|
165
|
-
adapter = SQLServerAdapter.create({
|
|
166
|
-
driver: 'sqlserver',
|
|
167
|
-
host: connectionDetails.host,
|
|
168
|
-
port: connectionDetails.port,
|
|
169
|
-
database: connectionDetails.database,
|
|
170
|
-
username: connectionDetails.username,
|
|
171
|
-
password: connectionDetails.password,
|
|
172
|
-
});
|
|
173
|
-
break;
|
|
174
|
-
}
|
|
175
|
-
default:
|
|
176
|
-
throw ErrorFactory.createValidationError(`Unsupported driver: ${config.sourceDriver}`);
|
|
220
|
+
Logger.info(`Connecting to ${config.sourceDriver} database...`);
|
|
221
|
+
Logger.info(`[DataMigrator] Source connection (redacted): ${redactConnectionString(config.sourceConnection)}`);
|
|
222
|
+
const adapter = createSourceAdapter(config);
|
|
223
|
+
try {
|
|
224
|
+
await adapter.connect();
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
const errorChain = getErrorChainMessages(error);
|
|
228
|
+
Logger.error(`Source database connection failed: ${errorChain.join(' -> ')}`);
|
|
229
|
+
Logger.error('Source database connection failure details:', error);
|
|
230
|
+
throw error;
|
|
177
231
|
}
|
|
178
|
-
await adapter.connect();
|
|
179
232
|
const connection = {
|
|
180
233
|
driver: config.sourceDriver,
|
|
181
234
|
connectionString: config.sourceConnection || '',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MigrateToD1Command.d.ts","sourceRoot":"","sources":["../../src/cli/MigrateToD1Command.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAOhD,KAAK,iBAAiB,GAAG;IACvB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,IAAI,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,CAAC;
|
|
1
|
+
{"version":3,"file":"MigrateToD1Command.d.ts","sourceRoot":"","sources":["../../src/cli/MigrateToD1Command.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAe,KAAK,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAOhD,KAAK,iBAAiB,GAAG;IACvB,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,IAAI,OAAO,CAAC;IACtB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,KAAK,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;CAC/B,CAAC;AA6rBF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,iBA4G/B,CAAC;AAEH;;GAEG;AACH,iBAAe,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CActE;AAED;;GAEG;AACH,iBAAe,kBAAkB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAkGxE;AAED;;GAEG;AACH,iBAAe,gBAAgB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAiGtE;AAED;;GAEG;AACH,iBAAS,cAAc,CAAC,MAAM,EAAE,eAAe,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CA2BrF;AAGD,eAAO,MAAM,iBAAiB;;;;;EAK5B,CAAC"}
|
|
@@ -48,6 +48,18 @@ const TARGET_DATABASE_ENV_KEYS = Object.freeze([
|
|
|
48
48
|
'D1_DATABASE',
|
|
49
49
|
'D1_DATABASE_ID',
|
|
50
50
|
]);
|
|
51
|
+
const uniq = (items) => {
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
const out = [];
|
|
54
|
+
for (const item of items) {
|
|
55
|
+
if (seen.has(item)) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
seen.add(item);
|
|
59
|
+
out.push(item);
|
|
60
|
+
}
|
|
61
|
+
return out;
|
|
62
|
+
};
|
|
51
63
|
const describeConfiguredD1Target = (config) => {
|
|
52
64
|
const parts = [];
|
|
53
65
|
if (typeof config.database_name === 'string' && config.database_name.trim() !== '') {
|
|
@@ -152,6 +164,117 @@ const resolveFlag = (options, optionKeys, envKeys) => {
|
|
|
152
164
|
}
|
|
153
165
|
return readEnvBool(envKeys) === true;
|
|
154
166
|
};
|
|
167
|
+
const encodeConnectionSegment = (value) => {
|
|
168
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (match) => {
|
|
169
|
+
return `%${match.charCodeAt(0).toString(16).toUpperCase()}`;
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
const decodeConnectionSegment = (value) => {
|
|
173
|
+
return value.trim() === '' ? '' : decodeURIComponent(value);
|
|
174
|
+
};
|
|
175
|
+
const getNetworkScheme = (sourceDriver) => {
|
|
176
|
+
if (sourceDriver === 'mysql')
|
|
177
|
+
return 'mysql';
|
|
178
|
+
if (sourceDriver === 'postgresql')
|
|
179
|
+
return 'postgresql';
|
|
180
|
+
if (sourceDriver === 'sqlserver')
|
|
181
|
+
return 'mssql';
|
|
182
|
+
return undefined;
|
|
183
|
+
};
|
|
184
|
+
const getDefaultNetworkPort = (sourceDriver) => {
|
|
185
|
+
if (sourceDriver === 'mysql')
|
|
186
|
+
return 3306;
|
|
187
|
+
if (sourceDriver === 'postgresql')
|
|
188
|
+
return 5432;
|
|
189
|
+
return 1433;
|
|
190
|
+
};
|
|
191
|
+
const parseNetworkConnectionDetails = (connectionString, sourceDriver) => {
|
|
192
|
+
const expectedScheme = getNetworkScheme(sourceDriver);
|
|
193
|
+
if (expectedScheme === undefined) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
try {
|
|
197
|
+
const parsed = new URL(connectionString);
|
|
198
|
+
const protocol = parsed.protocol.replace(/:$/, '').toLowerCase();
|
|
199
|
+
const allowedProtocols = sourceDriver === 'sqlserver' ? ['mssql', 'sqlserver'] : [expectedScheme];
|
|
200
|
+
if (!allowedProtocols.includes(protocol)) {
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
scheme: expectedScheme,
|
|
205
|
+
host: parsed.hostname || 'localhost',
|
|
206
|
+
port: parsed.port.trim() === ''
|
|
207
|
+
? getDefaultNetworkPort(sourceDriver)
|
|
208
|
+
: Number.parseInt(parsed.port, 10),
|
|
209
|
+
database: decodeConnectionSegment(parsed.pathname.replace(/^\/+/, '')),
|
|
210
|
+
username: decodeConnectionSegment(parsed.username),
|
|
211
|
+
password: decodeConnectionSegment(parsed.password),
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return undefined;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
const normalizeSourceConnectionString = (sourceConnection, sourceDriver) => {
|
|
219
|
+
const details = parseNetworkConnectionDetails(sourceConnection, sourceDriver);
|
|
220
|
+
if (details === undefined) {
|
|
221
|
+
return sourceConnection;
|
|
222
|
+
}
|
|
223
|
+
return buildNetworkConnectionString(details);
|
|
224
|
+
};
|
|
225
|
+
const redactConnectionString = (sourceConnection) => {
|
|
226
|
+
try {
|
|
227
|
+
const parsed = new URL(sourceConnection);
|
|
228
|
+
if (parsed.password.trim() !== '') {
|
|
229
|
+
parsed.password = '***';
|
|
230
|
+
}
|
|
231
|
+
return parsed.toString();
|
|
232
|
+
}
|
|
233
|
+
catch {
|
|
234
|
+
return sourceConnection;
|
|
235
|
+
}
|
|
236
|
+
};
|
|
237
|
+
const describePasswordForLog = (password) => {
|
|
238
|
+
const hasSpecialCharacters = /[^a-zA-Z0-9]/.test(password);
|
|
239
|
+
const containsBang = password.includes('!');
|
|
240
|
+
return `len=${password.length}, special_chars=${hasSpecialCharacters}, contains_bang=${containsBang}`;
|
|
241
|
+
};
|
|
242
|
+
const getErrorCause = (error) => {
|
|
243
|
+
if (error === null || typeof error !== 'object') {
|
|
244
|
+
return undefined;
|
|
245
|
+
}
|
|
246
|
+
return error.cause;
|
|
247
|
+
};
|
|
248
|
+
const getErrorMessage = (error) => {
|
|
249
|
+
if (error instanceof Error) {
|
|
250
|
+
return error.message;
|
|
251
|
+
}
|
|
252
|
+
return String(error);
|
|
253
|
+
};
|
|
254
|
+
const getErrorChainMessages = (error) => {
|
|
255
|
+
const messages = [];
|
|
256
|
+
let current = error;
|
|
257
|
+
while (current !== undefined) {
|
|
258
|
+
const message = getErrorMessage(current);
|
|
259
|
+
if (message.trim() !== '') {
|
|
260
|
+
messages.push(message);
|
|
261
|
+
}
|
|
262
|
+
current = getErrorCause(current);
|
|
263
|
+
}
|
|
264
|
+
return uniq(messages);
|
|
265
|
+
};
|
|
266
|
+
const logSourceConnectionDiagnostics = (sourceDriver, sourceConnection, origin, originalValue) => {
|
|
267
|
+
Logger.info(`[d1-migrator] Source connection origin: ${origin}`);
|
|
268
|
+
Logger.info(`[d1-migrator] Source connection driver: ${sourceDriver}`);
|
|
269
|
+
Logger.info(`[d1-migrator] Source connection (redacted): ${redactConnectionString(sourceConnection)}`);
|
|
270
|
+
const originalDetails = parseNetworkConnectionDetails(originalValue, sourceDriver);
|
|
271
|
+
const finalDetails = parseNetworkConnectionDetails(sourceConnection, sourceDriver);
|
|
272
|
+
if (originalDetails === undefined || finalDetails === undefined) {
|
|
273
|
+
Logger.info('[d1-migrator] Source connection diagnostics: non-network source or unable to parse URL');
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
Logger.info(`[d1-migrator] Source password diagnostics: provided(${describePasswordForLog(originalDetails.password)}), final(${describePasswordForLog(finalDetails.password)}), matches=${originalDetails.password === finalDetails.password}`);
|
|
277
|
+
};
|
|
155
278
|
const normalizeSourceDriver = (value) => {
|
|
156
279
|
if (value === undefined) {
|
|
157
280
|
return undefined;
|
|
@@ -188,9 +311,9 @@ const extractFirstHost = (value, fallback) => {
|
|
|
188
311
|
return host ?? fallback;
|
|
189
312
|
};
|
|
190
313
|
const buildNetworkConnectionString = ({ scheme, host, port, database, username, password, }) => {
|
|
191
|
-
const encodedUser =
|
|
192
|
-
const encodedPassword =
|
|
193
|
-
const encodedDatabase =
|
|
314
|
+
const encodedUser = encodeConnectionSegment(username);
|
|
315
|
+
const encodedPassword = encodeConnectionSegment(password);
|
|
316
|
+
const encodedDatabase = encodeConnectionSegment(database);
|
|
194
317
|
let auth = '';
|
|
195
318
|
if (encodedUser.length > 0) {
|
|
196
319
|
auth = `${encodedUser}@`;
|
|
@@ -267,15 +390,27 @@ const buildSourceConnectionFromDbEnv = (sourceDriver) => {
|
|
|
267
390
|
const resolveSourceConnection = (options, sourceDriver) => {
|
|
268
391
|
const fromOption = readOptionString(options, ['source-connection', 'sourceConnection']);
|
|
269
392
|
if (fromOption !== undefined) {
|
|
270
|
-
return
|
|
393
|
+
return {
|
|
394
|
+
value: normalizeSourceConnectionString(fromOption, sourceDriver),
|
|
395
|
+
origin: 'option',
|
|
396
|
+
originalValue: fromOption,
|
|
397
|
+
};
|
|
271
398
|
}
|
|
272
399
|
const fromEnv = readEnvString(SOURCE_CONNECTION_ENV_KEYS);
|
|
273
400
|
if (fromEnv !== undefined) {
|
|
274
|
-
return
|
|
401
|
+
return {
|
|
402
|
+
value: normalizeSourceConnectionString(fromEnv, sourceDriver),
|
|
403
|
+
origin: 'env',
|
|
404
|
+
originalValue: fromEnv,
|
|
405
|
+
};
|
|
275
406
|
}
|
|
276
407
|
const fromDbEnv = buildSourceConnectionFromDbEnv(sourceDriver);
|
|
277
408
|
if (fromDbEnv !== undefined && fromDbEnv.trim().length > 0) {
|
|
278
|
-
return
|
|
409
|
+
return {
|
|
410
|
+
value: normalizeSourceConnectionString(fromDbEnv, sourceDriver),
|
|
411
|
+
origin: 'db-env',
|
|
412
|
+
originalValue: fromDbEnv,
|
|
413
|
+
};
|
|
279
414
|
}
|
|
280
415
|
throw ErrorFactory.createValidationError('Source connection is required. Use --source-connection or set MIGRATE_TO_D1_SOURCE_CONNECTION (or DB_* variables)');
|
|
281
416
|
};
|
|
@@ -309,7 +444,7 @@ const resolveTargetDatabase = (options) => {
|
|
|
309
444
|
};
|
|
310
445
|
const resolveMigrationConfig = (options) => {
|
|
311
446
|
const sourceDriver = resolveSourceDriver(options);
|
|
312
|
-
const
|
|
447
|
+
const sourceConnectionResolution = resolveSourceConnection(options, sourceDriver);
|
|
313
448
|
const targetDatabase = resolveTargetDatabase(options);
|
|
314
449
|
const targetType = resolveTargetType(options);
|
|
315
450
|
const dryRun = resolveFlag(options, ['dry-run', 'dryRun'], ['MIGRATE_TO_D1_DRY_RUN', 'D1_MIGRATOR_DRY_RUN']);
|
|
@@ -323,7 +458,7 @@ const resolveMigrationConfig = (options) => {
|
|
|
323
458
|
}
|
|
324
459
|
return {
|
|
325
460
|
config: {
|
|
326
|
-
sourceConnection,
|
|
461
|
+
sourceConnection: sourceConnectionResolution.value,
|
|
327
462
|
sourceDriver,
|
|
328
463
|
targetDatabase,
|
|
329
464
|
targetType,
|
|
@@ -334,6 +469,8 @@ const resolveMigrationConfig = (options) => {
|
|
|
334
469
|
migrationId,
|
|
335
470
|
},
|
|
336
471
|
schemaOnly,
|
|
472
|
+
sourceConnectionOrigin: sourceConnectionResolution.origin,
|
|
473
|
+
originalSourceConnection: sourceConnectionResolution.originalValue,
|
|
337
474
|
};
|
|
338
475
|
};
|
|
339
476
|
/**
|
|
@@ -361,7 +498,8 @@ export const MigrateToD1Command = BaseCommand.create({
|
|
|
361
498
|
execute: async (options) => {
|
|
362
499
|
try {
|
|
363
500
|
Logger.info('Starting D1 migration process...');
|
|
364
|
-
const { config, schemaOnly } = resolveMigrationConfig(options);
|
|
501
|
+
const { config, schemaOnly, sourceConnectionOrigin, originalSourceConnection } = resolveMigrationConfig(options);
|
|
502
|
+
logSourceConnectionDiagnostics(config.sourceDriver, config.sourceConnection, sourceConnectionOrigin, originalSourceConnection);
|
|
365
503
|
const configValidation = validateConfig(config);
|
|
366
504
|
if (!configValidation.valid) {
|
|
367
505
|
throw ErrorFactory.createValidationError(`Invalid migration configuration: ${configValidation.errors.join(', ')}`);
|
|
@@ -414,8 +552,10 @@ export const MigrateToD1Command = BaseCommand.create({
|
|
|
414
552
|
Logger.info('D1 migration completed successfully');
|
|
415
553
|
}
|
|
416
554
|
catch (error) {
|
|
417
|
-
|
|
418
|
-
|
|
555
|
+
const errorChain = getErrorChainMessages(error);
|
|
556
|
+
Logger.error(`Migration failed: ${errorChain.join(' -> ')}`);
|
|
557
|
+
Logger.error('Migration failure details:', error);
|
|
558
|
+
throw ErrorFactory.createValidationError(`Migration failed: ${errorChain[0] ?? getErrorMessage(error)}`, error);
|
|
419
559
|
}
|
|
420
560
|
},
|
|
421
561
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SchemaAnalyzer.d.ts","sourceRoot":"","sources":["../../src/cli/SchemaAnalyzer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAOH,OAAO,KAAK,EACV,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,WAAW,EACZ,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"SchemaAnalyzer.d.ts","sourceRoot":"","sources":["../../src/cli/SchemaAnalyzer.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,42 @@ import { MySQLAdapter } from '@zintrust/db-mysql';
|
|
|
7
7
|
import { PostgreSQLAdapter } from '@zintrust/db-postgres';
|
|
8
8
|
import { SQLiteAdapter } from '@zintrust/db-sqlite';
|
|
9
9
|
import { SQLServerAdapter } from '@zintrust/db-sqlserver';
|
|
10
|
+
const redactConnectionString = (connectionString) => {
|
|
11
|
+
try {
|
|
12
|
+
const parsed = new URL(connectionString);
|
|
13
|
+
if (parsed.password.trim() !== '') {
|
|
14
|
+
parsed.password = '***';
|
|
15
|
+
}
|
|
16
|
+
return parsed.toString();
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return connectionString;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
const getErrorCause = (error) => {
|
|
23
|
+
if (error === null || typeof error !== 'object') {
|
|
24
|
+
return undefined;
|
|
25
|
+
}
|
|
26
|
+
return error.cause;
|
|
27
|
+
};
|
|
28
|
+
const getErrorMessage = (error) => {
|
|
29
|
+
if (error instanceof Error) {
|
|
30
|
+
return error.message;
|
|
31
|
+
}
|
|
32
|
+
return String(error);
|
|
33
|
+
};
|
|
34
|
+
const getErrorChainMessages = (error) => {
|
|
35
|
+
const messages = [];
|
|
36
|
+
let current = error;
|
|
37
|
+
while (current !== undefined) {
|
|
38
|
+
const message = getErrorMessage(current);
|
|
39
|
+
if (message.trim() !== '') {
|
|
40
|
+
messages.push(message);
|
|
41
|
+
}
|
|
42
|
+
current = getErrorCause(current);
|
|
43
|
+
}
|
|
44
|
+
return [...new Set(messages)];
|
|
45
|
+
};
|
|
10
46
|
/**
|
|
11
47
|
* SchemaAnalyzer - Sealed namespace for schema analysis
|
|
12
48
|
* Provides database schema analysis and compatibility checking
|
|
@@ -40,6 +76,7 @@ export const SchemaAnalyzer = Object.freeze({
|
|
|
40
76
|
*/
|
|
41
77
|
async extractTables(connection) {
|
|
42
78
|
Logger.info(`Extracting tables from ${connection.driver} database...`);
|
|
79
|
+
Logger.info(`[SchemaAnalyzer] Source connection (redacted): ${redactConnectionString(connection.connectionString)}`);
|
|
43
80
|
try {
|
|
44
81
|
// Create appropriate adapter based on driver
|
|
45
82
|
let adapter;
|
|
@@ -79,8 +116,10 @@ export const SchemaAnalyzer = Object.freeze({
|
|
|
79
116
|
return tableSchemas;
|
|
80
117
|
}
|
|
81
118
|
catch (error) {
|
|
82
|
-
|
|
83
|
-
|
|
119
|
+
const errorChain = getErrorChainMessages(error);
|
|
120
|
+
Logger.error(`Failed to extract database tables: ${errorChain.join(' -> ')}`);
|
|
121
|
+
Logger.error('Schema extraction failure details:', error);
|
|
122
|
+
throw ErrorFactory.createTryCatchError(`Schema extraction failed: ${errorChain[0] ?? getErrorMessage(error)}`, error);
|
|
84
123
|
}
|
|
85
124
|
},
|
|
86
125
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zintrust/d1-migrator",
|
|
3
|
-
"version": "1.8.
|
|
3
|
+
"version": "1.8.2",
|
|
4
4
|
"description": "Resumable database migration toolkit for moving data to Cloudflare D1 with ZinTrust.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -40,10 +40,10 @@
|
|
|
40
40
|
"prepublishOnly": "npm run build"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@zintrust/db-mysql": "1.
|
|
44
|
-
"@zintrust/db-postgres": "1.
|
|
45
|
-
"@zintrust/db-sqlite": "1.
|
|
46
|
-
"@zintrust/db-sqlserver": "1.
|
|
47
|
-
"@zintrust/db-d1": "1.
|
|
43
|
+
"@zintrust/db-mysql": "1.8.0",
|
|
44
|
+
"@zintrust/db-postgres": "1.8.0",
|
|
45
|
+
"@zintrust/db-sqlite": "1.8.0",
|
|
46
|
+
"@zintrust/db-sqlserver": "1.8.0",
|
|
47
|
+
"@zintrust/db-d1": "1.8.0"
|
|
48
48
|
}
|
|
49
|
-
}
|
|
49
|
+
}
|