@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.
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@zintrust/d1-migrator",
3
- "version": "1.8.0",
4
- "buildDate": "2026-05-04T17:51:37.015Z",
3
+ "version": "1.7.1",
4
+ "buildDate": "2026-05-01T05:26:52.011Z",
5
5
  "buildEnvironment": {
6
- "node": "v20.20.2",
7
- "platform": "linux",
8
- "arch": "x64"
6
+ "node": "v22.22.1",
7
+ "platform": "darwin",
8
+ "arch": "arm64"
9
9
  },
10
10
  "git": {
11
- "commit": "b1d6ed34",
12
- "branch": "master"
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": "4ad679c987f7eba3bdbc81acfe4fac600bc084cd0cfd44c53294ae3ac0bd9f18"
40
+ "sha256": "be301eb96726a2611e9f739c5f57b536b24243413ad100effc7afce905d83e81"
37
41
  },
38
42
  "cli/DataMigrator.js": {
39
- "size": 18591,
40
- "sha256": "b8002c2a5754b3a851282e45eebc38658f7c55119b7bafa722cd0bd155fc20b3"
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": "e553a989eb52524da375e412870ff0f57d52cdd26840c2761cf27a15f3151901"
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": 1523,
104
- "sha256": "efdf6d8b601de9ccf222be2c67c3730c1c714677f584ba6931225fda7f009f02"
107
+ "size": 1443,
108
+ "sha256": "46c568eef17ab0b0b1a59cfef0bf06f85d06de6e6d5479429e6a566b43ec87a7"
105
109
  },
106
110
  "schema/SchemaBuilder.d.ts.map": {
107
- "size": 712,
108
- "sha256": "ba0bfbf6f5c4bc743e5dc8578c1b641b46d393ccfe7081d8a45a85c4e8c270ff"
111
+ "size": 670,
112
+ "sha256": "6ee501ff68e7d23fbb14f3f24167606346826392c8782153920b5d27cbb3348f"
109
113
  },
110
114
  "schema/SchemaBuilder.js": {
111
- "size": 8424,
112
- "sha256": "97707408514eda3654e26b16f62d3ed716d60d8111688dba4e53fcd575a9a970"
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;AAsEF;;;GAGG;AACH,eAAO,MAAM,YAAY;IACvB;;OAEG;wBACuB,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmFtE;;OAEG;4BAC2B,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoEzE;;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"}
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"}
@@ -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
- Logger.error('Data migration failed:', error);
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: ${config.sourceConnection}`);
137
- let adapter;
138
- switch (config.sourceDriver) {
139
- case 'mysql':
140
- adapter = MySQLAdapter.create({
141
- driver: 'mysql',
142
- connectionString: config.sourceConnection,
143
- });
144
- break;
145
- case 'postgresql': {
146
- const connectionDetails = parseConnectionDetails(config.sourceConnection, 5432, 'postgres', 'postgres');
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;AAkgBF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,iBAgG/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"}
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 = encodeURIComponent(username);
192
- const encodedPassword = encodeURIComponent(password);
193
- const encodedDatabase = encodeURIComponent(database);
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 fromOption;
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 fromEnv;
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 fromDbEnv;
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 sourceConnection = resolveSourceConnection(options, sourceDriver);
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
- Logger.error('Migration failed:', error);
418
- throw ErrorFactory.createValidationError(`Migration failed: ${error}`);
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":"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"}
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
- Logger.error('Failed to extract database tables:', error);
83
- throw ErrorFactory.createTryCatchError('Schema extraction failed', error);
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.0",
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.7.2",
44
- "@zintrust/db-postgres": "1.7.0",
45
- "@zintrust/db-sqlite": "1.7.2",
46
- "@zintrust/db-sqlserver": "1.7.0",
47
- "@zintrust/db-d1": "1.7.0"
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
+ }