@a_jackie_z/fastify 1.0.0 → 1.1.0
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 +109 -72
- package/dist/index.d.ts +2 -2
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/package.json +3 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @a_jackie_z/fastify
|
|
2
2
|
|
|
3
|
-
A collection of Fastify plugins and utilities for building robust web applications with built-in support for JWT authentication, rate limiting, Swagger documentation, and
|
|
3
|
+
A collection of Fastify plugins and utilities for building robust web applications with built-in support for JWT authentication, rate limiting, Swagger documentation, and Zod validation.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -13,8 +13,8 @@ npm install @a_jackie_z/fastify
|
|
|
13
13
|
### Basic Setup
|
|
14
14
|
|
|
15
15
|
```typescript
|
|
16
|
-
import { createFastify } from '@a_jackie_z/fastify'
|
|
17
|
-
import {
|
|
16
|
+
import { createFastify, runFastify } from '@a_jackie_z/fastify'
|
|
17
|
+
import { z } from 'zod'
|
|
18
18
|
|
|
19
19
|
const app = await createFastify()
|
|
20
20
|
|
|
@@ -23,8 +23,8 @@ app.route({
|
|
|
23
23
|
url: '/hello',
|
|
24
24
|
schema: {
|
|
25
25
|
response: {
|
|
26
|
-
200:
|
|
27
|
-
message:
|
|
26
|
+
200: z.object({
|
|
27
|
+
message: z.string(),
|
|
28
28
|
}),
|
|
29
29
|
},
|
|
30
30
|
},
|
|
@@ -33,26 +33,31 @@ app.route({
|
|
|
33
33
|
},
|
|
34
34
|
})
|
|
35
35
|
|
|
36
|
-
await app.
|
|
36
|
+
await runFastify(app, '0.0.0.0', 3000)
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
## Features
|
|
40
40
|
|
|
41
41
|
- **JWT Authentication** - Built-in JWT support with global and route-level configuration
|
|
42
|
-
- **Rate Limiting** -
|
|
43
|
-
- **Swagger Documentation** - Auto-generated API documentation with
|
|
44
|
-
- **
|
|
45
|
-
- **Logger
|
|
42
|
+
- **Rate Limiting** - Global rate limiting for API protection
|
|
43
|
+
- **Swagger Documentation** - Auto-generated API documentation with Zod schemas
|
|
44
|
+
- **Zod Integration** - Type-safe request/response validation
|
|
45
|
+
- **Custom Logger Support** - Integrate any Fastify-compatible logger
|
|
46
|
+
- **Health Check Plugin** - Ready-to-use health check endpoint
|
|
47
|
+
- **Plugin Helper** - Utility for creating reusable Fastify plugins
|
|
46
48
|
|
|
47
49
|
## Examples
|
|
48
50
|
|
|
49
51
|
### 1. Complete Setup with All Features
|
|
50
52
|
|
|
51
53
|
```typescript
|
|
52
|
-
import { createFastify } from '@a_jackie_z/fastify'
|
|
53
|
-
import {
|
|
54
|
+
import { createFastify, runFastify } from '@a_jackie_z/fastify'
|
|
55
|
+
import { z } from 'zod'
|
|
54
56
|
|
|
55
57
|
const app = await createFastify({
|
|
58
|
+
// Optional: Integrate your logger
|
|
59
|
+
// logger: yourFastifyLogger,
|
|
60
|
+
|
|
56
61
|
// Rate limiting
|
|
57
62
|
rateLimit: {
|
|
58
63
|
global: {
|
|
@@ -77,7 +82,7 @@ const app = await createFastify({
|
|
|
77
82
|
},
|
|
78
83
|
})
|
|
79
84
|
|
|
80
|
-
await app.
|
|
85
|
+
await runFastify(app, '0.0.0.0', 3000)
|
|
81
86
|
```
|
|
82
87
|
|
|
83
88
|
### 2. Authentication Flow
|
|
@@ -92,16 +97,16 @@ app.route({
|
|
|
92
97
|
jwt: false, // Bypass JWT check for login
|
|
93
98
|
},
|
|
94
99
|
schema: {
|
|
95
|
-
body:
|
|
96
|
-
username:
|
|
97
|
-
password:
|
|
100
|
+
body: z.object({
|
|
101
|
+
username: z.string(),
|
|
102
|
+
password: z.string(),
|
|
98
103
|
}),
|
|
99
104
|
response: {
|
|
100
|
-
200:
|
|
101
|
-
token:
|
|
105
|
+
200: z.object({
|
|
106
|
+
token: z.string(),
|
|
102
107
|
}),
|
|
103
|
-
401:
|
|
104
|
-
error:
|
|
108
|
+
401: z.object({
|
|
109
|
+
error: z.string(),
|
|
105
110
|
}),
|
|
106
111
|
},
|
|
107
112
|
},
|
|
@@ -135,8 +140,8 @@ app.route({
|
|
|
135
140
|
},
|
|
136
141
|
schema: {
|
|
137
142
|
response: {
|
|
138
|
-
200:
|
|
139
|
-
message:
|
|
143
|
+
200: z.object({
|
|
144
|
+
message: z.string(),
|
|
140
145
|
}),
|
|
141
146
|
},
|
|
142
147
|
},
|
|
@@ -155,9 +160,9 @@ app.route({
|
|
|
155
160
|
// No config needed - global JWT setting applies
|
|
156
161
|
schema: {
|
|
157
162
|
response: {
|
|
158
|
-
200:
|
|
159
|
-
message:
|
|
160
|
-
user:
|
|
163
|
+
200: z.object({
|
|
164
|
+
message: z.string(),
|
|
165
|
+
user: z.unknown(),
|
|
161
166
|
}),
|
|
162
167
|
},
|
|
163
168
|
},
|
|
@@ -186,12 +191,12 @@ app.route({
|
|
|
186
191
|
},
|
|
187
192
|
schema: {
|
|
188
193
|
response: {
|
|
189
|
-
200:
|
|
190
|
-
message:
|
|
194
|
+
200: z.object({
|
|
195
|
+
message: z.string(),
|
|
191
196
|
}),
|
|
192
|
-
403:
|
|
193
|
-
error:
|
|
194
|
-
message:
|
|
197
|
+
403: z.object({
|
|
198
|
+
error: z.string(),
|
|
199
|
+
message: z.string(),
|
|
195
200
|
}),
|
|
196
201
|
},
|
|
197
202
|
},
|
|
@@ -216,12 +221,12 @@ app.route({
|
|
|
216
221
|
},
|
|
217
222
|
},
|
|
218
223
|
schema: {
|
|
219
|
-
params:
|
|
220
|
-
id:
|
|
224
|
+
params: z.object({
|
|
225
|
+
id: z.string(),
|
|
221
226
|
}),
|
|
222
227
|
response: {
|
|
223
|
-
200:
|
|
224
|
-
message:
|
|
228
|
+
200: z.object({
|
|
229
|
+
message: z.string(),
|
|
225
230
|
}),
|
|
226
231
|
},
|
|
227
232
|
},
|
|
@@ -259,61 +264,71 @@ app.route({
|
|
|
259
264
|
})
|
|
260
265
|
```
|
|
261
266
|
|
|
262
|
-
### 6.
|
|
263
|
-
|
|
264
|
-
#### Route-Specific Rate Limit
|
|
267
|
+
### 6. Health Check Plugin
|
|
265
268
|
|
|
266
269
|
```typescript
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
},
|
|
279
|
-
})
|
|
270
|
+
import { createFastify, runFastify, healthPlugin } from '@a_jackie_z/fastify'
|
|
271
|
+
|
|
272
|
+
const app = await createFastify()
|
|
273
|
+
|
|
274
|
+
// Register health check plugin
|
|
275
|
+
await app.register(healthPlugin)
|
|
276
|
+
|
|
277
|
+
// Health endpoint available at: GET /v1/health
|
|
278
|
+
// Response: { status: 200, message: 'ok' }
|
|
279
|
+
|
|
280
|
+
await runFastify(app, '0.0.0.0', 3000)
|
|
280
281
|
```
|
|
281
282
|
|
|
282
|
-
|
|
283
|
+
### 7. Creating Custom Plugins
|
|
283
284
|
|
|
284
285
|
```typescript
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
286
|
+
import { createFastify, runFastify, createFastifyPlugin } from '@a_jackie_z/fastify'
|
|
287
|
+
import { z } from 'zod'
|
|
288
|
+
|
|
289
|
+
// Create a reusable plugin
|
|
290
|
+
const myPlugin = createFastifyPlugin((app) => {
|
|
291
|
+
app.get('/plugin-route', {
|
|
292
|
+
schema: {
|
|
293
|
+
response: {
|
|
294
|
+
200: z.object({
|
|
295
|
+
message: z.string(),
|
|
296
|
+
}),
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
handler: async () => {
|
|
300
|
+
return { message: 'From plugin' }
|
|
301
|
+
},
|
|
302
|
+
})
|
|
294
303
|
})
|
|
304
|
+
|
|
305
|
+
// Use the plugin
|
|
306
|
+
const app = await createFastify()
|
|
307
|
+
await app.register(myPlugin)
|
|
308
|
+
|
|
309
|
+
await runFastify(app, '0.0.0.0', 3000)
|
|
295
310
|
```
|
|
296
311
|
|
|
297
|
-
###
|
|
312
|
+
### 8. Zod Schema Validation
|
|
298
313
|
|
|
299
314
|
```typescript
|
|
300
315
|
app.route({
|
|
301
316
|
method: 'POST',
|
|
302
317
|
url: '/users',
|
|
303
318
|
schema: {
|
|
304
|
-
body:
|
|
305
|
-
name:
|
|
306
|
-
email:
|
|
307
|
-
age:
|
|
319
|
+
body: z.object({
|
|
320
|
+
name: z.string().min(1).max(100),
|
|
321
|
+
email: z.string().email(),
|
|
322
|
+
age: z.number().min(0).max(150).optional(),
|
|
308
323
|
}),
|
|
309
324
|
response: {
|
|
310
|
-
201:
|
|
311
|
-
id:
|
|
312
|
-
name:
|
|
313
|
-
email:
|
|
325
|
+
201: z.object({
|
|
326
|
+
id: z.string(),
|
|
327
|
+
name: z.string(),
|
|
328
|
+
email: z.string(),
|
|
314
329
|
}),
|
|
315
|
-
400:
|
|
316
|
-
error:
|
|
330
|
+
400: z.object({
|
|
331
|
+
error: z.string(),
|
|
317
332
|
}),
|
|
318
333
|
},
|
|
319
334
|
},
|
|
@@ -334,6 +349,7 @@ app.route({
|
|
|
334
349
|
|
|
335
350
|
```typescript
|
|
336
351
|
interface CreateFastifyOptions {
|
|
352
|
+
logger?: FastifyServerOptions['loggerInstance'],
|
|
337
353
|
rateLimit?: {
|
|
338
354
|
global?: RateLimitPluginOptions
|
|
339
355
|
}
|
|
@@ -347,7 +363,7 @@ interface CreateFastifyOptions {
|
|
|
347
363
|
title: string
|
|
348
364
|
version: string
|
|
349
365
|
description: string
|
|
350
|
-
routePrefix?: string // Default: '/
|
|
366
|
+
routePrefix?: string // Default: '/docs/'
|
|
351
367
|
}
|
|
352
368
|
}
|
|
353
369
|
```
|
|
@@ -371,6 +387,27 @@ type JWTAuthorizationHandler = (
|
|
|
371
387
|
) => Promise<boolean> | boolean
|
|
372
388
|
```
|
|
373
389
|
|
|
390
|
+
## API Reference
|
|
391
|
+
|
|
392
|
+
### `createFastify(options?: CreateFastifyOptions): Promise<FastifyServer>`
|
|
393
|
+
|
|
394
|
+
Creates and configures a Fastify server instance with Zod support and optional plugins.
|
|
395
|
+
|
|
396
|
+
### `runFastify(fastify: FastifyServer, host: string, port: number): Promise<void>`
|
|
397
|
+
|
|
398
|
+
Starts the Fastify server. Handles errors and exits the process if the server fails to start.
|
|
399
|
+
|
|
400
|
+
**Parameters:**
|
|
401
|
+
- `fastify` - The Fastify server instance
|
|
402
|
+
- `host` - The host to bind to (e.g., '0.0.0.0' or 'localhost')
|
|
403
|
+
- `port` - The port number to listen on
|
|
404
|
+
|
|
405
|
+
**Example:**
|
|
406
|
+
```typescript
|
|
407
|
+
const app = await createFastify()
|
|
408
|
+
await runFastify(app, '0.0.0.0', 3000)
|
|
409
|
+
```
|
|
410
|
+
|
|
374
411
|
## Usage Patterns
|
|
375
412
|
|
|
376
413
|
### Pattern 1: Global JWT with Selective Public Routes
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fastify from 'fastify';
|
|
2
2
|
import { FastifyRequest, FastifyReply, FastifyServerOptions, FastifyInstance, RawServerDefault, FastifyBaseLogger, FastifyContextConfig, FastifyPluginCallback } from 'fastify';
|
|
3
|
-
import {
|
|
3
|
+
import { ZodTypeProvider } from 'fastify-type-provider-zod';
|
|
4
4
|
import { RateLimitPluginOptions } from '@fastify/rate-limit';
|
|
5
5
|
import { FastifyJWTOptions } from '@fastify/jwt';
|
|
6
6
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
@@ -38,7 +38,7 @@ interface CreateFastifyOptions {
|
|
|
38
38
|
routePrefix?: string;
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
type FastifyServer = FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse, FastifyBaseLogger,
|
|
41
|
+
type FastifyServer = FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse, FastifyBaseLogger, ZodTypeProvider> & FastifyContextConfig;
|
|
42
42
|
declare function createFastify(options?: CreateFastifyOptions): Promise<FastifyServer>;
|
|
43
43
|
declare function runFastify(fastify: FastifyServer, host: string, port: number): Promise<void>;
|
|
44
44
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// lib/fastify.ts
|
|
2
2
|
import Fastify from "fastify";
|
|
3
|
+
import {
|
|
4
|
+
serializerCompiler,
|
|
5
|
+
validatorCompiler
|
|
6
|
+
} from "fastify-type-provider-zod";
|
|
3
7
|
import fastifyRateLimit from "@fastify/rate-limit";
|
|
4
8
|
import fastifyJwt from "@fastify/jwt";
|
|
5
9
|
import fastifySwagger from "@fastify/swagger";
|
|
@@ -10,6 +14,8 @@ async function createFastify(options) {
|
|
|
10
14
|
fastifyOptions.loggerInstance = options.logger;
|
|
11
15
|
}
|
|
12
16
|
const fastify = Fastify(fastifyOptions).withTypeProvider();
|
|
17
|
+
fastify.setValidatorCompiler(validatorCompiler);
|
|
18
|
+
fastify.setSerializerCompiler(serializerCompiler);
|
|
13
19
|
if (options?.swagger) {
|
|
14
20
|
await fastify.register(fastifySwagger, {
|
|
15
21
|
openapi: {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../lib/fastify.ts","../lib/plugin.ts","../lib/plugins/healthPlugin.ts"],"sourcesContent":["import Fastify, {\n FastifyBaseLogger,\n FastifyContextConfig,\n FastifyInstance,\n FastifyReply,\n FastifyServerOptions,\n RawServerDefault,\n} from 'fastify'\nimport type { FastifyRequest } from 'fastify'\nimport {
|
|
1
|
+
{"version":3,"sources":["../lib/fastify.ts","../lib/plugin.ts","../lib/plugins/healthPlugin.ts"],"sourcesContent":["import Fastify, {\n FastifyBaseLogger,\n FastifyContextConfig,\n FastifyInstance,\n FastifyReply,\n FastifyServerOptions,\n RawServerDefault,\n} from 'fastify'\nimport type { FastifyRequest } from 'fastify'\nimport {\n serializerCompiler,\n validatorCompiler,\n ZodTypeProvider,\n} from 'fastify-type-provider-zod'\nimport fastifyRateLimit, { RateLimitPluginOptions } from '@fastify/rate-limit'\nimport fastifyJwt, { FastifyJWTOptions } from '@fastify/jwt'\nimport fastifySwagger, { SwaggerOptions } from '@fastify/swagger'\nimport fastifySwaggerUI, { FastifySwaggerUiOptions } from '@fastify/swagger-ui'\nimport { IncomingMessage, ServerResponse } from 'node:http'\n\nexport type JWTAuthorizationHandler = <TUser = unknown>(\n request: FastifyRequest,\n reply: FastifyReply,\n user: TUser\n) => Promise<boolean> | boolean\n\nexport interface JWTRouteConfig {\n jwt?:\n | boolean // true = require JWT, false = bypass JWT\n | {\n required?: boolean // Default: true if global enabled\n authorize?: JWTAuthorizationHandler // Check JWT info before route processing\n }\n}\n\n// Extend Fastify types to include custom config\ndeclare module 'fastify' {\n interface FastifyContextConfig {\n jwt?:\n | boolean\n | {\n required?: boolean\n authorize?: JWTAuthorizationHandler\n }\n }\n}\n\nexport interface CreateFastifyOptions {\n logger?: FastifyServerOptions['loggerInstance'],\n rateLimit?: {\n global?: RateLimitPluginOptions\n }\n jwt?: {\n secret: string\n sign?: FastifyJWTOptions['sign']\n verify?: FastifyJWTOptions['verify']\n global?: boolean // Enable JWT check globally for all routes\n }\n swagger?: {\n title: string\n version: string\n description: string\n routePrefix?: string\n }\n}\n\nexport type FastifyServer = FastifyInstance<\n RawServerDefault,\n IncomingMessage,\n ServerResponse,\n FastifyBaseLogger,\n ZodTypeProvider\n> & FastifyContextConfig\n\nexport async function createFastify(options?: CreateFastifyOptions): Promise<FastifyServer> {\n const fastifyOptions: FastifyServerOptions = {}\n\n if (options?.logger) {\n fastifyOptions.loggerInstance = options.logger\n }\n\n const fastify = Fastify(fastifyOptions).withTypeProvider<ZodTypeProvider>()\n\n // Set up Zod validation and serialization\n fastify.setValidatorCompiler(validatorCompiler)\n fastify.setSerializerCompiler(serializerCompiler)\n\n // Register Swagger first to capture all routes with Zod schemas\n if (options?.swagger) {\n await fastify.register(fastifySwagger, {\n openapi: {\n info: {\n title: options.swagger.title,\n version: options.swagger.version,\n description: options.swagger.description,\n },\n },\n } as SwaggerOptions)\n\n let routePrefix = options.swagger.routePrefix || '/docs/'\n\n if (!routePrefix.startsWith('/')) {\n routePrefix = '/' + routePrefix\n }\n\n if (!routePrefix.endsWith('/')) {\n routePrefix = routePrefix + '/'\n }\n\n await fastify.register(fastifySwaggerUI, { routePrefix } as FastifySwaggerUiOptions)\n }\n\n // Register JWT authentication\n if (options?.jwt) {\n const jwtOptions: FastifyJWTOptions = {\n secret: options.jwt.secret,\n }\n if (options.jwt.sign !== undefined) {\n jwtOptions.sign = options.jwt.sign\n }\n if (options.jwt.verify !== undefined) {\n jwtOptions.verify = options.jwt.verify\n }\n await fastify.register(fastifyJwt, jwtOptions)\n\n // Global JWT checking hook\n if (options.jwt.global) {\n fastify.addHook('onRequest', async (request, reply) => {\n const routeConfig = (request.routeOptions.config as JWTRouteConfig) || {}\n const jwtConfig = routeConfig.jwt\n\n // Check if route explicitly bypasses JWT\n if (jwtConfig === false) {\n return\n }\n\n // Check if route explicitly requires JWT or uses global setting\n const shouldVerify =\n jwtConfig === true ||\n (typeof jwtConfig === 'object' && jwtConfig.required !== false) ||\n (jwtConfig === undefined && options?.jwt?.global === true)\n\n if (shouldVerify) {\n try {\n await request.jwtVerify()\n\n // Custom authorization - check JWT info before route processing\n if (typeof jwtConfig === 'object' && jwtConfig.authorize) {\n const authorized = await jwtConfig.authorize(request, reply, request.user)\n if (!authorized) {\n reply.status(403).send({\n error: 'Forbidden',\n message: 'Authorization failed',\n })\n return\n }\n }\n } catch (err) {\n reply.status(401).send({\n error: 'Unauthorized',\n message: 'Invalid or missing JWT token',\n })\n }\n }\n })\n }\n }\n\n // Register Rate Limiting\n if (options?.rateLimit?.global) {\n await fastify.register(fastifyRateLimit, {\n global: true,\n ...options.rateLimit.global,\n })\n }\n\n return fastify\n}\n\nexport async function runFastify(fastify: FastifyServer, host: string, port: number) {\n try {\n await fastify.listen({ host, port })\n } catch (err) {\n fastify.log.error(err)\n process.exit(1)\n }\n}\n","import { FastifyPluginCallback } from 'fastify'\n\nexport function createFastifyPlugin(cb: FastifyPluginCallback) {\n return cb;\n}\n","import { createFastifyPlugin } from '../plugin.ts'\n\nexport const healthPlugin = createFastifyPlugin((app) => {\n app.get('/v1/health', {\n schema: {\n tags: ['health'],\n },\n handler: async () => {\n return {\n status: 200,\n message: 'ok',\n }\n },\n })\n})\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@a_jackie_z/fastify",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A collection of Fastify plugins and utilities for building robust web applications.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Sang Lu <connect.with.sang@gmail.com>",
|
|
@@ -24,10 +24,9 @@
|
|
|
24
24
|
"@fastify/rate-limit": "^10.3.0",
|
|
25
25
|
"@fastify/swagger": "^9.6.1",
|
|
26
26
|
"@fastify/swagger-ui": "^5.2.4",
|
|
27
|
-
"@fastify/type-provider-typebox": "^6.1.0",
|
|
28
|
-
"@sinclair/typebox": "^0.34.47",
|
|
29
27
|
"fastify": "^5.7.1",
|
|
30
|
-
"
|
|
28
|
+
"fastify-type-provider-zod": "^6.1.0",
|
|
29
|
+
"zod": "^4.3.5"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
32
|
"@types/node": "^25.0.9",
|