pgserve 1.0.9-rc.7 → 1.1.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.
@@ -81,4 +81,38 @@ jobs:
81
81
  - name: Verify executable
82
82
  run: |
83
83
  ./dist/pgserve --help
84
- echo "Build successful!"
84
+ echo "Build successful!"
85
+
86
+ # Test npx flow (user experience)
87
+ test-npx:
88
+ name: Test npx install
89
+ runs-on: ubuntu-latest
90
+
91
+ steps:
92
+ - name: Checkout
93
+ uses: actions/checkout@v4
94
+
95
+ - name: Setup Bun (for packing)
96
+ uses: oven-sh/setup-bun@v2
97
+ with:
98
+ bun-version: latest
99
+
100
+ - name: Setup Node.js (for testing)
101
+ uses: actions/setup-node@v4
102
+ with:
103
+ node-version: '20'
104
+
105
+ - name: Install deps and pack
106
+ run: |
107
+ bun install
108
+ bun pm pack --destination /tmp --ignore-scripts
109
+
110
+ - name: Test npx install (fresh environment)
111
+ run: |
112
+ cd /tmp
113
+ mkdir test-pgserve
114
+ cd test-pgserve
115
+ npm init -y
116
+ npm install /tmp/pgserve-*.tgz
117
+ timeout 30 npx pgserve --help
118
+ echo "npx test passed!"
@@ -105,11 +105,10 @@ jobs:
105
105
  git push origin HEAD:${{ github.ref_name }}
106
106
  git push origin --tags
107
107
 
108
- # Build: Build all platforms (skip for promote)
108
+ # Build & Publish: Always build and publish (npm_tag comes from version job)
109
109
  build:
110
110
  name: Build & Publish
111
111
  needs: version
112
- if: needs.version.outputs.is_promote != 'true'
113
112
  uses: ./.github/workflows/build-all-platforms.yml
114
113
  with:
115
114
  version: ${{ needs.version.outputs.version }}
@@ -117,52 +116,11 @@ jobs:
117
116
  ref: ${{ needs.version.outputs.tag }}
118
117
  secrets: inherit
119
118
 
120
- # Promote: Just update npm tags (no rebuild)
121
- promote:
122
- name: Promote to Latest
123
- needs: version
124
- if: needs.version.outputs.is_promote == 'true'
125
- runs-on: ubuntu-latest
126
- environment: npm-publish
127
-
128
- steps:
129
- - name: Setup Node.js
130
- uses: actions/setup-node@v4
131
- with:
132
- node-version: '20'
133
- registry-url: 'https://registry.npmjs.org'
134
-
135
- - name: Get RC version from @next tag
136
- id: get-rc
137
- run: |
138
- RC_VERSION=$(npm view pgserve@next version 2>/dev/null || echo "")
139
- if [ -z "$RC_VERSION" ]; then
140
- echo "No RC version found at @next tag"
141
- exit 1
142
- fi
143
- echo "rc_version=$RC_VERSION" >> $GITHUB_OUTPUT
144
- echo "Found RC version: $RC_VERSION"
145
-
146
- - name: Promote @next to @latest
147
- run: |
148
- echo "Promoting pgserve@${{ steps.get-rc.outputs.rc_version }} to @latest"
149
- npm dist-tag add pgserve@${{ steps.get-rc.outputs.rc_version }} latest
150
- env:
151
- NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
152
-
153
- - name: Verify promotion
154
- run: |
155
- LATEST=$(npm view pgserve@latest version)
156
- echo "Latest version is now: $LATEST"
157
- if [ "$LATEST" != "${{ steps.get-rc.outputs.rc_version }}" ]; then
158
- echo "Warning: Version mismatch after promotion"
159
- fi
160
-
161
119
  # GitHub Release: Create release with changelog
162
120
  github-release:
163
121
  name: Create GitHub Release
164
122
  needs: [version, build]
165
- if: always() && needs.version.result == 'success' && (needs.build.result == 'success' || needs.build.result == 'skipped')
123
+ if: always() && needs.version.result == 'success' && needs.build.result == 'success'
166
124
  runs-on: ubuntu-latest
167
125
  permissions:
168
126
  contents: write
package/AGENTS.md CHANGED
@@ -188,9 +188,16 @@ Before editing ANY implementation file, Base Genie must check:
188
188
 
