@abtnode/core 1.16.47-beta-20250717-221700-2d886a18 → 1.16.47-beta-20250721-025348-9ccb2d62

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.
@@ -32,7 +32,7 @@ async function checkNeedRunDocker(meta = {}, env = {}, nodeInfo = {}, isExternal
32
32
  // Ensure Docker is installed
33
33
  if (!nodeInfo.isDockerInstalled) {
34
34
  if (!(await checkDockerInstalled())) {
35
- throw new Error('Docker is not installed');
35
+ throw new Error('Docker mode is enabled, but the Docker CLI was not found.');
36
36
  }
37
37
  }
38
38
  return true;
@@ -1,30 +1,50 @@
1
+ /* eslint-disable no-await-in-loop */
2
+
1
3
  const path = require('path');
2
4
  const { spawn } = require('child_process');
3
5
  const fsp = require('fs/promises');
4
6
  const os = require('os');
7
+ const logger = require('@abtnode/logger')('@abtnode/core:util:ensure-bun');
8
+ const shelljs = require('shelljs');
9
+ const semver = require('semver');
5
10
 
6
- const BUN_VERSION = '1.2.18';
11
+ const IS_WINDOWS = process.platform === 'win32';
12
+ const BUN_VERSION = IS_WINDOWS ? '1.2.4' : '1.2.18';
7
13
 
8
14
  const getRootDir = () => {
9
15
  if (process.env.ABT_NODE_DATA_DIR) {
10
16
  return process.env.ABT_NODE_DATA_DIR;
11
17
  }
12
- return path.join(os.tmpdir(), 'bun_install');
18
+ const homeDir = os.homedir();
19
+ if (homeDir) {
20
+ return path.join(homeDir, '.blocklet-bun');
21
+ }
22
+ return path.join(os.tmpdir(), '.blocklet-bun');
13
23
  };
14
24
 
15
25
  async function _ensureBun() {
16
- const bunDir = path.join(getRootDir(), 'core', 'bun_install');
17
- try {
18
- await fsp.access(bunDir);
19
- } catch {
20
- await fsp.mkdir(bunDir, { recursive: true });
21
- }
22
-
26
+ const bunDir = path.join(getRootDir(), 'core', 'bun-install');
27
+ await fsp.mkdir(bunDir, { recursive: true }).catch(() => {});
23
28
  const installDir = path.join(bunDir, BUN_VERSION);
24
29
  const binDir = path.join(installDir, 'bin');
25
- const bunExec = path.join(binDir, process.platform === 'win32' ? 'bun.exe' : 'bun');
30
+ const bunExec = path.join(binDir, IS_WINDOWS ? 'bun.exe' : 'bun');
31
+
32
+ const ignoreWhichBun = process.env.ABT_NODE_IGNORE_WHICH_BUN === 'true';
33
+
34
+ if (!ignoreWhichBun) {
35
+ const whichBun = shelljs.which('bun');
36
+ // 如果有 bun 且版本大于等于 BUN_VERSION, 则直接使用现有的 bun
37
+ if (whichBun) {
38
+ // 检查 bun 版本
39
+ const bunVersion = shelljs.exec(`${whichBun} --version`).stdout.trim();
40
+ // 判断 bun 版本是否大于等于 BUN_VERSION, 应该用版本对比库
41
+ if (semver.gte(bunVersion, BUN_VERSION)) {
42
+ return whichBun.toString();
43
+ }
44
+ }
45
+ }
26
46
 
27
- // If bun is already installed in this project, return its path
47
+ // If already installed, return immediately
28
48
  try {
29
49
  await fsp.access(bunExec);
30
50
  return bunExec;
@@ -32,29 +52,20 @@ async function _ensureBun() {
32
52
  //
33
53
  }
34
54
 
35
- // Create installation directory
55
+ logger.info(`Bun not found; installing to: ${installDir}`);
36
56
  await fsp.mkdir(installDir, { recursive: true });
37
57
 
38
- // Run the official Bun installer script with BUN_INSTALL overridden
39
- await new Promise((resolvePromise, reject) => {
40
- const linuxInstall = ['-c', 'curl -fsSL https://bun.sh/install | bash'];
41
- const windowsInstall = ['-c', 'powershell -c "irm bun.sh/install.ps1 | iex"'];
42
- const installer = spawn('bash', process.platform === 'win32' ? windowsInstall : linuxInstall, {
58
+ // Run official Bun installer script
59
+ await new Promise((resolve, reject) => {
60
+ const cmd = IS_WINDOWS
61
+ ? ['-c', 'powershell -c "irm bun.sh/install.ps1 | iex"']
62
+ : ['-c', 'curl -fsSL https://bun.sh/install | bash'];
63
+ const installer = spawn('bash', cmd, {
43
64
  env: { ...process.env, BUN_INSTALL: installDir, BUN_VERSION, SHELL: '/dev/null', HOME: installDir },
44
65
  stdio: 'inherit',
45
66
  });
46
-
47
- installer.on('close', (code) => {
48
- if (code !== 0) {
49
- reject(new Error(`Bun installation failed with exit code ${code}`));
50
- } else {
51
- resolvePromise();
52
- }
53
- });
54
-
55
- installer.on('error', (err) => {
56
- reject(err);
57
- });
67
+ installer.on('close', (code) => (code === 0 ? resolve() : reject(new Error(`Installer exited with code ${code}`))));
68
+ installer.on('error', reject);
58
69
  });
59
70
 
60
71
  return bunExec;
@@ -67,7 +78,26 @@ const ensureBun = async () => {
67
78
  if (bunPathPromise) {
68
79
  return bunPathPromise;
69
80
  }
70
- bunPathPromise = _ensureBun();
81
+ bunPathPromise = (async () => {
82
+ const maxAttempts = 5;
83
+ let lastError;
84
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
85
+ try {
86
+ const bunExecPath = await _ensureBun();
87
+ // Verify executable exists
88
+ await fsp.access(bunExecPath);
89
+ logger.info(`Bun installation succeeded: ${bunExecPath}`);
90
+ return bunExecPath;
91
+ } catch (err) {
92
+ lastError = err;
93
+ logger.error(`Installation attempt ${attempt} failed: ${err.message}`);
94
+ if (attempt < maxAttempts) {
95
+ logger.info(`Retrying installation (${attempt + 1}/${maxAttempts})...`);
96
+ }
97
+ }
98
+ }
99
+ throw new Error(`All ${maxAttempts} installation attempts failed: ${lastError.message}`);
100
+ })();
71
101
  return bunPathPromise;
72
102
  };
73
103
 
@@ -76,18 +106,13 @@ const bunOptions = {
76
106
  };
77
107
 
78
108
  const getBunCacheDir = async (isDocker = false) => {
79
- const abtNodeDir = getRootDir();
80
- // 如果不是linux, 缓存的目录区分 docker 和非 docker
109
+ const bunDir = getRootDir();
81
110
  let cacheDir = isDocker ? 'bun-cache-docker' : 'bun-cache';
82
111
  if (os.type() === bunOptions.baseDockerOs) {
83
112
  cacheDir = 'bun-cache';
84
113
  }
85
- const bunCacheDir = path.join(abtNodeDir, 'tmp', cacheDir);
86
- try {
87
- await fsp.access(bunCacheDir);
88
- } catch (_) {
89
- await fsp.mkdir(bunCacheDir, { recursive: true });
90
- }
114
+ const bunCacheDir = path.join(bunDir, 'tmp', cacheDir);
115
+ await fsp.mkdir(bunCacheDir, { recursive: true }).catch(() => {});
91
116
  return bunCacheDir;
92
117
  };
93
118
 
@@ -55,7 +55,7 @@ async function installExternalDependencies({ appDir, forceInstall = false, nodeI
55
55
  await new Promise((resolve, reject) => {
56
56
  const child = spawn(bunPath, ['install'], {
57
57
  cwd: appDir,
58
- stdio: 'pipe',
58
+ stdio: 'inherit',
59
59
  shell: true,
60
60
  env: {
61
61
  ...process.env,
@@ -64,14 +64,9 @@ async function installExternalDependencies({ appDir, forceInstall = false, nodeI
64
64
  },
65
65
  });
66
66
 
67
- let errorOutput = '';
68
- child.stderr.on('data', (data) => {
69
- errorOutput += data.toString();
70
- });
71
-
72
67
  child.on('close', (code) => {
73
- if (code !== 0 && errorOutput.trim()) {
74
- reject(new Error(errorOutput));
68
+ if (code !== 0) {
69
+ reject(new Error(`exit code ${code}`));
75
70
  } else {
76
71
  resolve();
77
72
  }
@@ -127,7 +127,6 @@ async function migrateAllTablesNoModels(dbPath) {
127
127
  VALUES (${placeholders});
128
128
  `;
129
129
  }
130
-
131
130
  // Batch‐migrate rows
132
131
  const batchSize = 1000;
133
132
  let offset = 0;
@@ -245,6 +244,27 @@ async function migrateAllTablesNoModels(dbPath) {
245
244
  console.log(' ❌ Ignore error for enum_webhook_attempts_status');
246
245
  continue;
247
246
  }
247
+ if (err.message.includes('connected_accounts_userDid_fkey')) {
248
+ const violationFilePath = dbPath.replace('.db', '.connected_accounts_violation.json');
249
+ console.log(
250
+ ' ❌ Ignore error for connected_accounts_userDid_fkey',
251
+ err.message,
252
+ 'save to:',
253
+ violationFilePath,
254
+ 'count: '
255
+ );
256
+ try {
257
+ await fsp.appendFile(
258
+ violationFilePath,
259
+ // eslint-disable-next-line prefer-template
260
+ JSON.stringify({ table: tableName, row, error: 'connected_accounts_userDid_fkey' }) + '\n',
261
+ 'utf8'
262
+ );
263
+ } catch (writeErr) {
264
+ console.warn(' ⚠️ Failed to write violation record:', writeErr);
265
+ }
266
+ continue;
267
+ }
248
268
  throw err;
249
269
  }
250
270
  }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.16.47-beta-20250717-221700-2d886a18",
6
+ "version": "1.16.47-beta-20250721-025348-9ccb2d62",
7
7
  "description": "",
8
8
  "main": "lib/index.js",
9
9
  "files": [
@@ -19,22 +19,22 @@
19
19
  "author": "wangshijun <wangshijun2010@gmail.com> (http://github.com/wangshijun)",
20
20
  "license": "Apache-2.0",
21
21
  "dependencies": {
22
- "@abtnode/analytics": "1.16.47-beta-20250717-221700-2d886a18",
23
- "@abtnode/auth": "1.16.47-beta-20250717-221700-2d886a18",
24
- "@abtnode/certificate-manager": "1.16.47-beta-20250717-221700-2d886a18",
25
- "@abtnode/client": "1.16.47-beta-20250717-221700-2d886a18",
26
- "@abtnode/constant": "1.16.47-beta-20250717-221700-2d886a18",
27
- "@abtnode/cron": "1.16.47-beta-20250717-221700-2d886a18",
28
- "@abtnode/db-cache": "1.16.47-beta-20250717-221700-2d886a18",
29
- "@abtnode/docker-utils": "1.16.47-beta-20250717-221700-2d886a18",
30
- "@abtnode/logger": "1.16.47-beta-20250717-221700-2d886a18",
31
- "@abtnode/models": "1.16.47-beta-20250717-221700-2d886a18",
32
- "@abtnode/queue": "1.16.47-beta-20250717-221700-2d886a18",
33
- "@abtnode/rbac": "1.16.47-beta-20250717-221700-2d886a18",
34
- "@abtnode/router-provider": "1.16.47-beta-20250717-221700-2d886a18",
35
- "@abtnode/static-server": "1.16.47-beta-20250717-221700-2d886a18",
36
- "@abtnode/timemachine": "1.16.47-beta-20250717-221700-2d886a18",
37
- "@abtnode/util": "1.16.47-beta-20250717-221700-2d886a18",
22
+ "@abtnode/analytics": "1.16.47-beta-20250721-025348-9ccb2d62",
23
+ "@abtnode/auth": "1.16.47-beta-20250721-025348-9ccb2d62",
24
+ "@abtnode/certificate-manager": "1.16.47-beta-20250721-025348-9ccb2d62",
25
+ "@abtnode/client": "1.16.47-beta-20250721-025348-9ccb2d62",
26
+ "@abtnode/constant": "1.16.47-beta-20250721-025348-9ccb2d62",
27
+ "@abtnode/cron": "1.16.47-beta-20250721-025348-9ccb2d62",
28
+ "@abtnode/db-cache": "1.16.47-beta-20250721-025348-9ccb2d62",
29
+ "@abtnode/docker-utils": "1.16.47-beta-20250721-025348-9ccb2d62",
30
+ "@abtnode/logger": "1.16.47-beta-20250721-025348-9ccb2d62",
31
+ "@abtnode/models": "1.16.47-beta-20250721-025348-9ccb2d62",
32
+ "@abtnode/queue": "1.16.47-beta-20250721-025348-9ccb2d62",
33
+ "@abtnode/rbac": "1.16.47-beta-20250721-025348-9ccb2d62",
34
+ "@abtnode/router-provider": "1.16.47-beta-20250721-025348-9ccb2d62",
35
+ "@abtnode/static-server": "1.16.47-beta-20250721-025348-9ccb2d62",
36
+ "@abtnode/timemachine": "1.16.47-beta-20250721-025348-9ccb2d62",
37
+ "@abtnode/util": "1.16.47-beta-20250721-025348-9ccb2d62",
38
38
  "@arcblock/did": "1.20.16",
39
39
  "@arcblock/did-auth": "1.20.16",
40
40
  "@arcblock/did-ext": "1.20.16",
@@ -45,14 +45,14 @@
45
45
  "@arcblock/pm2-events": "^0.0.5",
46
46
  "@arcblock/validator": "1.20.16",
47
47
  "@arcblock/vc": "1.20.16",
48
- "@blocklet/constant": "1.16.47-beta-20250717-221700-2d886a18",
48
+ "@blocklet/constant": "1.16.47-beta-20250721-025348-9ccb2d62",
49
49
  "@blocklet/did-space-js": "^1.1.7",
50
- "@blocklet/env": "1.16.47-beta-20250717-221700-2d886a18",
50
+ "@blocklet/env": "1.16.47-beta-20250721-025348-9ccb2d62",
51
51
  "@blocklet/error": "^0.2.5",
52
- "@blocklet/meta": "1.16.47-beta-20250717-221700-2d886a18",
53
- "@blocklet/resolver": "1.16.47-beta-20250717-221700-2d886a18",
54
- "@blocklet/sdk": "1.16.47-beta-20250717-221700-2d886a18",
55
- "@blocklet/store": "1.16.47-beta-20250717-221700-2d886a18",
52
+ "@blocklet/meta": "1.16.47-beta-20250721-025348-9ccb2d62",
53
+ "@blocklet/resolver": "1.16.47-beta-20250721-025348-9ccb2d62",
54
+ "@blocklet/sdk": "1.16.47-beta-20250721-025348-9ccb2d62",
55
+ "@blocklet/store": "1.16.47-beta-20250721-025348-9ccb2d62",
56
56
  "@blocklet/theme": "^3.0.26",
57
57
  "@fidm/x509": "^1.2.1",
58
58
  "@ocap/mcrypto": "1.20.16",
@@ -116,5 +116,5 @@
116
116
  "jest": "^29.7.0",
117
117
  "unzipper": "^0.10.11"
118
118
  },
119
- "gitHead": "e8c5b883906dd53ba9c288cd5609cf7d023d90b3"
119
+ "gitHead": "e51fdc32b26511dd1d2297659e9aa5fa83768c40"
120
120
  }