@abtnode/core 1.17.5-beta-20251208-123021-e8c53f96 → 1.17.5-beta-20251211-104355-426d7eb6
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/lib/blocklet/manager/disk.js +49 -13
- package/lib/blocklet/manager/helper/blue-green-start-blocklet.js +100 -70
- package/lib/blocklet/migration-dist/migration.cjs +10 -2
- package/lib/event/index.js +39 -0
- package/lib/migrations/index.js +4 -4
- package/lib/monitor/blocklet-runtime-monitor.js +3 -5
- package/lib/states/blocklet-child.js +119 -0
- package/lib/states/blocklet.js +264 -11
- package/lib/states/index.js +4 -1
- package/lib/util/blocklet.js +116 -51
- package/lib/util/default-node-config.js +5 -1
- package/lib/util/migration-sqlite-to-postgres.js +79 -6
- package/package.json +24 -24
|
@@ -94,6 +94,14 @@ async function migrateAllTablesNoModels(dbPath) {
|
|
|
94
94
|
.filter(([, def]) => def.type && ['JSON', 'JSONB'].includes(def.type.toUpperCase()))
|
|
95
95
|
.map(([col, def]) => ({ name: col, type: def.type.toUpperCase() }));
|
|
96
96
|
|
|
97
|
+
// find DATE/TIMESTAMP columns (need to validate and fix invalid dates)
|
|
98
|
+
const dateCols = Object.entries(pgSchema)
|
|
99
|
+
.filter(([, def]) => {
|
|
100
|
+
const type = def.type?.toUpperCase() || '';
|
|
101
|
+
return type.includes('DATE') || type.includes('TIMESTAMP') || type === 'DATE' || type.startsWith('TIMESTAMP');
|
|
102
|
+
})
|
|
103
|
+
.map(([col]) => col);
|
|
104
|
+
|
|
97
105
|
// find auto-increment columns (nextval default)
|
|
98
106
|
const autoIncCols = Object.entries(pgSchema)
|
|
99
107
|
.filter(([, def]) => typeof def.defaultValue === 'string' && def.defaultValue.startsWith('nextval('))
|
|
@@ -159,12 +167,37 @@ async function migrateAllTablesNoModels(dbPath) {
|
|
|
159
167
|
console.log(` Migrating rows ${offset + 1}-${offset + rows.length}`);
|
|
160
168
|
|
|
161
169
|
for (const row of rows) {
|
|
162
|
-
//
|
|
163
|
-
|
|
164
|
-
row
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
170
|
+
// Fix invalid date values for all DATE/TIMESTAMP columns
|
|
171
|
+
for (const dateCol of dateCols) {
|
|
172
|
+
if (row[dateCol] != null) {
|
|
173
|
+
const dateVal = row[dateCol];
|
|
174
|
+
// Check if it's an invalid date (NaN, "Invalid date" string, or invalid Date object)
|
|
175
|
+
let isValid = false;
|
|
176
|
+
if (dateVal instanceof Date) {
|
|
177
|
+
isValid = !Number.isNaN(dateVal.getTime());
|
|
178
|
+
} else if (typeof dateVal === 'string') {
|
|
179
|
+
// Check for "Invalid date" string or empty string
|
|
180
|
+
if (dateVal === 'Invalid date' || dateVal === '' || dateVal === 'null') {
|
|
181
|
+
isValid = false;
|
|
182
|
+
} else {
|
|
183
|
+
const parsed = new Date(dateVal);
|
|
184
|
+
isValid = !Number.isNaN(parsed.getTime());
|
|
185
|
+
}
|
|
186
|
+
} else if (typeof dateVal === 'number') {
|
|
187
|
+
// Check if it's a valid timestamp
|
|
188
|
+
const parsed = new Date(dateVal);
|
|
189
|
+
isValid = !Number.isNaN(parsed.getTime());
|
|
190
|
+
} else {
|
|
191
|
+
// null or undefined are valid (will be handled by allowNull)
|
|
192
|
+
isValid = true;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
if (!isValid) {
|
|
196
|
+
console.warn(` ⚠️ ${tableName}: Invalid date in column "${dateCol}", fixing to current time`);
|
|
197
|
+
console.log(` Old value: ${dateVal} (type: ${typeof dateVal})`);
|
|
198
|
+
row[dateCol] = new Date();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
168
201
|
}
|
|
169
202
|
|
|
170
203
|
// 修复不合格的旧数据
|
|
@@ -266,6 +299,46 @@ async function migrateAllTablesNoModels(dbPath) {
|
|
|
266
299
|
console.error(` ❌ ${tableName}: string too long for VARCHAR columns:`, badCols);
|
|
267
300
|
continue;
|
|
268
301
|
}
|
|
302
|
+
// Handle invalid timestamp/date errors - should have been fixed above, but log if still occurs
|
|
303
|
+
const timestampErr = err.message.match(/invalid input syntax for type timestamp/i);
|
|
304
|
+
if (timestampErr) {
|
|
305
|
+
console.error(` ❌ ${tableName}: Invalid timestamp error (should have been fixed):`, err.message);
|
|
306
|
+
console.log(' Row data:', JSON.stringify(row, null, 2));
|
|
307
|
+
// Try to fix and retry once
|
|
308
|
+
let fixed = false;
|
|
309
|
+
for (const dateCol of dateCols) {
|
|
310
|
+
if (row[dateCol] != null) {
|
|
311
|
+
const dateVal = row[dateCol];
|
|
312
|
+
if (
|
|
313
|
+
dateVal === 'Invalid date' ||
|
|
314
|
+
dateVal === '' ||
|
|
315
|
+
(typeof dateVal === 'string' && dateVal.toLowerCase() === 'null')
|
|
316
|
+
) {
|
|
317
|
+
row[dateCol] = new Date();
|
|
318
|
+
fixed = true;
|
|
319
|
+
} else {
|
|
320
|
+
const parsed = new Date(dateVal);
|
|
321
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
322
|
+
row[dateCol] = new Date();
|
|
323
|
+
fixed = true;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (fixed) {
|
|
329
|
+
console.log(' 🔧 Fixed invalid dates, retrying insert...');
|
|
330
|
+
const retryBindVals = insertCols.map((c) => row[c]);
|
|
331
|
+
try {
|
|
332
|
+
await pgDb.query(upsertSQL, { bind: retryBindVals });
|
|
333
|
+
continue;
|
|
334
|
+
} catch (retryErr) {
|
|
335
|
+
console.error(' ❌ Retry failed:', retryErr.message);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
// If still failing, skip this row
|
|
339
|
+
console.warn(' ⚠️ Skipping row due to timestamp error');
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
269
342
|
console.error(` ❌ Upsert failed for ${tableName} : ${err.message}, SQL:${upsertSQL} value: ${bindVals}`);
|
|
270
343
|
if (ignoreErrorTableNames.has(tableName)) {
|
|
271
344
|
console.log(` ❌ Ignore error for ${tableName}`);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "1.17.5-beta-
|
|
6
|
+
"version": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
7
7
|
"description": "",
|
|
8
8
|
"main": "lib/index.js",
|
|
9
9
|
"files": [
|
|
@@ -17,21 +17,21 @@
|
|
|
17
17
|
"author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
|
|
18
18
|
"license": "Apache-2.0",
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@abtnode/analytics": "1.17.5-beta-
|
|
21
|
-
"@abtnode/auth": "1.17.5-beta-
|
|
22
|
-
"@abtnode/certificate-manager": "1.17.5-beta-
|
|
23
|
-
"@abtnode/constant": "1.17.5-beta-
|
|
24
|
-
"@abtnode/cron": "1.17.5-beta-
|
|
25
|
-
"@abtnode/db-cache": "1.17.5-beta-
|
|
26
|
-
"@abtnode/docker-utils": "1.17.5-beta-
|
|
27
|
-
"@abtnode/logger": "1.17.5-beta-
|
|
28
|
-
"@abtnode/models": "1.17.5-beta-
|
|
29
|
-
"@abtnode/queue": "1.17.5-beta-
|
|
30
|
-
"@abtnode/rbac": "1.17.5-beta-
|
|
31
|
-
"@abtnode/router-provider": "1.17.5-beta-
|
|
32
|
-
"@abtnode/static-server": "1.17.5-beta-
|
|
33
|
-
"@abtnode/timemachine": "1.17.5-beta-
|
|
34
|
-
"@abtnode/util": "1.17.5-beta-
|
|
20
|
+
"@abtnode/analytics": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
21
|
+
"@abtnode/auth": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
22
|
+
"@abtnode/certificate-manager": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
23
|
+
"@abtnode/constant": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
24
|
+
"@abtnode/cron": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
25
|
+
"@abtnode/db-cache": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
26
|
+
"@abtnode/docker-utils": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
27
|
+
"@abtnode/logger": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
28
|
+
"@abtnode/models": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
29
|
+
"@abtnode/queue": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
30
|
+
"@abtnode/rbac": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
31
|
+
"@abtnode/router-provider": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
32
|
+
"@abtnode/static-server": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
33
|
+
"@abtnode/timemachine": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
34
|
+
"@abtnode/util": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
35
35
|
"@aigne/aigne-hub": "^0.10.10",
|
|
36
36
|
"@arcblock/did": "^1.27.12",
|
|
37
37
|
"@arcblock/did-connect-js": "^1.27.12",
|
|
@@ -43,15 +43,15 @@
|
|
|
43
43
|
"@arcblock/pm2-events": "^0.0.5",
|
|
44
44
|
"@arcblock/validator": "^1.27.12",
|
|
45
45
|
"@arcblock/vc": "^1.27.12",
|
|
46
|
-
"@blocklet/constant": "1.17.5-beta-
|
|
46
|
+
"@blocklet/constant": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
47
47
|
"@blocklet/did-space-js": "^1.2.6",
|
|
48
|
-
"@blocklet/env": "1.17.5-beta-
|
|
48
|
+
"@blocklet/env": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
49
49
|
"@blocklet/error": "^0.3.3",
|
|
50
|
-
"@blocklet/meta": "1.17.5-beta-
|
|
51
|
-
"@blocklet/resolver": "1.17.5-beta-
|
|
52
|
-
"@blocklet/sdk": "1.17.5-beta-
|
|
53
|
-
"@blocklet/server-js": "1.17.5-beta-
|
|
54
|
-
"@blocklet/store": "1.17.5-beta-
|
|
50
|
+
"@blocklet/meta": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
51
|
+
"@blocklet/resolver": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
52
|
+
"@blocklet/sdk": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
53
|
+
"@blocklet/server-js": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
54
|
+
"@blocklet/store": "1.17.5-beta-20251211-104355-426d7eb6",
|
|
55
55
|
"@blocklet/theme": "^3.2.11",
|
|
56
56
|
"@fidm/x509": "^1.2.1",
|
|
57
57
|
"@ocap/mcrypto": "^1.27.12",
|
|
@@ -116,5 +116,5 @@
|
|
|
116
116
|
"express": "^4.18.2",
|
|
117
117
|
"unzipper": "^0.10.11"
|
|
118
118
|
},
|
|
119
|
-
"gitHead": "
|
|
119
|
+
"gitHead": "9ea2a8077a8edbf5021281e823719758eb9fe02c"
|
|
120
120
|
}
|