Skip to content

Commit 5d49ea5

Browse files
authored
Types: Add "pg" property to FastifyInstance (#68)
* Types: Add "pg" property to FastifyInstance As recommended in the guide for creating TypeScript compatible Fastify plugins, properties that the Fastify instances are decorated with should also in the types get added to those instances: https://www.fastify.io/docs/latest/TypeScript/#creating-a-typescript-fastify-plugin This change follows up on #63 by adding that. * Document "name" option * Enable use of non-docker postgres db in tests * Fix tests when no error is thrown * Throw if named and unnamed are combined * Clarify that intention is to manually add type
1 parent 3a38892 commit 5d49ea5

File tree

6 files changed

+138
-50
lines changed

6 files changed

+138
-50
lines changed

README.md

+54-1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,33 @@ fastify.listen(3000, err => {
147147

148148
As you can see there is no need to close the client, since is done internally. Promises and async await are supported as well.
149149

150+
### Name option
151+
If you need to have multiple databases set up, then you can name each one of them by passing `name: 'foo'`. It will then be accessible as `fastify.pg.foo` instead of `fastify.pg`.
152+
You can't use both named and an unnamed postgres conenction at once.
153+
154+
```js
155+
const fastify = require('fastify')()
156+
157+
fastify.register(require('fastify-postgres'), {
158+
connectionString: 'postgres://postgres@localhost/postgres',
159+
name: 'foo'
160+
})
161+
162+
fastify.get('/user/:id', (req, reply) => {
163+
fastify.pg.foo.query(
164+
'SELECT id, username, hash, salt FROM users WHERE id=$1', [req.params.id],
165+
function onResult (err, result) {
166+
reply.send(err || result)
167+
}
168+
)
169+
})
170+
171+
fastify.listen(3000, err => {
172+
if (err) throw err
173+
console.log(`server listening on ${fastify.server.address().port}`)
174+
})
175+
```
176+
150177
### Native option
151178
If you want to gain the maximum performances you can install [pg-native](https://github.com/brianc/node-pg-native), and pass `native: true` to the plugin options.
152179
*Note: it requires PostgreSQL client libraries & tools installed, see [instructions](https://github.com/brianc/node-pg-native#install).*
@@ -211,10 +238,24 @@ Install the compiler and typings for pg module:
211238
npm install --save-dev typescript @types/pg
212239
```
213240

214-
You can find examples in the [examples/typescript](./examples/typescript) directory.
241+
Add the `pg` property to `FastifyInstance`. Like this if you use an unnamed instance:
242+
243+
```typescript
244+
import type { PostgresDb } from 'fastify-postgres';
245+
246+
declare module 'fastify' {
247+
export interface FastifyInstance {
248+
pg: PostgresDb;
249+
}
250+
}
251+
```
252+
253+
More examples in the [examples/typescript](./examples/typescript) directory.
215254

216255
## Development and Testing
217256

257+
### Docker approach
258+
218259
First, start postgres with:
219260

220261
```
@@ -234,6 +275,18 @@ CREATE TABLE
234275
$ npm test
235276
```
236277

278+
### Custom Postgres approach
279+
280+
1. Set up a database of your choice oin a postgres server of your choice
281+
2. Create the required table using
282+
```sql
283+
CREATE TABLE users(id serial PRIMARY KEY, username VARCHAR (50) NOT NULL);
284+
```
285+
3. Specify a connection string to it in a `DATABASE_TEST_URL` environment variable when you run the tests
286+
```bash
287+
DATABASE_TEST_URL="postgres://username:password@localhost/something_thats_a_test_database" npm test
288+
```
289+
237290
## Acknowledgements
238291

239292
This project is kindly sponsored by:

index.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ function fastifyPostgres (fastify, options, next) {
8585
if (name) {
8686
if (!fastify.pg) {
8787
fastify.decorate('pg', {})
88-
}
89-
90-
if (fastify.pg[name]) {
88+
} else if (fastify.pg.pool instanceof pg.Pool) {
89+
return next(new Error('fastify-postgres already has an unnamed instance registered'))
90+
} else if (fastify.pg[name]) {
9191
return next(new Error(`fastify-postgres '${name}' instance name has already been registered`))
9292
}
9393

test/helpers.js

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
'use strict'
2+
3+
const BAD_DB_NAME = 'db_that_does_not_exist'
4+
const connectionString = process.env.DATABASE_TEST_URL || 'postgres://postgres:postgres@localhost/postgres'
5+
const connectionStringBadDbName = connectionString.replace(/\/[^/]+$/, '/' + BAD_DB_NAME)
6+
7+
module.exports = Object.freeze({
8+
BAD_DB_NAME,
9+
connectionString,
10+
connectionStringBadDbName
11+
})

test/initialization.test.js

+35-13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const t = require('tap')
44
const test = t.test
55
const Fastify = require('fastify')
66
const fastifyPostgres = require('../index')
7+
const { connectionString } = require('./helpers')
78

89
test('Should be able to use native module', (t) => {
910
t.plan(2)
@@ -12,7 +13,7 @@ test('Should be able to use native module', (t) => {
1213
t.teardown(() => fastify.close())
1314

1415
fastify.register(fastifyPostgres, {
15-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
16+
connectionString,
1617
native: true
1718
})
1819

@@ -38,7 +39,7 @@ test('Should be able to use an alternative pg module', (t) => {
3839
t.teardown(() => fastify.close())
3940

4041
fastify.register(fastifyPostgres, {
41-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
42+
connectionString,
4243
pg: altPg
4344
})
4445

@@ -64,20 +65,20 @@ test('Should not throw if registered within different scopes (with and without n
6465

6566
fastify.register(function scopeOne (instance, opts, next) {
6667
instance.register(fastifyPostgres, {
67-
connectionString: 'postgres://postgres:postgres@localhost/postgres'
68+
connectionString
6869
})
6970

7071
next()
7172
})
7273

7374
fastify.register(function scopeTwo (instance, opts, next) {
7475
instance.register(fastifyPostgres, {
75-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
76+
connectionString,
7677
name: 'one'
7778
})
7879

7980
instance.register(fastifyPostgres, {
80-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
81+
connectionString,
8182
name: 'two'
8283
})
8384

@@ -96,16 +97,37 @@ test('Should throw when trying to register multiple instances without giving a n
9697
t.teardown(() => fastify.close())
9798

9899
fastify.register(fastifyPostgres, {
99-
connectionString: 'postgres://postgres:postgres@localhost/postgres'
100+
connectionString
100101
})
101102

102103
fastify.register(fastifyPostgres, {
103-
connectionString: 'postgres://postgres:postgres@localhost/postgres'
104+
connectionString
104105
})
105106

106107
fastify.ready((err) => {
107108
t.ok(err)
108-
t.is(err.message, 'fastify-postgres has already been registered')
109+
t.is((err || {}).message, 'fastify-postgres has already been registered')
110+
})
111+
})
112+
113+
test('Should throw when trying to register a named instance after an unnamed', (t) => {
114+
t.plan(2)
115+
116+
const fastify = Fastify()
117+
t.teardown(() => fastify.close())
118+
119+
fastify.register(fastifyPostgres, {
120+
connectionString
121+
})
122+
123+
fastify.register(fastifyPostgres, {
124+
connectionString,
125+
name: 'two'
126+
})
127+
128+
fastify.ready((err) => {
129+
t.ok(err)
130+
t.is((err || {}).message, 'fastify-postgres already has an unnamed instance registered')
109131
})
110132
})
111133

@@ -118,17 +140,17 @@ test('Should throw when trying to register duplicate connection names', (t) => {
118140

119141
fastify
120142
.register(fastifyPostgres, {
121-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
143+
connectionString,
122144
name
123145
})
124146
fastify.register(fastifyPostgres, {
125-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
147+
connectionString,
126148
name
127149
})
128150

129151
fastify.ready((err) => {
130152
t.ok(err)
131-
t.is(err.message, `fastify-postgres '${name}' instance name has already been registered`)
153+
t.is((err || {}).message, `fastify-postgres '${name}' instance name has already been registered`)
132154
})
133155
})
134156

@@ -139,7 +161,7 @@ test('fastify.pg namespace should exist', (t) => {
139161
t.teardown(() => fastify.close())
140162

141163
fastify.register(fastifyPostgres, {
142-
connectionString: 'postgres://postgres:postgres@localhost/postgres'
164+
connectionString
143165
})
144166

145167
fastify.ready((err) => {
@@ -159,7 +181,7 @@ test('fastify.pg.test namespace should exist', (t) => {
159181
t.teardown(() => fastify.close())
160182

161183
fastify.register(fastifyPostgres, {
162-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
184+
connectionString,
163185
name: 'test'
164186
})
165187

test/query.test.js

+18-19
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ const t = require('tap')
44
const test = t.test
55
const Fastify = require('fastify')
66
const fastifyPostgres = require('../index')
7+
const {
8+
BAD_DB_NAME,
9+
connectionString,
10+
connectionStringBadDbName
11+
} = require('./helpers')
712

813
test('When fastify.pg root namespace is used:', (t) => {
914
t.test('Should be able to connect and perform a query with a callback', (t) => {
@@ -13,7 +18,7 @@ test('When fastify.pg root namespace is used:', (t) => {
1318
t.teardown(() => fastify.close())
1419

1520
fastify.register(fastifyPostgres, {
16-
connectionString: 'postgres://postgres:postgres@localhost/postgres'
21+
connectionString
1722
})
1823

1924
fastify.ready((err) => {
@@ -40,7 +45,7 @@ test('When fastify.pg root namespace is used:', (t) => {
4045
t.teardown(() => fastify.close())
4146

4247
fastify.register(fastifyPostgres, {
43-
connectionString: 'postgres://postgres:postgres@localhost/postgres'
48+
connectionString
4449
})
4550

4651
fastify.ready((err) => {
@@ -60,7 +65,7 @@ test('When fastify.pg root namespace is used:', (t) => {
6065
t.teardown(() => fastify.close())
6166

6267
fastify.register(fastifyPostgres, {
63-
connectionString: 'postgres://postgres:postgres@localhost/postgres'
68+
connectionString
6469
})
6570

6671
fastify.ready((err) => {
@@ -85,10 +90,8 @@ test('When fastify.pg root namespace is used:', (t) => {
8590
const fastify = Fastify()
8691
t.teardown(() => fastify.close())
8792

88-
const DB_NAME = 'database_that_do_not_exist'
89-
9093
fastify.register(fastifyPostgres, {
91-
connectionString: `postgres://postgres:postgres@localhost/${DB_NAME}`
94+
connectionString: connectionStringBadDbName
9295
})
9396

9497
fastify.ready((err) => {
@@ -97,7 +100,7 @@ test('When fastify.pg root namespace is used:', (t) => {
97100
fastify.pg.query('SELECT NOW()', (err, result) => {
98101
t.is(result, undefined)
99102
t.ok(err)
100-
t.is(err.message, `database "${DB_NAME}" does not exist`)
103+
t.is(err.message, `database "${BAD_DB_NAME}" does not exist`)
101104
})
102105
})
103106
}
@@ -109,10 +112,8 @@ test('When fastify.pg root namespace is used:', (t) => {
109112
const fastify = Fastify()
110113
t.teardown(() => fastify.close())
111114

112-
const DB_NAME = 'database_that_do_not_exist'
113-
114115
fastify.register(fastifyPostgres, {
115-
connectionString: `postgres://postgres:postgres@localhost/${DB_NAME}`
116+
connectionString: connectionStringBadDbName
116117
})
117118

118119
fastify.ready((err) => {
@@ -125,7 +126,7 @@ test('When fastify.pg root namespace is used:', (t) => {
125126
})
126127
.catch((err) => {
127128
t.ok(err)
128-
t.is(err.message, `database "${DB_NAME}" does not exist`)
129+
t.is(err.message, `database "${BAD_DB_NAME}" does not exist`)
129130
})
130131
})
131132
})
@@ -141,7 +142,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
141142
t.teardown(() => fastify.close())
142143

143144
fastify.register(fastifyPostgres, {
144-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
145+
connectionString,
145146
name: 'test'
146147
})
147148

@@ -167,7 +168,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
167168
t.teardown(() => fastify.close())
168169

169170
fastify.register(fastifyPostgres, {
170-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
171+
connectionString,
171172
name: 'test'
172173
})
173174

@@ -187,7 +188,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
187188
t.teardown(() => fastify.close())
188189

189190
fastify.register(fastifyPostgres, {
190-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
191+
connectionString,
191192
name: 'test'
192193
})
193194

@@ -212,7 +213,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
212213
t.teardown(() => fastify.close())
213214

214215
fastify.register(fastifyPostgres, {
215-
connectionString: 'postgres://postgres:postgres@localhost/postgres',
216+
connectionString,
216217
name: 'test',
217218
native: true
218219
})
@@ -237,10 +238,8 @@ test('When fastify.pg.test namespace is used:', (t) => {
237238
const fastify = Fastify()
238239
t.teardown(() => fastify.close())
239240

240-
const DB_NAME = 'database_that_do_not_exist'
241-
242241
fastify.register(fastifyPostgres, {
243-
connectionString: `postgres://postgres:postgres@localhost/${DB_NAME}`,
242+
connectionString: connectionStringBadDbName,
244243
name: 'test'
245244
})
246245

@@ -254,7 +253,7 @@ test('When fastify.pg.test namespace is used:', (t) => {
254253
})
255254
.catch((err) => {
256255
t.ok(err)
257-
t.is(err.message, `database "${DB_NAME}" does not exist`)
256+
t.is(err.message, `database "${BAD_DB_NAME}" does not exist`)
258257
})
259258
})
260259
})

0 commit comments

Comments
 (0)