189
189
  **Protocol:** `@.genie/spells/orchestration-boundary-protocol.md`
190
190
 
191
+ **Release Workflow Protocol:**
192
+ - ❌ Never manually trigger `workflow_dispatch` for releases
193
+ - ❌ Never manually bump version in package.json
194
+ - ✅ Always use PR with `rc` or `stable` label - release.yml auto-triggers on merge
195
+ - ✅ Version bumping is automated by scripts/release.cjs
196
+
191
197
  **Documented Violations:**
192
198
  - Bug #168, task b51db539, 2025-10-21 (duplicate implementation)
193
199
  - 2025-10-26 (claimed release implementation steps without investigating automation)
200
+ - 2025-12-08 (manually set version to 1.1.0 + triggered workflow_dispatch → version jumped to 1.1.1-rc.1)
194
201
 
195
202
  ### 4. Task State Optimization - Live State, Not Documentation 🔴 CRITICAL
196
203
  **Rule:** Task state is ephemeral runtime data, not permanent documentation
package/README.md CHANGED
@@ -4,8 +4,7 @@
4
4
 
5
5
  <p>
6
6
  <a href="https://www.npmjs.com/package/pgserve"><img src="https://img.shields.io/npm/v/pgserve?style=flat-square&color=00D9FF" alt="npm version"></a>
7
- <img src="https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen?style=flat-square" alt="Node.js">
8
- <img src="https://img.shields.io/badge/bun-%3E%3D1.0.0-f472b6?style=flat-square" alt="Bun">
7
+ <img src="https://img.shields.io/badge/node-%3E%3D18-green?style=flat-square" alt="Node.js">
9
8
  <img src="https://img.shields.io/badge/PostgreSQL-17.7-blue?style=flat-square" alt="PostgreSQL">
10
9
  <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat-square" alt="License"></a>
11
10
  <a href="https://discord.gg/xcW8c7fF3R"><img src="https://img.shields.io/discord/1095114867012292758?style=flat-square&color=00D9FF&label=discord" alt="Discord"></a>
@@ -33,7 +32,7 @@ npx pgserve
33
32
  Connect from any PostgreSQL client — databases auto-create on first connection:
34
33
 
35
34
  ```bash
36
- psql postgresql://localhost:5432/myapp
35
+ psql postgresql://localhost:8432/myapp
37
36
  ```
38
37
 
39
38
  <br>
@@ -41,6 +40,10 @@ psql postgresql://localhost:5432/myapp
41
40
  ## Features
42
41
 
43
42
  <table>
43
+ <tr>
44
+ <td><b>Real PostgreSQL 17</b></td>
45
+ <td>Native binaries, not WASM — full compatibility, extensions support</td>
46
+ </tr>
44
47
  <tr>
45
48
  <td><b>Unlimited Concurrency</b></td>
46
49
  <td>Native PostgreSQL process forking — no connection locks</td>
@@ -67,7 +70,7 @@ psql postgresql://localhost:5432/myapp
67
70
  </tr>
68
71
  <tr>
69
72
  <td><b>Async Replication</b></td>
70
- <td>Sync to real PostgreSQL with zero performance impact</td>
73
+ <td>Sync to real PostgreSQL with minimal overhead</td>
71
74
  </tr>
72
75
  <tr>
73
76
  <td><b>Cross-Platform</b></td>
@@ -92,13 +95,9 @@ npm install -g pgserve
92
95
 
93
96
  # Project dependency
94
97
  npm install pgserve
95
-
96
- # With Bun
97
- bunx pgserve
98
- bun add pgserve
99
98
  ```
100
99
 
101
- > PostgreSQL binaries are automatically downloaded on first run.
100
+ > PostgreSQL binaries are automatically downloaded on first run (~100MB).
102
101
 
103
102
  <br>
104
103
 
@@ -179,7 +178,7 @@ await server.stop();
179
178
  import pg from 'pg';
180
179
 
181
180
  const client = new pg.Client({
182
- connectionString: 'postgresql://localhost:5432/myapp'
181
+ connectionString: 'postgresql://localhost:8432/myapp'
183
182
  });
184
183
 
185
184
  await client.connect();
@@ -205,7 +204,7 @@ datasource db {
205
204
 
206
205
  ```bash
207
206
  # .env
208
- DATABASE_URL="postgresql://localhost:5432/myapp"
207
+ DATABASE_URL="postgresql://localhost:8432/myapp"
209
208
 
