pgserve 1.1.3-rc.2 → 1.1.3-rc.6
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/.github/workflows/build-all-platforms.yml +39 -15
- package/README.md +11 -0
- package/assets/icon.ico +0 -0
- package/bin/pgserve-wrapper.cjs +75 -53
- package/bun.lock +3 -1
- package/package.json +2 -2
- package/src/postgres.js +161 -7
|
@@ -38,26 +38,26 @@ concurrency:
|
|
|
38
38
|
jobs:
|
|
39
39
|
build:
|
|
40
40
|
name: Build ${{ matrix.platform }}
|
|
41
|
-
runs-on:
|
|
41
|
+
runs-on: ${{ matrix.os }}
|
|
42
42
|
strategy:
|
|
43
43
|
fail-fast: false
|
|
44
44
|
matrix:
|
|
45
45
|
include:
|
|
46
|
-
|
|
47
|
-
|
|
46
|
+
# Linux x64
|
|
47
|
+
- platform: linux-x64
|
|
48
|
+
pg_pkg: linux-x64
|
|
48
49
|
output: pgserve-linux-x64
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
platform: darwin-x64
|
|
54
|
-
output: pgserve-darwin-x64
|
|
55
|
-
- target: bun-darwin-arm64
|
|
56
|
-
platform: darwin-arm64
|
|
50
|
+
os: ubuntu-latest
|
|
51
|
+
# macOS ARM64 (Apple Silicon) - must build on macOS for native binaries
|
|
52
|
+
- platform: darwin-arm64
|
|
53
|
+
pg_pkg: darwin-arm64
|
|
57
54
|
output: pgserve-darwin-arm64
|
|
58
|
-
|
|
59
|
-
|
|
55
|
+
os: macos-latest
|
|
56
|
+
# Windows x64 - must build on Windows for --windows-icon
|
|
57
|
+
- platform: windows-x64
|
|
58
|
+
pg_pkg: windows-x64
|
|
60
59
|
output: pgserve-windows-x64.exe
|
|
60
|
+
os: windows-latest
|
|
61
61
|
|
|
62
62
|
steps:
|
|
63
63
|
- name: Checkout
|
|
@@ -73,10 +73,33 @@ jobs:
|
|
|
73
73
|
- name: Install dependencies
|
|
74
74
|
run: bun install
|
|
75
75
|
|
|
76
|
+
# Bundle PostgreSQL binaries for standalone exe
|
|
77
|
+
- name: Bundle PostgreSQL binaries
|
|
78
|
+
run: |
|
|
79
|
+
echo "Installing @embedded-postgres/${{ matrix.pg_pkg }}..."
|
|
80
|
+
npm install @embedded-postgres/${{ matrix.pg_pkg }}
|
|
81
|
+
mkdir -p embedded-postgres
|
|
82
|
+
cp -r node_modules/@embedded-postgres/${{ matrix.pg_pkg }}/native/* embedded-postgres/
|
|
83
|
+
echo "Bundled PostgreSQL binaries:"
|
|
84
|
+
ls -la embedded-postgres/
|
|
85
|
+
ls -la embedded-postgres/bin/ || true
|
|
86
|
+
shell: bash
|
|
87
|
+
|
|
88
|
+
# Windows: native build with custom icon
|
|
89
|
+
- name: Build for Windows (with icon)
|
|
90
|
+
if: matrix.platform == 'windows-x64'
|
|
91
|
+
run: |
|
|
92
|
+
mkdir -p dist
|
|
93
|
+
bun build --compile --windows-icon=assets/icon.ico bin/pglite-server.js --outfile dist/${{ matrix.output }}
|
|
94
|
+
ls -lh dist/
|
|
95
|
+
shell: bash
|
|
96
|
+
|
|
97
|
+
# Linux/macOS: native build
|
|
76
98
|
- name: Build for ${{ matrix.platform }}
|
|
99
|
+
if: matrix.platform != 'windows-x64'
|
|
77
100
|
run: |
|
|
78
101
|
mkdir -p dist
|
|
79
|
-
bun build --compile
|
|
102
|
+
bun build --compile bin/pglite-server.js --outfile dist/${{ matrix.output }}
|
|
80
103
|
ls -lh dist/
|
|
81
104
|
|
|
82
105
|
- name: Upload artifact
|
|
@@ -129,7 +152,8 @@ jobs:
|
|
|
129
152
|
ls -la dist/
|
|
130
153
|
|
|
131
154
|
MISSING=""
|
|
132
|
-
|
|
155
|
+
# Supported platforms: linux-x64, darwin-arm64, windows-x64
|
|
156
|
+
for platform in linux-x64 darwin-arm64; do
|
|
133
157
|
if [ ! -f "dist/pgserve-$platform" ]; then
|
|
134
158
|
MISSING="$MISSING pgserve-$platform"
|
|
135
159
|
fi
|
package/README.md
CHANGED
|
@@ -99,6 +99,17 @@ npm install pgserve
|
|
|
99
99
|
|
|
100
100
|
> PostgreSQL binaries are automatically downloaded on first run (~100MB).
|
|
101
101
|
|
|
102
|
+
### Windows
|
|
103
|
+
|
|
104
|
+
Download `pgserve-windows-x64.exe` from [GitHub Releases](https://github.com/namastexlabs/pgserve/releases).
|
|
105
|
+
|
|
106
|
+
Double-click to run, or use CLI:
|
|
107
|
+
|
|
108
|
+
```cmd
|
|
109
|
+
pgserve-windows-x64.exe --port 5432
|
|
110
|
+
pgserve-windows-x64.exe --data C:\pgserve-data
|
|
111
|
+
```
|
|
112
|
+
|
|
102
113
|
<br>
|
|
103
114
|
|
|
104
115
|
## CLI Reference
|
package/assets/icon.ico
ADDED
|
Binary file
|
package/bin/pgserve-wrapper.cjs
CHANGED
|
@@ -55,63 +55,61 @@ if (!bunPath) {
|
|
|
55
55
|
|
|
56
56
|
const scriptPath = path.join(__dirname, 'pglite-server.js');
|
|
57
57
|
|
|
58
|
-
//
|
|
59
|
-
//
|
|
60
|
-
//
|
|
61
|
-
const child = spawn(bunPath, [scriptPath, ...process.argv.slice(2)], {
|
|
62
|
-
stdio: 'inherit',
|
|
63
|
-
windowsHide: true
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
child.on('error', (err) => {
|
|
67
|
-
console.error('Failed to start pgserve:', err.message);
|
|
68
|
-
process.exit(1);
|
|
69
|
-
});
|
|
58
|
+
// Platform-specific spawning strategy:
|
|
59
|
+
// - Windows: Use pipes for explicit handle control (prevents EBUSY errors)
|
|
60
|
+
// - Unix: Use inherit for simplicity (works fine)
|
|
70
61
|
|
|
71
|
-
|
|
72
|
-
|
|
62
|
+
if (isWindows) {
|
|
63
|
+
// WINDOWS PATH: Explicit pipe control to prevent EBUSY errors
|
|
64
|
+
// Using stdio: 'inherit' causes file handle inheritance that we cannot release,
|
|
65
|
+
// leading to npm cleanup failures. With pipes, we control when handles are destroyed.
|
|
73
66
|
|
|
74
|
-
child
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
process.exit(1);
|
|
79
|
-
}, 5000);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// Use 'close' event instead of 'exit' - fires AFTER all stdio streams are closed
|
|
83
|
-
// This is critical for Windows where file handles may remain locked after 'exit' fires
|
|
84
|
-
child.on('close', (code, signal) => {
|
|
85
|
-
// Clear the safety timeout
|
|
86
|
-
if (forceExitTimeout) {
|
|
87
|
-
clearTimeout(forceExitTimeout);
|
|
88
|
-
}
|
|
67
|
+
const child = spawn(bunPath, [scriptPath, ...process.argv.slice(2)], {
|
|
68
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
69
|
+
windowsHide: true
|
|
70
|
+
});
|
|
89
71
|
|
|
90
|
-
//
|
|
91
|
-
//
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}
|
|
72
|
+
// Manually pipe stdio - we now control the handles
|
|
73
|
+
// Handle stdin errors gracefully (may not be connected in some environments)
|
|
74
|
+
process.stdin.on('error', () => {});
|
|
75
|
+
child.stdin.on('error', () => {});
|
|
76
|
+
|
|
77
|
+
// Only pipe stdin if it's readable
|
|
78
|
+
if (process.stdin.readable) {
|
|
79
|
+
process.stdin.pipe(child.stdin);
|
|
99
80
|
}
|
|
81
|
+
child.stdout.pipe(process.stdout);
|
|
82
|
+
child.stderr.pipe(process.stderr);
|
|
100
83
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
84
|
+
child.on('error', (err) => {
|
|
85
|
+
console.error('Failed to start pgserve:', err.message);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
child.on('close', (code, signal) => {
|
|
90
|
+
// CRITICAL: Explicitly destroy ALL streams to release file handles
|
|
91
|
+
// This must happen BEFORE process.exit() to prevent EBUSY
|
|
92
|
+
try {
|
|
93
|
+
if (process.stdin.readable) {
|
|
94
|
+
process.stdin.unpipe(child.stdin);
|
|
95
|
+
}
|
|
96
|
+
child.stdin.destroy();
|
|
97
|
+
child.stdout.destroy();
|
|
98
|
+
child.stderr.destroy();
|
|
99
|
+
} catch {
|
|
100
|
+
// Ignore stream destruction errors
|
|
107
101
|
}
|
|
108
|
-
} else {
|
|
109
|
-
process.exit(code ?? 0);
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
102
|
|
|
113
|
-
//
|
|
114
|
-
|
|
103
|
+
// Remove all listeners to prevent memory leaks
|
|
104
|
+
child.removeAllListeners();
|
|
105
|
+
|
|
106
|
+
// Use setImmediate to ensure stream destruction completes before exit
|
|
107
|
+
// This gives the event loop one tick to process pending I/O cleanup
|
|
108
|
+
setImmediate(() => {
|
|
109
|
+
process.exit(signal ? 1 : (code ?? 0));
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
|
|
115
113
|
// Windows: use taskkill for reliable process termination
|
|
116
114
|
// process.kill(pid, 'SIGINT') does NOT work properly on Windows
|
|
117
115
|
process.on('SIGINT', () => {
|
|
@@ -139,13 +137,37 @@ if (isWindows) {
|
|
|
139
137
|
rl.on('SIGINT', () => {
|
|
140
138
|
process.emit('SIGINT');
|
|
141
139
|
});
|
|
140
|
+
// Clean up readline on close
|
|
141
|
+
child.on('close', () => {
|
|
142
|
+
rl.close();
|
|
143
|
+
});
|
|
142
144
|
}
|
|
145
|
+
|
|
143
146
|
} else {
|
|
147
|
+
// UNIX PATH: Simple stdio inheritance (works fine, no EBUSY issues)
|
|
148
|
+
const child = spawn(bunPath, [scriptPath, ...process.argv.slice(2)], {
|
|
149
|
+
stdio: 'inherit',
|
|
150
|
+
windowsHide: true
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
child.on('error', (err) => {
|
|
154
|
+
console.error('Failed to start pgserve:', err.message);
|
|
155
|
+
process.exit(1);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
child.on('close', (code, signal) => {
|
|
159
|
+
if (signal) {
|
|
160
|
+
process.kill(process.pid, signal);
|
|
161
|
+
} else {
|
|
162
|
+
process.exit(code ?? 0);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
144
166
|
// Unix: forward signals to child process normally
|
|
145
|
-
['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(
|
|
146
|
-
process.on(
|
|
167
|
+
['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(sig => {
|
|
168
|
+
process.on(sig, () => {
|
|
147
169
|
if (child.pid) {
|
|
148
|
-
process.kill(child.pid,
|
|
170
|
+
process.kill(child.pid, sig);
|
|
149
171
|
}
|
|
150
172
|
});
|
|
151
173
|
});
|
package/bun.lock
CHANGED
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
"@embedded-postgres/darwin-arm64": "17.7.0-beta.15",
|
|
21
21
|
"@embedded-postgres/darwin-x64": "17.7.0-beta.15",
|
|
22
22
|
"@embedded-postgres/linux-x64": "17.7.0-beta.15",
|
|
23
|
-
"@embedded-postgres/
|
|
23
|
+
"@embedded-postgres/windows-x64": "17.7.0-beta.15",
|
|
24
24
|
},
|
|
25
25
|
},
|
|
26
26
|
},
|
|
@@ -33,6 +33,8 @@
|
|
|
33
33
|
|
|
34
34
|
"@embedded-postgres/linux-x64": ["@embedded-postgres/linux-x64@17.7.0-beta.15", "", { "os": "linux", "cpu": "x64" }, "sha512-HeaxSHsw6ccVh8l5iC4OgXqvaaCGWnnZR9CpgNgrAfnKPPGiEhUPBmO2XhEsFQIhc+ad/+36h0NTvKo4bdi40w=="],
|
|
35
35
|
|
|
36
|
+
"@embedded-postgres/windows-x64": ["@embedded-postgres/windows-x64@17.7.0-beta.15", "", { "os": "win32", "cpu": "x64" }, "sha512-Oq11yyKxISjefuYdKljcp3Q+uxx237zn9YpP9hO43+6Feorq7USuMIDqk5ofLSQ30FAnVyTqaIQK8ZIjW+tQXQ=="],
|
|
37
|
+
|
|
36
38
|
"@emnapi/core": ["@emnapi/core@1.7.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.1.0", "tslib": "^2.4.0" } }, "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg=="],
|
|
37
39
|
|
|
38
40
|
"@emnapi/runtime": ["@emnapi/runtime@1.7.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA=="],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pgserve",
|
|
3
|
-
"version": "1.1.3-rc.
|
|
3
|
+
"version": "1.1.3-rc.6",
|
|
4
4
|
"description": "Embedded PostgreSQL server with true concurrent connections - zero config, auto-provision databases",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"@embedded-postgres/darwin-arm64": "17.7.0-beta.15",
|
|
45
45
|
"@embedded-postgres/darwin-x64": "17.7.0-beta.15",
|
|
46
46
|
"@embedded-postgres/linux-x64": "17.7.0-beta.15",
|
|
47
|
-
"@embedded-postgres/
|
|
47
|
+
"@embedded-postgres/windows-x64": "17.7.0-beta.15"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@electric-sql/pglite": "^0.2.17",
|
package/src/postgres.js
CHANGED
|
@@ -18,6 +18,124 @@ import path from 'path';
|
|
|
18
18
|
import fs from 'fs';
|
|
19
19
|
import crypto from 'crypto';
|
|
20
20
|
|
|
21
|
+
/**
|
|
22
|
+
* Get platform key for binary lookup (e.g., 'windows-x64', 'linux-x64', 'darwin-arm64')
|
|
23
|
+
* @returns {string} Platform key
|
|
24
|
+
*/
|
|
25
|
+
function getPlatformKey() {
|
|
26
|
+
const platform = os.platform();
|
|
27
|
+
const arch = os.arch();
|
|
28
|
+
|
|
29
|
+
if (platform === 'win32') return 'windows-x64';
|
|
30
|
+
if (platform === 'linux' && arch === 'x64') return 'linux-x64';
|
|
31
|
+
if (platform === 'darwin' && arch === 'arm64') return 'darwin-arm64';
|
|
32
|
+
if (platform === 'darwin' && arch === 'x64') return 'darwin-x64';
|
|
33
|
+
if (platform === 'linux' && arch === 'arm64') return 'linux-arm64';
|
|
34
|
+
|
|
35
|
+
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Get the directory where extracted binaries are cached
|
|
40
|
+
* @returns {string} Cache directory path
|
|
41
|
+
*/
|
|
42
|
+
function getBinaryCacheDir() {
|
|
43
|
+
const platformKey = getPlatformKey();
|
|
44
|
+
return path.join(os.homedir(), '.pgserve', 'bin', platformKey);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Check if bundled PostgreSQL binaries exist (standalone exe mode)
|
|
49
|
+
* When compiled with `bun build --compile`, the embedded-postgres folder
|
|
50
|
+
* should be bundled alongside the executable.
|
|
51
|
+
* @returns {string|null} Path to bundled binaries or null if not found
|
|
52
|
+
*/
|
|
53
|
+
function getBundledBinaryDir() {
|
|
54
|
+
// Check for embedded-postgres folder relative to the module
|
|
55
|
+
// This works when binaries are bundled during build
|
|
56
|
+
const bundledDir = path.join(import.meta.dirname, '..', 'embedded-postgres');
|
|
57
|
+
if (fs.existsSync(path.join(bundledDir, 'bin'))) {
|
|
58
|
+
return bundledDir;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Extract bundled PostgreSQL binaries to cache directory.
|
|
65
|
+
* Bun-compiled binaries can read embedded files but cannot execute them directly.
|
|
66
|
+
* We extract to ~/.pgserve/bin/{platform}/ for execution.
|
|
67
|
+
*
|
|
68
|
+
* @returns {Promise<string>} Path to extracted bin directory
|
|
69
|
+
*/
|
|
70
|
+
async function extractBundledBinaries() {
|
|
71
|
+
const platform = os.platform();
|
|
72
|
+
const cacheDir = getBinaryCacheDir();
|
|
73
|
+
const cacheBinDir = path.join(cacheDir, 'bin');
|
|
74
|
+
const initdbName = platform === 'win32' ? 'initdb.exe' : 'initdb';
|
|
75
|
+
const postgresName = platform === 'win32' ? 'postgres.exe' : 'postgres';
|
|
76
|
+
|
|
77
|
+
// Check if already extracted
|
|
78
|
+
if (fs.existsSync(path.join(cacheBinDir, initdbName)) &&
|
|
79
|
+
fs.existsSync(path.join(cacheBinDir, postgresName))) {
|
|
80
|
+
return cacheDir;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Get bundled directory
|
|
84
|
+
const bundledDir = getBundledBinaryDir();
|
|
85
|
+
if (!bundledDir) {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
console.log('[pgserve] Extracting PostgreSQL binaries...');
|
|
90
|
+
|
|
91
|
+
// Create cache directory
|
|
92
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
93
|
+
|
|
94
|
+
// Copy bundled binaries to cache
|
|
95
|
+
// Use recursive copy to get bin/, lib/, share/ directories
|
|
96
|
+
await copyRecursive(bundledDir, cacheDir);
|
|
97
|
+
|
|
98
|
+
// Make executables executable (Unix only)
|
|
99
|
+
if (platform !== 'win32') {
|
|
100
|
+
const binDir = path.join(cacheDir, 'bin');
|
|
101
|
+
const files = fs.readdirSync(binDir);
|
|
102
|
+
for (const file of files) {
|
|
103
|
+
const filePath = path.join(binDir, file);
|
|
104
|
+
try {
|
|
105
|
+
fs.chmodSync(filePath, 0o755);
|
|
106
|
+
} catch {
|
|
107
|
+
// Ignore permission errors for non-executables
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
console.log(`[pgserve] Binaries extracted to ${cacheDir}`);
|
|
113
|
+
return cacheDir;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Recursively copy a directory
|
|
118
|
+
* @param {string} src - Source directory
|
|
119
|
+
* @param {string} dest - Destination directory
|
|
120
|
+
*/
|
|
121
|
+
async function copyRecursive(src, dest) {
|
|
122
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
123
|
+
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
const srcPath = path.join(src, entry.name);
|
|
126
|
+
const destPath = path.join(dest, entry.name);
|
|
127
|
+
|
|
128
|
+
if (entry.isDirectory()) {
|
|
129
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
130
|
+
await copyRecursive(srcPath, destPath);
|
|
131
|
+
} else {
|
|
132
|
+
// Read and write file (works with Bun's virtual filesystem)
|
|
133
|
+
const content = fs.readFileSync(srcPath);
|
|
134
|
+
fs.writeFileSync(destPath, content);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
|
|
21
139
|
/**
|
|
22
140
|
* Ensure library symlinks exist in the lib directory.
|
|
23
141
|
* The @embedded-postgres package ships versioned libraries but binaries look for soname versions.
|
|
@@ -94,10 +212,47 @@ function ensureLibrarySymlinks(libDir, platform) {
|
|
|
94
212
|
}
|
|
95
213
|
|
|
96
214
|
// Resolve binary paths from embedded-postgres platform packages
|
|
97
|
-
|
|
215
|
+
// Now async to support bundled binary extraction
|
|
216
|
+
async function getBinaryPaths() {
|
|
98
217
|
const platform = os.platform();
|
|
99
218
|
const arch = os.arch();
|
|
219
|
+
const exeSuffix = platform === 'win32' ? '.exe' : '';
|
|
220
|
+
|
|
221
|
+
// Priority 1: Check extracted cache directory (standalone exe mode)
|
|
222
|
+
// This is where bundled binaries are extracted on first run
|
|
223
|
+
const cacheDir = getBinaryCacheDir();
|
|
224
|
+
const cacheBinDir = path.join(cacheDir, 'bin');
|
|
225
|
+
const cachedInitdb = path.join(cacheBinDir, 'initdb' + exeSuffix);
|
|
226
|
+
const cachedPostgres = path.join(cacheBinDir, 'postgres' + exeSuffix);
|
|
227
|
+
|
|
228
|
+
if (fs.existsSync(cachedInitdb) && fs.existsSync(cachedPostgres)) {
|
|
229
|
+
const libDir = path.join(cacheDir, 'lib');
|
|
230
|
+
if ((platform === 'linux' || platform === 'darwin') && fs.existsSync(libDir)) {
|
|
231
|
+
ensureLibrarySymlinks(libDir, platform);
|
|
232
|
+
}
|
|
233
|
+
return { initdb: cachedInitdb, postgres: cachedPostgres, binDir: cacheBinDir, libDir };
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Priority 2: Check for bundled binaries and extract if found (standalone exe mode)
|
|
237
|
+
const bundledDir = getBundledBinaryDir();
|
|
238
|
+
if (bundledDir) {
|
|
239
|
+
const extractedDir = await extractBundledBinaries();
|
|
240
|
+
if (extractedDir) {
|
|
241
|
+
const extractedBinDir = path.join(extractedDir, 'bin');
|
|
242
|
+
const extractedInitdb = path.join(extractedBinDir, 'initdb' + exeSuffix);
|
|
243
|
+
const extractedPostgres = path.join(extractedBinDir, 'postgres' + exeSuffix);
|
|
244
|
+
|
|
245
|
+
if (fs.existsSync(extractedInitdb) && fs.existsSync(extractedPostgres)) {
|
|
246
|
+
const libDir = path.join(extractedDir, 'lib');
|
|
247
|
+
if ((platform === 'linux' || platform === 'darwin') && fs.existsSync(libDir)) {
|
|
248
|
+
ensureLibrarySymlinks(libDir, platform);
|
|
249
|
+
}
|
|
250
|
+
return { initdb: extractedInitdb, postgres: extractedPostgres, binDir: extractedBinDir, libDir };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
100
254
|
|
|
255
|
+
// Priority 3: Find the package in node_modules (npm install case)
|
|
101
256
|
let pkgName;
|
|
102
257
|
if (platform === 'linux' && arch === 'x64') {
|
|
103
258
|
pkgName = '@embedded-postgres/linux-x64';
|
|
@@ -106,12 +261,11 @@ function getBinaryPaths() {
|
|
|
106
261
|
} else if (platform === 'darwin' && arch === 'x64') {
|
|
107
262
|
pkgName = '@embedded-postgres/darwin-x64';
|
|
108
263
|
} else if (platform === 'win32' && arch === 'x64') {
|
|
109
|
-
pkgName = '@embedded-postgres/
|
|
264
|
+
pkgName = '@embedded-postgres/windows-x64';
|
|
110
265
|
} else {
|
|
111
266
|
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
112
267
|
}
|
|
113
268
|
|
|
114
|
-
// Find the package in node_modules (check multiple locations for npx/pnpm/npm compatibility)
|
|
115
269
|
const possiblePaths = [
|
|
116
270
|
path.join(process.cwd(), 'node_modules', pkgName, 'native', 'bin'),
|
|
117
271
|
path.join(import.meta.dirname, '..', 'node_modules', pkgName, 'native', 'bin'),
|
|
@@ -120,8 +274,8 @@ function getBinaryPaths() {
|
|
|
120
274
|
];
|
|
121
275
|
|
|
122
276
|
for (const binDir of possiblePaths) {
|
|
123
|
-
const initdb = path.join(binDir,
|
|
124
|
-
const postgres = path.join(binDir,
|
|
277
|
+
const initdb = path.join(binDir, 'initdb' + exeSuffix);
|
|
278
|
+
const postgres = path.join(binDir, 'postgres' + exeSuffix);
|
|
125
279
|
if (fs.existsSync(initdb) && fs.existsSync(postgres)) {
|
|
126
280
|
// Resolve the actual binary paths (handles symlinks from package managers)
|
|
127
281
|
const realInitdb = fs.realpathSync(initdb);
|
|
@@ -237,8 +391,8 @@ export class PostgresManager {
|
|
|
237
391
|
* Start the embedded PostgreSQL instance
|
|
238
392
|
*/
|
|
239
393
|
async start() {
|
|
240
|
-
// Get binary paths
|
|
241
|
-
this.binaries = getBinaryPaths();
|
|
394
|
+
// Get binary paths (may extract bundled binaries on first run)
|
|
395
|
+
this.binaries = await getBinaryPaths();
|
|
242
396
|
|
|
243
397
|
// Make binaries executable
|
|
244
398
|
await fs.promises.chmod(this.binaries.initdb, '755');
|