pg-ephemeral 0.2.2 → 0.2.3
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/README.md +169 -0
- package/bin/pg-ephemeral.js +4 -0
- package/package.json +5 -5
package/README.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# pg-ephemeral npm Package
|
|
2
|
+
|
|
3
|
+
Node.js wrapper for [pg-ephemeral](https://github.com/mbj/mrs/tree/main/pg-ephemeral). Installs the platform-specific binary
|
|
4
|
+
via optional dependencies and provides a TypeScript API for ephemeral PostgreSQL instances.
|
|
5
|
+
|
|
6
|
+
Published on npm: [pg-ephemeral](https://www.npmjs.com/package/pg-ephemeral)
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install pg-ephemeral
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
Platform binaries are installed automatically for `linux-x64`, `linux-arm64`, and `darwin-arm64`.
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
### Direct connection
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
import { withConnection } from 'pg-ephemeral';
|
|
22
|
+
|
|
23
|
+
await withConnection(async (client) => {
|
|
24
|
+
const result = await client.query('SELECT 1 AS value');
|
|
25
|
+
console.log(result.rows[0].value);
|
|
26
|
+
});
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`withConnection` yields a connected `pg.Client` and closes it after the callback.
|
|
30
|
+
|
|
31
|
+
### Server handle
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { withServer } from 'pg-ephemeral';
|
|
35
|
+
|
|
36
|
+
await withServer(async (server) => {
|
|
37
|
+
console.log(server.url); // => "postgres://postgres:...@127.0.0.1:54321/postgres"
|
|
38
|
+
});
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`withServer` yields a `Server` with a `.url` property. The container shuts down
|
|
42
|
+
after the callback.
|
|
43
|
+
|
|
44
|
+
### Options
|
|
45
|
+
|
|
46
|
+
Both `withConnection` and `withServer` accept an options object:
|
|
47
|
+
|
|
48
|
+
| Option | Description | Default |
|
|
49
|
+
|----------------|--------------------------------------------------|------------|
|
|
50
|
+
| `instanceName` | Target instance from `database.toml` | `"main"` |
|
|
51
|
+
| `config` | Path to a `database.toml` config file | `null` |
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
await withConnection(async (client) => {
|
|
55
|
+
await client.query('SELECT 1');
|
|
56
|
+
}, { instanceName: 'analytics', config: 'path/to/database.toml' });
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Manual lifecycle
|
|
60
|
+
|
|
61
|
+
For cases where the callback form doesn't fit:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { start } from 'pg-ephemeral';
|
|
65
|
+
|
|
66
|
+
const server = await start();
|
|
67
|
+
// ... use server.url ...
|
|
68
|
+
await server.shutdown();
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Utilities
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
import { version, platformSupported, binaryPath } from 'pg-ephemeral';
|
|
75
|
+
|
|
76
|
+
version(); // => "0.2.0"
|
|
77
|
+
platformSupported(); // => true
|
|
78
|
+
binaryPath(); // => "/path/to/pg-ephemeral"
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Test Framework Integration
|
|
82
|
+
|
|
83
|
+
### Jest
|
|
84
|
+
|
|
85
|
+
Use `globalSetup`/`globalTeardown` to manage the container lifecycle and share
|
|
86
|
+
the URL via `process.env`:
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
// jest.globalSetup.ts
|
|
90
|
+
import { start } from 'pg-ephemeral';
|
|
91
|
+
|
|
92
|
+
export default async function globalSetup() {
|
|
93
|
+
const server = await start();
|
|
94
|
+
process.env.DATABASE_URL = server.url;
|
|
95
|
+
(globalThis as any).__pgEphemeralServer = server;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// jest.globalTeardown.ts
|
|
99
|
+
export default async function globalTeardown() {
|
|
100
|
+
await (globalThis as any).__pgEphemeralServer?.shutdown();
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Then connect via the environment variable in your tests:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
import { Client } from 'pg';
|
|
108
|
+
|
|
109
|
+
let client: Client;
|
|
110
|
+
|
|
111
|
+
beforeAll(async () => {
|
|
112
|
+
client = new Client({ connectionString: process.env.DATABASE_URL });
|
|
113
|
+
await client.connect();
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
afterAll(async () => {
|
|
117
|
+
await client.end();
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('inserts a user', async () => {
|
|
121
|
+
await client.query("INSERT INTO users (name) VALUES ('alice')");
|
|
122
|
+
const result = await client.query('SELECT name FROM users');
|
|
123
|
+
expect(result.rows[0].name).toBe('alice');
|
|
124
|
+
});
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
### Prisma
|
|
128
|
+
|
|
129
|
+
Use `globalSetup` to start the container and deploy migrations before tests run:
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
// jest.globalSetup.ts
|
|
133
|
+
import { start } from 'pg-ephemeral';
|
|
134
|
+
import { execSync } from 'node:child_process';
|
|
135
|
+
|
|
136
|
+
export default async function globalSetup() {
|
|
137
|
+
const server = await start();
|
|
138
|
+
process.env.DATABASE_URL = server.url;
|
|
139
|
+
execSync('npx prisma migrate deploy', { env: process.env });
|
|
140
|
+
(globalThis as any).__pgEphemeralServer = server;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// jest.globalTeardown.ts
|
|
144
|
+
export default async function globalTeardown() {
|
|
145
|
+
await (globalThis as any).__pgEphemeralServer?.shutdown();
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Then use `PrismaClient` in your tests as usual:
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
import { PrismaClient } from '@prisma/client';
|
|
153
|
+
|
|
154
|
+
const prisma = new PrismaClient();
|
|
155
|
+
|
|
156
|
+
afterAll(async () => {
|
|
157
|
+
await prisma.$disconnect();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it('creates a user', async () => {
|
|
161
|
+
const user = await prisma.user.create({ data: { name: 'alice' } });
|
|
162
|
+
expect(user.name).toBe('alice');
|
|
163
|
+
});
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
## Requirements
|
|
167
|
+
|
|
168
|
+
- Node.js >= 20
|
|
169
|
+
- Docker Engine 20.10+ / Docker Desktop 4.34+, or Podman 5.3+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg-ephemeral",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"description": "Provides ephemeral PostgreSQL instances for testing, wrapping the pg-ephemeral project binary",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/mbj/mrs/tree/main/pg-ephemeral",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"lib/"
|
|
20
20
|
],
|
|
21
21
|
"engines": {
|
|
22
|
-
"node": ">=
|
|
22
|
+
"node": ">=22.15.0"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"pg": "^8.0.0"
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"typescript": "^5.0.0"
|
|
31
31
|
},
|
|
32
32
|
"optionalDependencies": {
|
|
33
|
-
"@pg-ephemeral/darwin-arm64": "0.2.
|
|
34
|
-
"@pg-ephemeral/linux-arm64": "0.2.
|
|
35
|
-
"@pg-ephemeral/linux-x64": "0.2.
|
|
33
|
+
"@pg-ephemeral/darwin-arm64": "0.2.3",
|
|
34
|
+
"@pg-ephemeral/linux-arm64": "0.2.3",
|
|
35
|
+
"@pg-ephemeral/linux-x64": "0.2.3"
|
|
36
36
|
}
|
|
37
37
|
}
|