210
209
  # Run migrations
211
210
  npx prisma migrate dev
@@ -221,7 +220,7 @@ import { drizzle } from 'drizzle-orm/node-postgres';
221
220
  import { Pool } from 'pg';
222
221
 
223
222
  const pool = new Pool({
224
- connectionString: 'postgresql://localhost:5432/myapp'
223
+ connectionString: 'postgresql://localhost:8432/myapp'
225
224
  });
226
225
 
227
226
  const db = drizzle(pool);
@@ -244,7 +243,7 @@ pgserve --sync-to "postgresql://user:pass@db.example.com:5432/mydb"
244
243
  pgserve --sync-to "postgresql://..." --sync-databases "myapp,tenant_*"
245
244
  ```
246
245
 
247
- > Replication is handled by PostgreSQL's WAL writer process, completely off the Node.js event loop. Sync failures don't affect main server operation.
246
+ > Replication is handled by PostgreSQL's WAL writer process, completely off the runtime event loop. Sync failures don't affect main server operation.
248
247
 
249
248
  <br>
250
249
 
@@ -287,9 +286,9 @@ pgserve --sync-to "postgresql://..." --sync-databases "myapp,tenant_*"
287
286
  </tr>
288
287
  </table>
289
288
 
290
- > **Bun gives 2x throughput** for concurrent writes vs Node.js. **RAM mode adds another 2-4x** on Linux.
289
+ > pgserve uses Bun runtime internally for 2x throughput. **RAM mode adds another 2-4x** on Linux.
291
290
  >
292
- > Run benchmarks: `bun run bench`
291
+ > Run benchmarks: `bun run bench` (contributors only)
293
292
 
294
293
  <br>
295
294
 
@@ -339,14 +338,14 @@ pgserve --sync-to "postgresql://..." --sync-databases "myapp,tenant_*"
339
338
 
340
339
  ## Requirements
341
340
 
342
- - **Runtime**: Node.js >= 18.0.0 or Bun >= 1.0.0
341
+ - **Runtime**: Node.js >= 18 (npm/npx)
343
342
  - **Platform**: Linux x64, macOS ARM64/x64, Windows x64
344
343
 
345
344
  <br>
346
345
 
347
346
  ## Development
348
347
 
349
- This project uses Bun for development:
348
+ Contributors: This project uses Bun internally for development:
350
349
 
351
350
  ```bash
352
351
  # Install dependencies
