neon-testing 2.7.0 → 3.0.0-beta.1

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.
Files changed (80) hide show
  1. package/README.md +58 -41
  2. package/dist/bun.d.ts +11 -0
  3. package/dist/bun.d.ts.map +1 -0
  4. package/dist/bun.js +10 -0
  5. package/dist/bun.js.map +1 -0
  6. package/dist/{index.d.ts → core.d.ts} +49 -29
  7. package/dist/core.d.ts.map +1 -0
  8. package/dist/{index.js → core.js} +34 -122
  9. package/dist/core.js.map +1 -0
  10. package/dist/lib/barrier.d.ts.map +1 -0
  11. package/dist/lib/barrier.js.map +1 -0
  12. package/dist/lib/cleared-database-url.d.ts +10 -0
  13. package/dist/lib/cleared-database-url.d.ts.map +1 -0
  14. package/dist/lib/cleared-database-url.js +10 -0
  15. package/dist/lib/cleared-database-url.js.map +1 -0
  16. package/dist/lib/expires-in.d.ts +5 -0
  17. package/dist/lib/expires-in.d.ts.map +1 -0
  18. package/dist/lib/expires-in.js +21 -0
  19. package/dist/lib/expires-in.js.map +1 -0
  20. package/dist/lib/singleton.d.ts.map +1 -0
  21. package/dist/lib/singleton.js.map +1 -0
  22. package/dist/lib/ssl.d.ts +9 -0
  23. package/dist/lib/ssl.d.ts.map +1 -0
  24. package/dist/lib/ssl.js +21 -0
  25. package/dist/lib/ssl.js.map +1 -0
  26. package/dist/lib/with-retry.d.ts +12 -0
  27. package/dist/lib/with-retry.d.ts.map +1 -0
  28. package/dist/lib/with-retry.js +39 -0
  29. package/dist/lib/with-retry.js.map +1 -0
  30. package/dist/lib/ws-error.d.ts +6 -0
  31. package/dist/lib/ws-error.d.ts.map +1 -0
  32. package/dist/lib/ws-error.js +15 -0
  33. package/dist/lib/ws-error.js.map +1 -0
  34. package/dist/setup.d.ts +2 -0
  35. package/dist/setup.d.ts.map +1 -0
  36. package/dist/setup.js +9 -0
  37. package/dist/setup.js.map +1 -0
  38. package/dist/utils.d.ts +2 -8
  39. package/dist/utils.d.ts.map +1 -1
  40. package/dist/utils.js +2 -8
  41. package/dist/utils.js.map +1 -1
  42. package/dist/vitest.d.ts +11 -0
  43. package/dist/vitest.d.ts.map +1 -0
  44. package/dist/vitest.js +9 -0
  45. package/dist/vitest.js.map +1 -0
  46. package/package.json +62 -30
  47. package/src/bun.ts +13 -0
  48. package/src/core.ts +375 -0
  49. package/src/lib/barrier.ts +22 -0
  50. package/src/lib/cleared-database-url.ts +9 -0
  51. package/src/lib/expires-in.ts +24 -0
  52. package/src/lib/singleton.ts +10 -0
  53. package/src/lib/ssl.ts +24 -0
  54. package/src/lib/with-retry.ts +55 -0
  55. package/src/lib/ws-error.ts +17 -0
  56. package/src/setup.ts +10 -0
  57. package/src/utils.ts +2 -0
  58. package/src/vitest.ts +12 -0
  59. package/dist/barrier.d.ts.map +0 -1
  60. package/dist/barrier.js.map +0 -1
  61. package/dist/browser-empty.d.ts +0 -2
  62. package/dist/browser-empty.d.ts.map +0 -1
  63. package/dist/browser-empty.js +0 -4
  64. package/dist/browser-empty.js.map +0 -1
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/index.js.map +0 -1
  67. package/dist/singleton.d.ts.map +0 -1
  68. package/dist/singleton.js.map +0 -1
  69. package/dist/vite-plugin.d.ts +0 -13
  70. package/dist/vite-plugin.d.ts.map +0 -1
  71. package/dist/vite-plugin.js +0 -26
  72. package/dist/vite-plugin.js.map +0 -1
  73. package/dist/vitest-setup.d.ts +0 -3
  74. package/dist/vitest-setup.d.ts.map +0 -1
  75. package/dist/vitest-setup.js +0 -10
  76. package/dist/vitest-setup.js.map +0 -1
  77. /package/dist/{barrier.d.ts → lib/barrier.d.ts} +0 -0
  78. /package/dist/{barrier.js → lib/barrier.js} +0 -0
  79. /package/dist/{singleton.d.ts → lib/singleton.d.ts} +0 -0
  80. /package/dist/{singleton.js → lib/singleton.js} +0 -0
