pgserve 1.1.3-rc.4 → 1.1.3-rc.7
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 +11 -20
- package/assets/icon.ico +0 -0
- package/package.json +1 -1
- package/src/postgres.js +191 -6
|
@@ -43,26 +43,16 @@ jobs:
|
|
|
43
43
|
fail-fast: false
|
|
44
44
|
matrix:
|
|
45
45
|
include:
|
|
46
|
-
# Linux
|
|
47
|
-
-
|
|
48
|
-
platform: linux-x64
|
|
46
|
+
# Linux x64
|
|
47
|
+
- platform: linux-x64
|
|
49
48
|
output: pgserve-linux-x64
|
|
50
49
|
os: ubuntu-latest
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
output: pgserve-linux-arm64
|
|
54
|
-
os: ubuntu-latest
|
|
55
|
-
- target: bun-darwin-x64
|
|
56
|
-
platform: darwin-x64
|
|
57
|
-
output: pgserve-darwin-x64
|
|
58
|
-
os: ubuntu-latest
|
|
59
|
-
- target: bun-darwin-arm64
|
|
60
|
-
platform: darwin-arm64
|
|
50
|
+
# macOS ARM64 (Apple Silicon)
|
|
51
|
+
- platform: darwin-arm64
|
|
61
52
|
output: pgserve-darwin-arm64
|
|
62
|
-
os:
|
|
63
|
-
# Windows
|
|
64
|
-
-
|
|
65
|
-
platform: windows-x64
|
|
53
|
+
os: macos-latest
|
|
54
|
+
# Windows x64 - must build on Windows for --windows-icon
|
|
55
|
+
- platform: windows-x64
|
|
66
56
|
output: pgserve-windows-x64.exe
|
|
67
57
|
os: windows-latest
|
|
68
58
|
|
|
@@ -89,12 +79,12 @@ jobs:
|
|
|
89
79
|
ls -lh dist/
|
|
90
80
|
shell: bash
|
|
91
81
|
|
|
92
|
-
# Linux/macOS:
|
|
82
|
+
# Linux/macOS: native build
|
|
93
83
|
- name: Build for ${{ matrix.platform }}
|
|
94
84
|
if: matrix.platform != 'windows-x64'
|
|
95
85
|
run: |
|
|
96
86
|
mkdir -p dist
|
|
97
|
-
bun build --compile
|
|
87
|
+
bun build --compile bin/pglite-server.js --outfile dist/${{ matrix.output }}
|
|
98
88
|
ls -lh dist/
|
|
99
89
|
|
|
100
90
|
- name: Upload artifact
|
|
@@ -147,7 +137,8 @@ jobs:
|
|
|
147
137
|
ls -la dist/
|
|
148
138
|
|
|
149
139
|
MISSING=""
|
|
150
|
-
|
|
140
|
+
# Supported platforms: linux-x64, darwin-arm64, windows-x64
|
|
141
|
+
for platform in linux-x64 darwin-arm64; do
|
|
151
142
|
if [ ! -f "dist/pgserve-$platform" ]; then
|
|
152
143
|
MISSING="$MISSING pgserve-$platform"
|
|
153
144
|
fi
|
package/assets/icon.ico
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/postgres.js
CHANGED
|
@@ -13,11 +13,162 @@
|
|
|
13
13
|
* - No locale dependency (works on any system)
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
/* global fetch, Bun */
|
|
16
17
|
import os from 'os';
|
|
17
18
|
import path from 'path';
|
|
18
19
|
import fs from 'fs';
|
|
19
20
|
import crypto from 'crypto';
|
|
20
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Get platform key for binary lookup (e.g., 'windows-x64', 'linux-x64', 'darwin-arm64')
|
|
24
|
+
* @returns {string} Platform key
|
|
25
|
+
*/
|
|
26
|
+
function getPlatformKey() {
|
|
27
|
+
const platform = os.platform();
|
|
28
|
+
const arch = os.arch();
|
|
29
|
+
|
|
30
|
+
if (platform === 'win32') return 'windows-x64';
|
|
31
|
+
if (platform === 'linux' && arch === 'x64') return 'linux-x64';
|
|
32
|
+
if (platform === 'darwin' && arch === 'arm64') return 'darwin-arm64';
|
|
33
|
+
if (platform === 'darwin' && arch === 'x64') return 'darwin-x64';
|
|
34
|
+
if (platform === 'linux' && arch === 'arm64') return 'linux-arm64';
|
|
35
|
+
|
|
36
|
+
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the directory where extracted binaries are cached
|
|
41
|
+
* @returns {string} Cache directory path
|
|
42
|
+
*/
|
|
43
|
+
function getBinaryCacheDir() {
|
|
44
|
+
const platformKey = getPlatformKey();
|
|
45
|
+
return path.join(os.homedir(), '.pgserve', 'bin', platformKey);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Download and extract PostgreSQL binaries on first run.
|
|
50
|
+
* Downloads from npm registry (@embedded-postgres packages).
|
|
51
|
+
*
|
|
52
|
+
* @returns {Promise<string>} Path to extracted directory
|
|
53
|
+
*/
|
|
54
|
+
async function downloadPostgresBinaries() {
|
|
55
|
+
const platform = os.platform();
|
|
56
|
+
const cacheDir = getBinaryCacheDir();
|
|
57
|
+
const cacheBinDir = path.join(cacheDir, 'bin');
|
|
58
|
+
const initdbName = platform === 'win32' ? 'initdb.exe' : 'initdb';
|
|
59
|
+
const postgresName = platform === 'win32' ? 'postgres.exe' : 'postgres';
|
|
60
|
+
|
|
61
|
+
// Check if already downloaded
|
|
62
|
+
if (fs.existsSync(path.join(cacheBinDir, initdbName)) &&
|
|
63
|
+
fs.existsSync(path.join(cacheBinDir, postgresName))) {
|
|
64
|
+
return cacheDir;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const platformKey = getPlatformKey();
|
|
68
|
+
const pkgName = `@embedded-postgres/${platformKey}`;
|
|
69
|
+
const pkgVersion = '17.7.0-beta.15';
|
|
70
|
+
|
|
71
|
+
console.log(`[pgserve] PostgreSQL binaries not found.`);
|
|
72
|
+
console.log(`[pgserve] Downloading ${pkgName}@${pkgVersion}...`);
|
|
73
|
+
|
|
74
|
+
// Get tarball URL from npm registry
|
|
75
|
+
const registryUrl = `https://registry.npmjs.org/${pkgName}`;
|
|
76
|
+
const registryRes = await fetch(registryUrl);
|
|
77
|
+
if (!registryRes.ok) {
|
|
78
|
+
throw new Error(`Failed to fetch package info: ${registryRes.status}`);
|
|
79
|
+
}
|
|
80
|
+
const pkgInfo = await registryRes.json();
|
|
81
|
+
const tarballUrl = pkgInfo.versions[pkgVersion]?.dist?.tarball;
|
|
82
|
+
|
|
83
|
+
if (!tarballUrl) {
|
|
84
|
+
throw new Error(`Version ${pkgVersion} not found for ${pkgName}`);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Download tarball
|
|
88
|
+
console.log(`[pgserve] Downloading from npm registry...`);
|
|
89
|
+
const tarballRes = await fetch(tarballUrl);
|
|
90
|
+
if (!tarballRes.ok) {
|
|
91
|
+
throw new Error(`Failed to download tarball: ${tarballRes.status}`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const tarballBuffer = await tarballRes.arrayBuffer();
|
|
95
|
+
const tarballSize = (tarballBuffer.byteLength / 1024 / 1024).toFixed(1);
|
|
96
|
+
console.log(`[pgserve] Downloaded ${tarballSize} MB`);
|
|
97
|
+
|
|
98
|
+
// Create temp file for tarball
|
|
99
|
+
const tempDir = path.join(os.tmpdir(), `pgserve-download-${Date.now()}`);
|
|
100
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
101
|
+
const tarballPath = path.join(tempDir, 'package.tgz');
|
|
102
|
+
fs.writeFileSync(tarballPath, Buffer.from(tarballBuffer));
|
|
103
|
+
|
|
104
|
+
// Extract tarball using tar (available on all platforms via bun/node)
|
|
105
|
+
console.log(`[pgserve] Extracting binaries...`);
|
|
106
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
107
|
+
|
|
108
|
+
// Use Bun.spawn for extraction
|
|
109
|
+
const extractProc = Bun.spawn(['tar', '-xzf', tarballPath, '-C', tempDir], {
|
|
110
|
+
stdout: 'pipe',
|
|
111
|
+
stderr: 'pipe'
|
|
112
|
+
});
|
|
113
|
+
await extractProc.exited;
|
|
114
|
+
|
|
115
|
+
// Copy native/* to cache dir
|
|
116
|
+
const nativeDir = path.join(tempDir, 'package', 'native');
|
|
117
|
+
if (!fs.existsSync(nativeDir)) {
|
|
118
|
+
throw new Error('Extracted package does not contain native/ directory');
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// Copy files recursively
|
|
122
|
+
await copyDirRecursive(nativeDir, cacheDir);
|
|
123
|
+
|
|
124
|
+
// Make executables executable (Unix only)
|
|
125
|
+
if (platform !== 'win32') {
|
|
126
|
+
const binDir = path.join(cacheDir, 'bin');
|
|
127
|
+
if (fs.existsSync(binDir)) {
|
|
128
|
+
const files = fs.readdirSync(binDir);
|
|
129
|
+
for (const file of files) {
|
|
130
|
+
const filePath = path.join(binDir, file);
|
|
131
|
+
try {
|
|
132
|
+
fs.chmodSync(filePath, 0o755);
|
|
133
|
+
} catch {
|
|
134
|
+
// Ignore
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Cleanup temp
|
|
141
|
+
try {
|
|
142
|
+
fs.rmSync(tempDir, { recursive: true, force: true });
|
|
143
|
+
} catch {
|
|
144
|
+
// Ignore cleanup errors
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
console.log(`[pgserve] PostgreSQL binaries installed to ${cacheDir}`);
|
|
148
|
+
return cacheDir;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Recursively copy a directory
|
|
153
|
+
* @param {string} src - Source directory
|
|
154
|
+
* @param {string} dest - Destination directory
|
|
155
|
+
*/
|
|
156
|
+
async function copyDirRecursive(src, dest) {
|
|
157
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
158
|
+
|
|
159
|
+
for (const entry of entries) {
|
|
160
|
+
const srcPath = path.join(src, entry.name);
|
|
161
|
+
const destPath = path.join(dest, entry.name);
|
|
162
|
+
|
|
163
|
+
if (entry.isDirectory()) {
|
|
164
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
165
|
+
await copyDirRecursive(srcPath, destPath);
|
|
166
|
+
} else {
|
|
167
|
+
fs.copyFileSync(srcPath, destPath);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
21
172
|
/**
|
|
22
173
|
* Ensure library symlinks exist in the lib directory.
|
|
23
174
|
* The @embedded-postgres package ships versioned libraries but binaries look for soname versions.
|
|
@@ -94,10 +245,45 @@ function ensureLibrarySymlinks(libDir, platform) {
|
|
|
94
245
|
}
|
|
95
246
|
|
|
96
247
|
// Resolve binary paths from embedded-postgres platform packages
|
|
97
|
-
|
|
248
|
+
// Now async to support bundled binary extraction
|
|
249
|
+
async function getBinaryPaths() {
|
|
98
250
|
const platform = os.platform();
|
|
99
251
|
const arch = os.arch();
|
|
252
|
+
const exeSuffix = platform === 'win32' ? '.exe' : '';
|
|
253
|
+
|
|
254
|
+
// Priority 1: Check extracted cache directory (standalone exe mode)
|
|
255
|
+
// This is where bundled binaries are extracted on first run
|
|
256
|
+
const cacheDir = getBinaryCacheDir();
|
|
257
|
+
const cacheBinDir = path.join(cacheDir, 'bin');
|
|
258
|
+
const cachedInitdb = path.join(cacheBinDir, 'initdb' + exeSuffix);
|
|
259
|
+
const cachedPostgres = path.join(cacheBinDir, 'postgres' + exeSuffix);
|
|
260
|
+
|
|
261
|
+
if (fs.existsSync(cachedInitdb) && fs.existsSync(cachedPostgres)) {
|
|
262
|
+
const libDir = path.join(cacheDir, 'lib');
|
|
263
|
+
if ((platform === 'linux' || platform === 'darwin') && fs.existsSync(libDir)) {
|
|
264
|
+
ensureLibrarySymlinks(libDir, platform);
|
|
265
|
+
}
|
|
266
|
+
return { initdb: cachedInitdb, postgres: cachedPostgres, binDir: cacheBinDir, libDir };
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Priority 2: Download binaries if not found (standalone exe mode)
|
|
270
|
+
// This downloads from npm registry on first run
|
|
271
|
+
const downloadedDir = await downloadPostgresBinaries();
|
|
272
|
+
if (downloadedDir) {
|
|
273
|
+
const downloadedBinDir = path.join(downloadedDir, 'bin');
|
|
274
|
+
const downloadedInitdb = path.join(downloadedBinDir, 'initdb' + exeSuffix);
|
|
275
|
+
const downloadedPostgres = path.join(downloadedBinDir, 'postgres' + exeSuffix);
|
|
276
|
+
|
|
277
|
+
if (fs.existsSync(downloadedInitdb) && fs.existsSync(downloadedPostgres)) {
|
|
278
|
+
const libDir = path.join(downloadedDir, 'lib');
|
|
279
|
+
if ((platform === 'linux' || platform === 'darwin') && fs.existsSync(libDir)) {
|
|
280
|
+
ensureLibrarySymlinks(libDir, platform);
|
|
281
|
+
}
|
|
282
|
+
return { initdb: downloadedInitdb, postgres: downloadedPostgres, binDir: downloadedBinDir, libDir };
|
|
283
|
+
}
|
|
284
|
+
}
|
|
100
285
|
|
|
286
|
+
// Priority 3: Find the package in node_modules (npm install case)
|
|
101
287
|
let pkgName;
|
|
102
288
|
if (platform === 'linux' && arch === 'x64') {
|
|
103
289
|
pkgName = '@embedded-postgres/linux-x64';
|
|
@@ -111,7 +297,6 @@ function getBinaryPaths() {
|
|
|
111
297
|
throw new Error(`Unsupported platform: ${platform}-${arch}`);
|
|
112
298
|
}
|
|
113
299
|
|
|
114
|
-
// Find the package in node_modules (check multiple locations for npx/pnpm/npm compatibility)
|
|
115
300
|
const possiblePaths = [
|
|
116
301
|
path.join(process.cwd(), 'node_modules', pkgName, 'native', 'bin'),
|
|
117
302
|
path.join(import.meta.dirname, '..', 'node_modules', pkgName, 'native', 'bin'),
|
|
@@ -120,8 +305,8 @@ function getBinaryPaths() {
|
|
|
120
305
|
];
|
|
121
306
|
|
|
122
307
|
for (const binDir of possiblePaths) {
|
|
123
|
-
const initdb = path.join(binDir,
|
|
124
|
-
const postgres = path.join(binDir,
|
|
308
|
+
const initdb = path.join(binDir, 'initdb' + exeSuffix);
|
|
309
|
+
const postgres = path.join(binDir, 'postgres' + exeSuffix);
|
|
125
310
|
if (fs.existsSync(initdb) && fs.existsSync(postgres)) {
|
|
126
311
|
// Resolve the actual binary paths (handles symlinks from package managers)
|
|
127
312
|
const realInitdb = fs.realpathSync(initdb);
|
|
@@ -237,8 +422,8 @@ export class PostgresManager {
|
|
|
237
422
|
* Start the embedded PostgreSQL instance
|
|
238
423
|
*/
|
|
239
424
|
async start() {
|
|
240
|
-
// Get binary paths
|
|
241
|
-
this.binaries = getBinaryPaths();
|
|
425
|
+
// Get binary paths (may extract bundled binaries on first run)
|
|
426
|
+
this.binaries = await getBinaryPaths();
|
|
242
427
|
|
|
243
428
|
// Make binaries executable
|
|
244
429
|
await fs.promises.chmod(this.binaries.initdb, '755');
|