@@ -0,0 +1,81 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * pgserve wrapper - Finds and spawns bun runtime from node_modules
4
+ *
5
+ * This wrapper enables `npx pgserve` to work without requiring
6
+ * users to install bun globally. The bun runtime is bundled as
7
+ * an npm dependency and this wrapper finds and invokes it.
8
+ */
9
+
10
+ const { spawn } = require('child_process');
11
+ const path = require('path');
12
+ const fs = require('fs');
13
+
14
+ // Detect platform
15
+ const isWindows = process.platform === 'win32';
16
+ const bunBin = isWindows ? 'bun.exe' : 'bun';
17
+
18
+ // Try multiple locations for cross-platform compatibility
19
+ // Order matters - most common locations first
20
+ // Note: npm hoists dependencies, so bun may be in parent node_modules
21
+ const locations = [
22
+ // Hoisted to top-level node_modules (npm default behavior)
23
+ path.join(__dirname, '..', '..', '.bin', bunBin),
24
+ // Standard location when not hoisted
25
+ path.join(__dirname, '..', 'node_modules', '.bin', bunBin),
26
+ // Direct bun package location (some npm versions)
27
+ path.join(__dirname, '..', 'node_modules', 'bun', bunBin),
28
+ // Hoisted bun package
29
+ path.join(__dirname, '..', '..', 'bun', bunBin),
30
+ // Platform-specific @oven packages (hoisted)
31
+ path.join(__dirname, '..', '..', '@oven', `bun-${process.platform}-${process.arch}`, bunBin),
32
+ // Platform-specific @oven packages (not hoisted)
33
+ path.join(__dirname, '..', 'node_modules', '@oven', `bun-${process.platform}-${process.arch}`, bunBin),
34
+ // Alternative arch naming (darwin-aarch64 vs darwin-arm64)
35
+ path.join(__dirname, '..', '..', '@oven', `bun-${process.platform}-${process.arch === 'arm64' ? 'aarch64' : process.arch}`, bunBin),
36
+ // Windows specific paths
37
+ isWindows ? path.join(__dirname, '..', '..', '.bin', 'bun.cmd') : null,
38
+ isWindows ? path.join(__dirname, '..', 'node_modules', '.bin', 'bun.cmd') : null,
39
+ ].filter(Boolean);
40
+
41
+ const bunPath = locations.find(p => fs.existsSync(p));
42
+
43
+ if (!bunPath) {
44
+ console.error('Error: Could not find bun runtime.');
45
+ console.error('');
46
+ console.error('Tried locations:');
47
+ locations.forEach(l => console.error(` - ${l}`));
48
+ console.error('');
49
+ console.error('Try reinstalling: npm install pgserve');
50
+ process.exit(1);
51
+ }
52
+
53
+ const scriptPath = path.join(__dirname, 'pglite-server.js');
54
+
55
+ // Spawn bun with the actual script, inherit all stdio
56
+ const child = spawn(bunPath, [scriptPath, ...process.argv.slice(2)], {
57
+ stdio: 'inherit',
58
+ windowsHide: true
59
+ });
60
+
61
+ child.on('error', (err) => {
62
+ console.error('Failed to start pgserve:', err.message);
63
+ process.exit(1);
64
+ });
65
+
66
+ child.on('exit', (code, signal) => {
67
+ if (signal) {
68
+ process.kill(process.pid, signal);
69
+ } else {
70
+ process.exit(code ?? 0);
71
+ }
72
+ });
73
+
74
+ // Forward signals to child process
75
+ ['SIGINT', 'SIGTERM', 'SIGHUP'].forEach(signal => {
76
+ process.on(signal, () => {
77
+ if (child.pid) {
78
+ process.kill(child.pid, signal);
79
+ }
80
+ });
81
+ });
package/bun.lock CHANGED
@@ -4,6 +4,9 @@
4
4
  "workspaces": {
5
5
  "": {
6
6
  "name": "pgserve",
7
+ "dependencies": {
8
+ "bun": "^1.3.4",
9
+ },
7
10
  "devDependencies": {
8
11
  "@electric-sql/pglite": "^0.2.17",
9
12
  "eslint": "^9.39.1",
@@ -70,6 +73,28 @@
70
73
 
71
74
  "@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
72
75
 
76
+ "@oven/bun-darwin-aarch64": ["@oven/bun-darwin-aarch64@1.3.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2Ie4jDGvNGuPSD+pyyBKL8dJmX+bZfDNYEalwgROImVtwB1XYAatJK20dMaRlPA7jOhjvS9Io+4IZAJu7Js0AA=="],
77
+
78
+ "@oven/bun-darwin-x64": ["@oven/bun-darwin-x64@1.3.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-4/BJojT8hk5g6Gecjn5yI7y96/+9Mtzsvdp9+2dcy9sTMdlV7jBvDzswqyJPZyQqw0F3HV3Vu9XuMubZwKd9lA=="],
79
+
80
+ "@oven/bun-darwin-x64-baseline": ["@oven/bun-darwin-x64-baseline@1.3.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-ZYxzIOCDqylTMsnWYERjKMMuK2b4an4qbloBmUZTwLHmVzos00yrhtpitZhJBgH6yB/l4Q5eoJ2W98UKtFFeiQ=="],
81
+
82
+ "@oven/bun-linux-aarch64": ["@oven/bun-linux-aarch64@1.3.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-8DUIlanftMdFxLGq2FxwKwfrp8O4ZofF/8Oc6lxCyEFmg2hixbHhL04+fPfJIi5D4hZloynxZdwTeDbGv/Kc4A=="],
83
+
84
+ "@oven/bun-linux-aarch64-musl": ["@oven/bun-linux-aarch64-musl@1.3.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-6UtmM4wXgRKz+gnLZEfddfsuBSVQpJr09K12e5pbdnLzeWgXYlBT5FG8S7SVn1t6cbgBMnigEsFjWwfTuMNoCw=="],
85
+
86
+ "@oven/bun-linux-x64": ["@oven/bun-linux-x64@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-03iSDMqdrmIFAsvsRptq+A7EGNjkg20dNzPnqxAlXHk5rc1PeIRWIP0eIn0i3nI6mmdj33mimf9AGr0+d0lKMg=="],
87
+
88
+ "@oven/bun-linux-x64-baseline": ["@oven/bun-linux-x64-baseline@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-ZMGPbFPqmG/VYJv61D+Y1V7T23jPK57vYl7yYLakmkTRjG6vcJ0Akhb2qR1iW94rHvfEBjeuVDAZBp8Qp9oyWA=="],
89
+
90
+ "@oven/bun-linux-x64-musl": ["@oven/bun-linux-x64-musl@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-xUXPuJHndGhk4K3Cx1FgTyTgDZOn+ki3eWvdXYqKdfi0EaNA9KpUq+/vUtpJbZRjzpHs9L+OJcdDILq5H0LX4g=="],
91
+
92
+ "@oven/bun-linux-x64-musl-baseline": ["@oven/bun-linux-x64-musl-baseline@1.3.4", "", { "os": "linux", "cpu": "x64" }, "sha512-qsGSSlNsxiX8lAayK2uYCfMLtqu776F0nn7qoyzg9Ti7mElM3woNh7RtGClTwQ6qsp5/UvgqT9g4pLaDHmqJFg=="],
93
+
94
+ "@oven/bun-windows-x64": ["@oven/bun-windows-x64@1.3.4", "", { "os": "win32", "cpu": "x64" }, "sha512-nswsuN6+HZPim6x4tFpDFpMa/qpTKfywbGvCkzxwrbJO9MtpuW/54NA1nFbHhpV14OLU0xuxyBj2PK4FHq4MlA=="],
95
+
96
+ "@oven/bun-windows-x64-baseline": ["@oven/bun-windows-x64-baseline@1.3.4", "", { "os": "win32", "cpu": "x64" }, "sha512-ZQiSDFfSUdOrPTiL2GvkxlC/kMED4fsJwdZnwJK6S9ylXnk9xY/9ZXfe1615SFLQl2LsVRzJAtjQLeM0BifIKQ=="],
97
+
73
98
  "@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.15.0", "", { "os": "android", "cpu": "arm" }, "sha512-Q+lWuFfq7whNelNJIP1dhXaVz4zO9Tu77GcQHyxDWh3MaCoO2Bisphgzmsh4ZoUe2zIchQh6OvQL99GlWHg9Tw=="],
74
99
 
75
100
  "@oxc-resolver/binding-android-arm64": ["@oxc-resolver/binding-android-arm64@11.15.0", "", { "os": "android", "cpu": "arm64" }, "sha512-vbdBttesHR0W1oJaxgWVTboyMUuu+VnPsHXJ6jrXf4czELzB6GIg5DrmlyhAmFBhjwov+yJH/DfTnHS+2sDgOw=="],
@@ -138,6 +163,8 @@
138
163
 
139
164
  "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
140
165
 
166
+ "bun": ["bun@1.3.4", "", { "optionalDependencies": { "@oven/bun-darwin-aarch64": "1.3.4", "@oven/bun-darwin-x64": "1.3.4", "@oven/bun-darwin-x64-baseline": "1.3.4", "@oven/bun-linux-aarch64": "1.3.4", "@oven/bun-linux-aarch64-musl": "1.3.4", "@oven/bun-linux-x64": "1.3.4", "@oven/bun-linux-x64-baseline": "1.3.4", "@oven/bun-linux-x64-musl": "1.3.4", "@oven/bun-linux-x64-musl-baseline": "1.3.4", "@oven/bun-windows-x64": "1.3.4", "@oven/bun-windows-x64-baseline": "1.3.4" }, "os": [ "linux", "win32", "darwin", ], "cpu": [ "x64", "arm64", ], "bin": { "bun": "bin/bun.exe", "bunx": "bin/bunx.exe" } }, "sha512-xV6KgD5ImquuKsoghzbWmYzeCXmmSgN6yJGz444hri2W+NGKNRFUNrEhy9+/rRXbvNA2qF0K0jAwqFNy1/GhBg=="],
167
+
141
168
  "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
142
169
 
143
170
  "chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
package/knip.json CHANGED
@@ -1,8 +1,9 @@
1
1
  {
2
2
  "$schema": "https://unpkg.com/knip@5/schema.json",
3
- "entry": ["src/index.js", "bin/pglite-server.js"],
4
- "project": ["src/**/*.js", "bin/**/*.js"],
3
+ "entry": ["src/index.js", "bin/pglite-server.js", "bin/pgserve-wrapper.cjs"],
4
+ "project": ["src/**/*.js", "bin/**/*.js", "bin/**/*.cjs"],
5
5
  "ignore": ["tests/**", "helpers/**", "scripts/**"],
6
- "ignoreBinaries": ["scripts/test-bunx.sh", "make"],
6
+ "ignoreBinaries": ["scripts/test-npx.sh", "make"],
7
+ "ignoreDependencies": ["bun"],
7
8
  "ignoreExportsUsedInFile": true
8
9
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "pgserve",
3
- "version": "1.0.9-rc.7",
3
+ "version": "1.1.2",
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",
7
7
  "bin": {
8
- "pgserve": "./bin/pglite-server.js"
8
+ "pgserve": "./bin/pgserve-wrapper.cjs"
9
9
  },
10
10
  "scripts": {
11
11
  "bench": "bun tests/benchmarks/runner.js",
@@ -18,8 +18,8 @@
18
18
  "lint": "eslint src/ bin/",
19
19
  "lint:fix": "eslint src/ bin/ --fix",
20
20
  "deadcode": "knip",
21
- "test:bunx": "scripts/test-bunx.sh",
22
- "prepublishOnly": "npm run lint && npm run deadcode && npm run test:bunx",
21
+ "test:npx": "scripts/test-npx.sh",
22
+ "prepublishOnly": "npm run lint && npm run deadcode && npm run test:npx",
23
23
  "prepare": "husky"
24
24
  },
25
25
  "keywords": [
@@ -55,9 +55,6 @@
55
55
  "lint-staged": "^16.2.7",
56
56
  "pg": "^8.16.3"
57
57
  },
58
- "engines": {
59
- "bun": ">=1.1.0"
60
- },
61
58
  "lint-staged": {
62
59
  "src/**/*.js": [
63
60
  "eslint --fix"
@@ -65,5 +62,8 @@
65
62
  "bin/**/*.js": [
66
63
  "eslint --fix"
67
64
  ]
65
+ },
66
+ "dependencies": {
67
+ "bun": "^1.3.4"
68
68
  }
69
69
  }
@@ -89,12 +89,20 @@ function bumpRcVersion(currentVersion) {
89
89
  }
90
90
 
91
91
  function promoteToStable(currentVersion) {
92
- // 1.0.9-rc.2 -> 1.0.9
93
- const match = currentVersion.match(/^(\d+\.\d+\.\d+)-rc\.\d+$/);
94
- if (!match) {
95
- throw new Error(`Cannot promote: ${currentVersion} is not an RC version`);
92
+ // If RC version: 1.0.9-rc.2 -> 1.0.9
93
+ const rcMatch = currentVersion.match(/^(\d+\.\d+\.\d+)-rc\.\d+$/);
94
+ if (rcMatch) {
95
+ return rcMatch[1];
96
+ }
97
+
98
+ // If already stable: 1.1.1 -> 1.1.2 (bump patch for new stable release)
99
+ const stableMatch = currentVersion.match(/^(\d+)\.(\d+)\.(\d+)$/);
100
+ if (stableMatch) {
101
+ const [, major, minor, patch] = stableMatch;
102
+ return `${major}.${minor}.${parseInt(patch) + 1}`;
96
103
  }
97
- return match[1];
104
+
105
+ throw new Error(`Invalid version format: ${currentVersion}`);
98
106
  }
99
107
 
100
108
  function createTag(version) {
@@ -0,0 +1,60 @@
1
+ #!/bin/bash
2
+ # Test that the package works with npx (simulates fresh user install)
3
+ # This catches path resolution issues that static analysis can't detect
4
+
5
+ set -e
6
+
7
+ echo "=== Testing npx compatibility ==="
8
+
9
+ # Create temp directory
10
+ TEST_DIR=$(mktemp -d)
11
+ trap "rm -rf $TEST_DIR" EXIT
12
+
13
+ # Pack the current package
14
+ echo "Packing package..."
15
+ PACK_OUTPUT=$(npm pack --pack-destination "$TEST_DIR" 2>&1)
16
+ PACK_FILE=$(echo "$PACK_OUTPUT" | grep -E '\.tgz$' | tail -1)
17
+
18
+ # If npm pack fails, exit with an error
19
+ if [ -z "$PACK_FILE" ] || [ ! -f "$TEST_DIR/$PACK_FILE" ]; then
20
+ echo "✗ Failed to pack package with npm"
21
+ echo "Pack output: $PACK_OUTPUT"
22
+ exit 1
23
+ fi
24
+ echo "Packed: $PACK_FILE"
25
+
26
+ # Install in isolated environment using npm
27
+ echo "Installing in isolated environment..."
28
+ cd "$TEST_DIR"
29
+ echo '{"name":"test-npx-install","private":true}' > package.json
30
+ npm install "./$PACK_FILE" > /dev/null 2>&1
31
+
32
+ # Test that it starts (with timeout)
33
+ echo "Testing server startup via npx..."
34
+ timeout 30 npx pgserve --no-cluster --port 15432 > output.log 2>&1 &
35
+ PID=$!
36
+
37
+ # Wait for ready signal (Server started successfully!)
38
+ for i in {1..60}; do
39
+ if grep -q "Server started successfully" output.log 2>/dev/null; then
40
+ echo "✓ Server started successfully via npx"
41
+ kill $PID 2>/dev/null || true
42
+ wait $PID 2>/dev/null || true
43
+ echo "=== npx test PASSED ==="
44
+ exit 0
45
+ fi
46
+ if ! kill -0 $PID 2>/dev/null; then
47
+ echo "✗ Server exited unexpectedly"
48
+ cat output.log
49
+ echo "=== npx test FAILED ==="
50
+ exit 1
51
+ fi
52
+ sleep 0.5
53
+ done
54
+
55
+ # Timeout
56
+ kill $PID 2>/dev/null || true
57
+ echo "✗ Server did not start within timeout"
58
+ cat output.log
59
+ echo "=== npx test FAILED ==="
60
+ exit 1
@@ -1,60 +0,0 @@
1
- #!/bin/bash
2
- # Test that the package works with bunx (simulates fresh install)
3
- # This catches path resolution issues that static analysis can't detect
4
-
5
- set -e
6
-
7
- echo "=== Testing bunx compatibility ==="
8
-
9
- # Create temp directory
10
- TEST_DIR=$(mktemp -d)
11
- trap "rm -rf $TEST_DIR" EXIT
12
-
13
- # Pack the current package (--ignore-scripts to skip prepare/husky in CI)
14
- echo "Packing package..."
15
- PACK_PATH=$(bun pm pack --destination "$TEST_DIR" --ignore-scripts --quiet 2>&1)
16
- PACK_FILE=$(basename "$PACK_PATH" 2>/dev/null)
17
-
18
- # If bun pm pack fails, exit with an error
19
- if [ -z "$PACK_FILE" ] || [ ! -f "$TEST_DIR/$PACK_FILE" ]; then
20
- echo "✗ Failed to pack package with bun"
21
- echo "Pack output: $PACK_PATH"
22
- exit 1
23
- fi
24
- echo "Packed: $PACK_FILE"
25
-
26
- # Extract and install in isolated environment
27
- echo "Installing in isolated environment..."
28
- cd "$TEST_DIR"
29
- echo '{"name":"test","type":"module"}' > package.json
30
- bun add "./$PACK_FILE" > /dev/null 2>&1 || bun install "$PACK_FILE" > /dev/null 2>&1
31
-
32
- # Test that it starts (with timeout)
33
- echo "Testing server startup..."
34
- timeout 8 bunx pgserve --no-cluster --port 15432 > output.log 2>&1 &
35
- PID=$!
36
-
37
- # Wait for ready signal
38
- for i in {1..20}; do
39
- if grep -q "READY" output.log 2>/dev/null; then
40
- echo "✓ Server started successfully"
41
- kill $PID 2>/dev/null || true
42
- wait $PID 2>/dev/null || true
43
- echo "=== bunx test PASSED ==="
44
- exit 0
45
- fi
46
- if ! kill -0 $PID 2>/dev/null; then
47
- echo "✗ Server exited unexpectedly"
48
- cat output.log
49
- echo "=== bunx test FAILED ==="
50
- exit 1
51
- fi
52
- sleep 0.5
53
- done
54
-
55
- # Timeout
56
- kill $PID 2>/dev/null || true
57
- echo "✗ Server did not start within timeout"
58
- cat output.log
59
- echo "=== bunx test FAILED ==="
60
- exit 1