package/README.md CHANGED
@@ -5,7 +5,9 @@
5
5
  [![GitHub release](https://img.shields.io/github/v/release/starmode-base/neon-testing)](https://github.com/starmode-base/neon-testing/releases)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue)](LICENSE)
7
7
 
8
- A [Vitest](https://vitest.dev/) utility for seamless integration tests with [Neon Postgres](https://neon.com/). <!-- A [STΛR MODΞ](https://starmode.dev) open-source project. -->
8
+ A testing utility for seamless integration tests with [Neon Postgres](https://neon.com/), for [Vitest](https://vitest.dev/) and [Bun Test](https://bun.com/docs/cli/test).
9
+
10
+ <!-- A [STΛR MODΞ](https://starmode.dev) open-source project. -->
9
11
 
10
12
  Each test file runs against its own isolated PostgreSQL database (Neon branch), ensuring clean, parallel, and reproducible testing of code that interacts with a database. Because it uses a real, isolated clone of your production database, you can test code logic that depends on database features, such as transaction rollbacks, unique constraints, and more.
11
13
 
@@ -29,7 +31,7 @@ Each test file runs against its own isolated PostgreSQL database (Neon branch),
29
31
  - 🔄 **Isolated test environments** - Each test file runs against its own Postgres database with your actual schema and constraints
30
32
  - 🧹 **Automatic cleanup** - Neon test branches are created and destroyed automatically
31
33
  - 🐛 **Debug friendly** - Option to preserve test branches for debugging failed tests
32
- - 🛡️ **TypeScript native** - With JavaScript support
34
+ - 🛡️ **TypeScript native** - Ships compiled JavaScript with type declarations and source maps too
33
35
  - 🎯 **ESM only** - No CommonJS support
34
36
 
35
37
  ## How it works
@@ -41,7 +43,9 @@ Each test file runs against its own isolated PostgreSQL database (Neon branch),
41
43
 
42
44
  ### Test isolation
43
45
 
44
- Tests in the same file share a single database instance (Neon branch). This means test files are fully isolated from each other, but individual tests within a file are intentionally not isolated. This works because Vitest runs test files in [parallel](https://vitest.dev/guide/parallelism.html), while tests within each file run sequentially.
46
+ Each test file runs against its own database instance (Neon branch), so test files are fully isolated from each other. Tests within a single file share that branch and run sequentially individual tests within a file are intentionally not isolated.
47
+
48
+ Vitest and Bun differ in how they execute files. Vitest runs each file in its own process, [in parallel](https://vitest.dev/guide/parallelism.html), while Bun runs every file in [a single shared process](https://bun.com/docs/test), one after another by default. File-level isolation is the same on both — each file gets its own branch — but Vitest creates those branches concurrently whereas Bun creates them one at a time.
45
49
 
46
50
  If you prefer individual tests to be isolated, you can [reset the database](examples/isolated.test.ts) in a `beforeEach` lifecycle hook.
47
51
 
@@ -59,7 +63,11 @@ Test branches are automatically deleted after your tests complete. As a safety n
59
63
  ### Install
60
64
 
61
65
  ```sh
66
+ # Vitest
62
67
  bun add -d neon-testing vitest
68
+
69
+ # Bun Test
70
+ bun add -d neon-testing
63
71
  ```
64
72
 
65
73
  ### Minimal example
@@ -67,7 +75,7 @@ bun add -d neon-testing vitest
67
75
  ```ts
68
76
  // minimal.test.ts
69
77
  import { expect, test } from "vitest";
70
- import { makeNeonTesting } from "neon-testing";
78
+ import { makeNeonTesting } from "neon-testing/vitest";
71
79
  import { Pool } from "@neondatabase/serverless";
72
80
 
73
81
  // Enable Neon test branch for this test file
@@ -75,6 +83,7 @@ makeNeonTesting({
75
83
  apiKey: process.env.NEON_API_KEY!,
76
84
  projectId: process.env.NEON_PROJECT_ID!,
77
85
  // Recommended for Neon WebSocket drivers to automatically close connections
86
+ // (Vitest only)
78
87
  autoCloseWebSockets: true,
79
88
  })();
80
89
 
@@ -93,21 +102,29 @@ Source: [`examples/minimal.test.ts`](examples/minimal.test.ts)
93
102
 
94
103
  ### Recommended usage
95
104
 
96
- #### 1. Plugin setup
105
+ #### 1. Setup
97
106
 
98
- First, add the Vite plugin to clear any existing `DATABASE_URL` environment variable before tests run, ensuring tests use isolated test databases.
107
+ Register `neon-testing/setup` so any existing `DATABASE_URL` is cleared before tests run. A test file that forgets to enable branching then fails loudly instead of silently writing to a real database.
99
108
 
100
109
  ```ts
101
110
  // vitest.config.ts
102
111
  import { defineConfig } from "vitest/config";
103
- import { neonTesting } from "neon-testing/vite";
104
112
 
105
113
  export default defineConfig({
106
- plugins: [neonTesting()],
114
+ test: {
115
+ setupFiles: ["neon-testing/setup"],
116
+ },
107
117
  });
108
118
  ```
109
119
 
110
- This plugin is recommended but not required. Without it, tests might accidentally use your existing `DATABASE_URL` (from `.env` files or environment variables) instead of the isolated test databases that Neon Testing creates. This can happen if you forget to call `neonTesting()` in a test file where database writes happen.
120
+ For Bun, add it to `bunfig.toml` instead:
121
+
122
+ ```toml
123
+ [test]
124
+ preload = ["neon-testing/setup"]
125
+ ```
126
+
127
+ Recommended but not required. Without it, a test file that forgets to call `neonTesting()` could fall back to your real `DATABASE_URL` (from `.env` or the environment) instead of an isolated test branch.
111
128
 
112
129
  #### 2. Configuration
113
130
 
@@ -115,7 +132,7 @@ Use the `makeNeonTesting` factory to generate a lifecycle function for your test
115
132
 
116
133
  ```ts
117
134
  // neon-testing.ts
118
- import { makeNeonTesting } from "neon-testing";
135
+ import { makeNeonTesting } from "neon-testing/vitest"; // or "neon-testing/bun"
119
136
 
120
137
  // Export a configured lifecycle function to use in test files
121
138
  export const neonTesting = makeNeonTesting({
@@ -139,6 +156,7 @@ import { Pool } from "@neondatabase/serverless";
139
156
  // Enable Neon test branch for this test file
140
157
  neonTesting({
141
158
  // Recommended for Neon WebSocket drivers to automatically close connections
159
+ // (Vitest only)
142
160
  autoCloseWebSockets: true,
143
161
  });
144
162
 
@@ -157,20 +175,28 @@ Source: [`examples/recommended.test.ts`](examples/recommended.test.ts)
157
175
 
158
176
  ## Drivers
159
177
 
160
- This library works with any database driver that supports Neon Postgres and Vitest. The examples below demonstrate connection management, transaction support, and test isolation patterns for some popular drivers.
178
+ This library works with any database driver that supports Neon Postgres.
179
+
180
+ ### Closing connections
181
+
182
+ Some drivers keep a connection open after a test finishes — [Neon's WebSocket driver](https://neon.com/docs/serverless/serverless-driver#use-the-driver-over-websockets) and [node-postgres](https://www.npmjs.com/package/pg). If the test branch is deleted while a connection is still open, the driver errors. Avoid it in one of three ways:
161
183
 
162
- **IMPORTANT:** For [Neon WebSocket drivers](https://neon.com/docs/serverless/serverless-driver), enable `autoCloseWebSockets` in your `makeNeonTesting()` or `neonTesting()` configuration. This automatically closes WebSocket connections when deleting test branches, preventing connection termination errors.
184
+ - close the connection yourself (e.g. `await pool.end()`)
185
+ - enable `autoCloseWebSockets` (WebSocket driver only, Vitest only)
186
+ - keep the branch with `deleteBranch: false`
187
+
188
+ [Neon's HTTP driver](https://neon.com/docs/serverless/serverless-driver#use-the-driver-over-http) and [Postgres.js](https://www.npmjs.com/package/postgres) close their own connections, so they need none of this.
163
189
 
164
190
  ### Examples
165
191
 
166
- - [Neon serverless WebSocket](examples/drivers/ws-neon.test.ts)
167
- - [Neon serverless WebSocket + Drizzle](examples/drivers/ws-neon-drizzle.test.ts)
168
- - [Neon serverless HTTP](examples/drivers/http-neon.test.ts)
169
- - [Neon serverless HTTP + Drizzle](examples/drivers/http-neon-drizzle.test.ts)
170
- - [node-postgres](examples/drivers/tcp-pg.test.ts)
171
- - [node-postgres + Drizzle](examples/drivers/tcp-pg-drizzle.test.ts)
172
- - [Postgres.js](examples/drivers/tcp-postgres.test.ts)
173
- - [Postgres.js + Drizzle](examples/drivers/tcp-postgres-drizzle.test.ts)
192
+ - [Neon serverless WebSocket](tests-vitest/drivers/ws-neon.test.ts)
193
+ - [Neon serverless WebSocket + Drizzle](tests-vitest/drivers/ws-neon-drizzle.test.ts)
194
+ - [Neon serverless HTTP](tests-vitest/drivers/http-neon.test.ts)
195
+ - [Neon serverless HTTP + Drizzle](tests-vitest/drivers/http-neon-drizzle.test.ts)
196
+ - [node-postgres](tests-vitest/drivers/tcp-pg.test.ts)
197
+ - [node-postgres + Drizzle](tests-vitest/drivers/tcp-pg-drizzle.test.ts)
198
+ - [Postgres.js](tests-vitest/drivers/tcp-postgres.test.ts)
199
+ - [Postgres.js + Drizzle](tests-vitest/drivers/tcp-postgres-drizzle.test.ts)
174
200
 
175
201
  ## Configuration
176
202
 
@@ -179,10 +205,10 @@ You configure Neon Testing in two places:
179
205
  - **Base settings** in `makeNeonTesting()`
180
206
  - **Optional overrides** when calling the returned function (e.g., `neonTesting()`)
181
207
 
182
- Configure these in `makeNeonTesting()` and optionally override per test file when calling the returned function.
208
+ Configure these in `makeNeonTesting()`; every option except `apiKey` can also be overridden per test file when calling the returned function.
183
209
 
184
210
  ```ts
185
- export interface NeonTestingOptions {
211
+ export interface MakeNeonTestingOptions {
186
212
  /**
187
213
  * The Neon API key, this is used to create and teardown test branches (required)
188
214
  *
@@ -224,6 +250,8 @@ export interface NeonTestingOptions {
224
250
  * Suppresses the specific Neon WebSocket "Connection terminated unexpectedly"
225
251
  * error that may surface when deleting a branch with open WebSocket
226
252
  * connections
253
+ *
254
+ * Vitest only.
227
255
  */
228
256
  autoCloseWebSockets?: boolean;
229
257
  /**
@@ -273,7 +301,7 @@ Configure the base settings in `makeNeonTesting()`:
273
301
 
274
302
  ```ts
275
303
  // neon-testing.ts
276
- import { makeNeonTesting } from "neon-testing";
304
+ import { makeNeonTesting } from "neon-testing/vitest";
277
305
 
278
306
  export const neonTesting = makeNeonTesting({
279
307
  apiKey: process.env.NEON_API_KEY!,
@@ -373,7 +401,9 @@ It's easy to run Neon integration tests in CI/CD pipelines:
373
401
 
374
402
  ## API Reference
375
403
 
376
- ### Main exports (`neon-testing`)
404
+ ### Runner entry (`neon-testing/vitest` or `neon-testing/bun`)
405
+
406
+ Both entries export the same `makeNeonTesting`; they differ only in which runner's `beforeAll`/`afterAll` hooks they wire up. (For other runners, `neon-testing/core` takes the hooks directly.)
377
407
 
378
408
  #### makeNeonTesting(options)
379
409
 
@@ -381,7 +411,7 @@ The factory function that creates a configured lifecycle function for your tests
381
411
 
382
412
  ```ts
383
413
  // neon-testing.ts
384
- import { makeNeonTesting } from "neon-testing";
414
+ import { makeNeonTesting } from "neon-testing/vitest";
385
415
 
386
416
  export const neonTesting = makeNeonTesting({
387
417
  apiKey: process.env.NEON_API_KEY!,
@@ -434,24 +464,11 @@ test("access branch information", () => {
434
464
 
435
465
  See the [Neon Branch API documentation](https://api-docs.neon.tech/reference/getprojectbranch) for all available properties.
436
466
 
437
- ### Vite plugin (`neon-testing/vite`)
438
-
439
- The Vite plugin clears any existing `DATABASE_URL` environment variable before tests run, ensuring tests use isolated test databases.
440
-
441
- ```ts
442
- import { defineConfig } from "vitest/config";
443
- import { neonTesting } from "neon-testing/vite";
444
-
445
- export default defineConfig({
446
- plugins: [neonTesting()],
447
- });
448
- ```
449
-
450
- **Options:**
467
+ ### Setup (`neon-testing/setup`)
451
468
 
452
- - `debug` (boolean, default: `false`) - Enable debug logging
469
+ A zero-config preload that clears `DATABASE_URL` before tests run, so a file that forgets to call `neonTesting()` can't reach a real database. Register it with your runner — Vitest `setupFiles` or Bun `bunfig` `preload` (see [Recommended usage](#recommended-usage)).
453
470
 
454
- This plugin is recommended but not required. Without it, tests might accidentally use your existing `DATABASE_URL` instead of isolated test databases.
471
+ Set `NEON_TESTING_DEBUG=true` to log when it clears a value.
455
472
 
456
473
  ### Utilities (`neon-testing/utils`)
457
474
 
package/dist/bun.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { MakeNeonTestingOptions } from "./core.js";
2
+ export type { MakeNeonTestingOptions, NeonTestingOptions } from "./core.js";
3
+ /**
4
+ * Create a Neon test-branch factory wired to Bun's lifecycle hooks.
5
+ */
6
+ export declare function makeNeonTesting(options: MakeNeonTestingOptions): {
7
+ (overrides?: import("./core.js").NeonTestingOptions): () => import("@neondatabase/api-client").Branch | undefined;
8
+ deleteAllTestBranches: () => Promise<void>;
9
+ api: import("@neondatabase/api-client").Api<unknown>;
10
+ };
11
+ //# sourceMappingURL=bun.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun.d.ts","sourceRoot":"","sources":["../src/bun.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,WAAW,CAAC;AAExD,YAAY,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE5E;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB;;;;EAE9D"}
package/dist/bun.js ADDED
@@ -0,0 +1,10 @@
1
+ /// <reference types="bun" />
2
+ import { beforeAll, afterAll } from "bun:test";
3
+ import { makeNeonTestingCore } from "./core.js";
4
+ /**
5
+ * Create a Neon test-branch factory wired to Bun's lifecycle hooks.
6
+ */
7
+ export function makeNeonTesting(options) {
8
+ return makeNeonTestingCore({ ...options, hooks: { beforeAll, afterAll } });
9
+ }
10
+ //# sourceMappingURL=bun.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bun.js","sourceRoot":"","sources":["../src/bun.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAC7B,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAKhD;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,OAA+B;IAC7D,OAAO,mBAAmB,CAAC,EAAE,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC7E,CAAC"}
@@ -2,7 +2,30 @@
2
2
  * https://neon.com/docs/reference/typescript-sdk
3
3
  */
4
4
  import { type Branch } from "@neondatabase/api-client";
5
- export interface NeonTestingOptions {
5
+ /**
6
+ * Test-runner lifecycle hooks
7
+ *
8
+ * Injected so the core stays runner-agnostic. Most users don't build these by
9
+ * hand — import the pre-wired factory from `neon-testing/vitest` or
10
+ * `neon-testing/bun`, which supply them automatically.
11
+ */
12
+ export interface NeonTestingHooks {
13
+ beforeAll: (fn: () => void | Promise<void>) => void;
14
+ afterAll: (fn: () => void | Promise<void>) => void;
15
+ }
16
+ /**
17
+ * Configuration for the Neon test-branch factory.
18
+ *
19
+ * `hooks` are injected by the per-runner entry (`neon-testing/vitest` or
20
+ * `neon-testing/bun`); the remaining fields control how each test branch is
21
+ * created and torn down.
22
+ */
23
+ export interface MakeNeonTestingCoreOptions {
24
+ /**
25
+ * Test-runner lifecycle hooks (supplied by `neon-testing/vitest` or
26
+ * `neon-testing/bun`)
27
+ */
28
+ hooks: NeonTestingHooks;
6
29
  /**
7
30
  * The Neon API key, this is used to create and teardown test branches (required)
8
31
  *
@@ -44,6 +67,9 @@ export interface NeonTestingOptions {
44
67
  * Suppresses the specific Neon WebSocket "Connection terminated unexpectedly"
45
68
  * error that may surface when deleting a branch with open WebSocket
46
69
  * connections
70
+ *
71
+ * Vitest only — under Bun the uncaughtException suppression does not
72
+ * intercept, so close connections explicitly there instead.
47
73
  */
48
74
  autoCloseWebSockets?: boolean;
49
75
  /**
@@ -85,44 +111,38 @@ export interface NeonTestingOptions {
85
111
  */
86
112
  sslMode?: "verify-full" | "require";
87
113
  }
88
- /** Options for overriding test database setup (excludes apiKey) */
89
- export type NeonTestingOverrides = Omit<Partial<NeonTestingOptions>, "apiKey">;
114
+ /** Options for the `makeNeonTesting` factories core options minus the injected hooks */
115
+ export type MakeNeonTestingOptions = Omit<MakeNeonTestingCoreOptions, "hooks">;
116
+ /** Per-file overrides accepted by the returned `neonTesting()` function */
117
+ export type NeonTestingOptions = Partial<Omit<MakeNeonTestingOptions, "apiKey">>;
90
118
  /**
91
- * Factory function that creates a Neon test database setup/teardown function
92
- * for Vitest test suites.
93
- *
94
- * @param factoryOptions - Configuration options (see {@link NeonTestingOptions})
95
- * @returns A setup/teardown function with attached utilities:
96
- * - `deleteAllTestBranches()` - Cleanup method to delete all test branches
97
- * - `api` - Direct access to the Neon API client
119
+ * Low-level factory that creates a Neon test-branch setup/teardown function.
120
+ * Runner-agnostic you inject the lifecycle hooks via `options.hooks`.
98
121
  *
99
- * @example
100
- * ```ts
101
- * // neon-testing.ts
102
- * import { makeNeonTesting } from "neon-testing";
122
+ * Most users want a pre-wired entry instead: `neon-testing/vitest` or
123
+ * `neon-testing/bun`. Reach for this core factory only for other runners
124
+ * (jest, node:test, …).
103
125
  *
104
- * export const neonTesting = makeNeonTesting({
105
- * apiKey: "apiKey",
106
- * projectId: "projectId",
107
- * });
108
- * ```
126
+ * @param factoryOptions - see {@link MakeNeonTestingCoreOptions}
127
+ * @returns A setup/teardown function with attached utilities:
128
+ * - `deleteAllTestBranches()` - delete all test branches
129
+ * - `api` - the Neon API client
109
130
  *
110
131
  * @example
111
132
  * ```ts
112
- * // my-test.test.ts
113
- * import { neonTesting } from "./neon-testing";
114
- *
115
- * const getBranch = neonTesting();
133
+ * import { beforeAll, afterAll } from "vitest"; // or any runner
134
+ * import { makeNeonTestingCore } from "neon-testing/core";
116
135
  *
117
- * test("my test", () => {
118
- * const branch = getBranch();
119
- * console.log(branch.id);
136
+ * export const neonTesting = makeNeonTestingCore({
137
+ * apiKey: process.env.NEON_API_KEY!,
138
+ * projectId: process.env.NEON_PROJECT_ID!,
139
+ * hooks: { beforeAll, afterAll },
120
140
  * });
121
141
  * ```
122
142
  */
123
- export declare function makeNeonTesting(factoryOptions: NeonTestingOptions): {
124
- (overrides?: NeonTestingOverrides): () => Branch | undefined;
143
+ export declare function makeNeonTestingCore(factoryOptions: MakeNeonTestingCoreOptions): {
144
+ (overrides?: NeonTestingOptions): () => Branch | undefined;
125
145
  deleteAllTestBranches: () => Promise<void>;
126
146
  api: import("@neondatabase/api-client").Api<unknown>;
127
147
  };
128
- //# sourceMappingURL=index.d.ts.map
148
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAGL,KAAK,MAAM,EACZ,MAAM,0BAA0B,CAAC;AAOlC;;;;;;GAMG;AACH,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;IACpD,QAAQ,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;CACpD;AAED;;;;;;GAMG;AACH,MAAM,WAAW,0BAA0B;IACzC;;;OAGG;IACH,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;OAEG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC/B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,aAAa,GAAG,SAAS,CAAC;CACrC;AAED,0FAA0F;AAC1F,MAAM,MAAM,sBAAsB,GAAG,IAAI,CAAC,0BAA0B,EAAE,OAAO,CAAC,CAAC;AAE/E,2EAA2E;AAC3E,MAAM,MAAM,kBAAkB,GAAG,OAAO,CACtC,IAAI,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CACvC,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,mBAAmB,CACjC,cAAc,EAAE,0BAA0B;iBA0C5B,kBAAkB;;;EA6KjC"}
@@ -2,77 +2,37 @@
2
2
  * https://neon.com/docs/reference/typescript-sdk
3
3
  */
4
4
  import { createApiClient, EndpointType, } from "@neondatabase/api-client";
5
- import { afterAll, beforeAll } from "vitest";
5
+ import { applySslMode } from "./lib/ssl.js";
6
+ import { validateExpiresIn } from "./lib/expires-in.js";
7
+ import { neonWsErrorHandler } from "./lib/ws-error.js";
8
+ import { withRetry } from "./lib/with-retry.js";
9
+ import { CLEARED_DATABASE_URL } from "./lib/cleared-database-url.js";
6
10
  /**
7
- * Rewrite the `sslmode` (and related) query params on a Neon connection URI.
11
+ * Low-level factory that creates a Neon test-branch setup/teardown function.
12
+ * Runner-agnostic — you inject the lifecycle hooks via `options.hooks`.
8
13
  *
9
- * Neon's API returns URIs with `sslmode=require`. In pg v9 /
10
- * pg-connection-string v3 this mode will adopt libpq semantics (encrypt
11
- * without CA verification) instead of today's effective `verify-full`.
12
- */
13
- function applySslMode(uri, mode) {
14
- if (mode === undefined)
15
- return uri;
16
- const url = new URL(uri);
17
- url.searchParams.set("sslmode", mode);
18
- if (mode === "require") {
19
- url.searchParams.set("uselibpqcompat", "true");
20
- }
21
- else {
22
- url.searchParams.delete("uselibpqcompat");
23
- }
24
- return url.toString();
25
- }
26
- /**
27
- * Validates the expiresIn option
28
- */
29
- function validateExpiresIn(expiresIn) {
30
- if (expiresIn !== null && expiresIn !== undefined) {
31
- if (!Number.isInteger(expiresIn)) {
32
- throw new Error("expiresIn must be an integer");
33
- }
34
- if (expiresIn <= 0) {
35
- throw new Error("expiresIn must be a positive integer");
36
- }
37
- if (expiresIn > 2592000) {
38
- throw new Error("expiresIn must not exceed 30 days (2,592,000 seconds)");
39
- }
40
- }
41
- }
42
- /**
43
- * Factory function that creates a Neon test database setup/teardown function
44
- * for Vitest test suites.
14
+ * Most users want a pre-wired entry instead: `neon-testing/vitest` or
15
+ * `neon-testing/bun`. Reach for this core factory only for other runners
16
+ * (jest, node:test, ).
45
17
  *
46
- * @param factoryOptions - Configuration options (see {@link NeonTestingOptions})
18
+ * @param factoryOptions - see {@link MakeNeonTestingCoreOptions}
47
19
  * @returns A setup/teardown function with attached utilities:
48
- * - `deleteAllTestBranches()` - Cleanup method to delete all test branches
49
- * - `api` - Direct access to the Neon API client
20
+ * - `deleteAllTestBranches()` - delete all test branches
21
+ * - `api` - the Neon API client
50
22
  *
51
23
  * @example
52
24
  * ```ts
53
- * // neon-testing.ts
54
- * import { makeNeonTesting } from "neon-testing";
25
+ * import { beforeAll, afterAll } from "vitest"; // or any runner
26
+ * import { makeNeonTestingCore } from "neon-testing/core";
55
27
  *
56
- * export const neonTesting = makeNeonTesting({
57
- * apiKey: "apiKey",
58
- * projectId: "projectId",
59
- * });
60
- * ```
61
- *
62
- * @example
63
- * ```ts
64
- * // my-test.test.ts
65
- * import { neonTesting } from "./neon-testing";
66
- *
67
- * const getBranch = neonTesting();
68
- *
69
- * test("my test", () => {
70
- * const branch = getBranch();
71
- * console.log(branch.id);
28
+ * export const neonTesting = makeNeonTestingCore({
29
+ * apiKey: process.env.NEON_API_KEY!,
30
+ * projectId: process.env.NEON_PROJECT_ID!,
31
+ * hooks: { beforeAll, afterAll },
72
32
  * });
73
33
  * ```
74
34
  */
75
- export function makeNeonTesting(factoryOptions) {
35
+ export function makeNeonTestingCore(factoryOptions) {
76
36
  // Validate factory options
77
37
  validateExpiresIn(factoryOptions.expiresIn);
78
38
  const apiClient = createApiClient({ apiKey: factoryOptions.apiKey });
@@ -91,15 +51,15 @@ export function makeNeonTesting(factoryOptions) {
91
51
  }
92
52
  }
93
53
  /**
94
- * Setup/teardown function for Vitest test suites
54
+ * Setup/teardown function for a test file.
95
55
  *
96
- * Registers Vitest lifecycle hooks that:
56
+ * Registers lifecycle hooks (via the injected `hooks`) that:
97
57
  * - Create an isolated test branch from your parent branch
98
58
  * - Set `DATABASE_URL` environment variable to the test branch connection URI
99
59
  * - Automatically delete the test branch after tests complete (unless `deleteBranch: false`)
100
60
  * - Automatically expire branches after 10 minutes for cleanup (unless `expiresIn: null`)
101
61
  *
102
- * @param overrides - Optional overrides for the factory options
62
+ * @param overrides - Optional per-file overrides for the factory options
103
63
  * @returns A function that provides access to the current Neon branch object
104
64
  */
105
65
  const neonTesting = (
@@ -131,9 +91,11 @@ export function makeNeonTesting(factoryOptions) {
131
91
  const { data } = await apiClient.createProjectBranch(options.projectId, {
132
92
  branch: {
133
93
  name: `test/${crypto.randomUUID()}`,
134
- parent_id: options.parentBranchId,
135
- init_source: options.schemaOnly ? "schema-only" : undefined,
136
- expires_at: expiresAt,
94
+ ...(options.parentBranchId
95
+ ? { parent_id: options.parentBranchId }
96
+ : {}),
97
+ ...(options.schemaOnly ? { init_source: "schema-only" } : {}),
98
+ ...(expiresAt ? { expires_at: expiresAt } : {}),
137
99
  },
138
100
  endpoints: [{ type: EndpointType.ReadWrite }],
139
101
  annotation_value: {
@@ -184,7 +146,7 @@ export function makeNeonTesting(factoryOptions) {
184
146
  await apiClient.deleteProjectBranch(options.projectId, branch.id);
185
147
  branch = undefined;
186
148
  }
187
- beforeAll(async () => {
149
+ factoryOptions.hooks.beforeAll(async () => {
188
150
  process.env.DATABASE_URL = await withRetry(createBranch, {
189
151
  maxRetries: 8,
190
152
  baseDelayMs: 1000,
@@ -212,8 +174,10 @@ export function makeNeonTesting(factoryOptions) {
212
174
  }
213
175
  }
214
176
  });
215
- afterAll(async () => {
216
- process.env.DATABASE_URL = undefined;
177
+ factoryOptions.hooks.afterAll(async () => {
178
+ // Overwrite (not `delete`) so DATABASE_URL no longer points at the test
179
+ // branch; see CLEARED_DATABASE_URL for why a sentinel rather than delete.
180
+ process.env.DATABASE_URL = CLEARED_DATABASE_URL;
217
181
  // Close all tracked Neon WebSocket connections before deleting the branch
218
182
  if (options.autoCloseWebSockets && neonSockets) {
219
183
  // Suppress Neon WebSocket "Connection terminated unexpectedly" error
@@ -237,56 +201,4 @@ export function makeNeonTesting(factoryOptions) {
237
201
  neonTesting.api = apiClient;
238
202
  return neonTesting;
239
203
  }
240
- /**
241
- * Error handler: Suppress Neon WebSocket "Connection terminated unexpectedly"
242
- * error
243
- */
244
- const neonWsErrorHandler = (error) => {
245
- const isNeonWsClose = error.message.includes("Connection terminated unexpectedly") &&
246
- error.stack?.includes("@neondatabase/serverless");
247
- if (isNeonWsClose) {
248
- // Swallow this specific Neon WS termination error
249
- return;
250
- }
251
- // For any other error, detach and rethrow
252
- throw error;
253
- };
254
- /**
255
- * Reusable API call wrapper with automatic retry on 423 errors with exponential
256
- * backoff
257
- *
258
- * https://neon.com/docs/reference/typescript-sdk#error-handling
259
- * https://neon.com/docs/changelog/2022-07-20
260
- */
261
- async function withRetry(fn, options) {
262
- if (!Number.isInteger(options.maxRetries) || options.maxRetries <= 0) {
263
- throw new Error("maxRetries must be a positive integer");
264
- }
265
- if (!Number.isInteger(options.baseDelayMs) || options.baseDelayMs <= 0) {
266
- throw new Error("baseDelayMs must be a positive integer");
267
- }
268
- for (let attempt = 1; attempt <= options.maxRetries; attempt++) {
269
- try {
270
- return await fn();
271
- }
272
- catch (error) {
273
- const status = error?.response?.status;
274
- // Retry on 423 (resource locked) with exponential backoff
275
- if (status === 423 && attempt < options.maxRetries) {
276
- const delay = options.baseDelayMs * Math.pow(2, attempt - 1);
277
- console.log(`API call failed with 423, retrying in ${delay}ms (attempt ${attempt}/${options.maxRetries})`);
278
- await new Promise((resolve) => setTimeout(resolve, delay));
279
- continue;
280
- }
281
- // Surface Neon API error details that are otherwise buried in the Axios error
282
- if (error?.response?.data?.code) {
283
- const { code, message } = error.response.data;
284
- throw new Error(`Neon API error - HTTP ${status} - ${code} - ${message}`, { cause: error });
285
- }
286
- // Non-API errors (network, timeouts, etc.) pass through as-is
287
- throw error;
288
- }
289
- }
290
- throw new Error("apiCallWithRetry reached unexpected end");
291
- }
292
- //# sourceMappingURL=index.js.map
204
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barrier.d.ts","sourceRoot":"","sources":["../../src/lib/barrier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,uBAiB1C"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"barrier.js","sourceRoot":"","sources":["../../src/lib/barrier.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAa;IACzC,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,OAAmB,CAAC;IAExB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;QAC5C,OAAO,GAAG,OAAO,CAAC;IACpB,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,IAAI,EAAE;QAChB,OAAO,EAAE,CAAC;QAEV,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;YACtB,OAAO,EAAE,CAAC;QACZ,CAAC;QAED,MAAM,OAAO,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Sentinel written to `DATABASE_URL` to clear it, instead of `delete`.
3
+ *
4
+ * Keeps the value a string for consumers that type `DATABASE_URL` as required
5
+ * (so the library never has to fight their env typing), and is an invalid
6
+ * connection string so a test that forgot `neonTesting()` fails loudly rather
7
+ * than silently reaching a real database.
8
+ */
9
+ export declare const CLEARED_DATABASE_URL = "neon-testing: DATABASE_URL cleared, call neonTesting()";
10
+ //# sourceMappingURL=cleared-database-url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleared-database-url.d.ts","sourceRoot":"","sources":["../../src/lib/cleared-database-url.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,2DAA2D,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Sentinel written to `DATABASE_URL` to clear it, instead of `delete`.
3
+ *
4
+ * Keeps the value a string for consumers that type `DATABASE_URL` as required
5
+ * (so the library never has to fight their env typing), and is an invalid
6
+ * connection string so a test that forgot `neonTesting()` fails loudly rather
7
+ * than silently reaching a real database.
8
+ */
9
+ export const CLEARED_DATABASE_URL = `neon-testing: DATABASE_URL cleared, call neonTesting()`;
10
+ //# sourceMappingURL=cleared-database-url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cleared-database-url.js","sourceRoot":"","sources":["../../src/lib/cleared-database-url.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,wDAAwD,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Validates the expiresIn option
3
+ */
4
+ export declare function validateExpiresIn(expiresIn: number | null | undefined): void;
5
+ //# sourceMappingURL=expires-in.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"expires-in.d.ts","sourceRoot":"","sources":["../../src/lib/expires-in.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,QAoBrE"}