@gasket/plugin-fastify 7.0.0-next.4 → 7.0.0-next.41

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 CHANGED
@@ -34,7 +34,6 @@ All the configurations for the plugin are added under `fastify` in the config:
34
34
 
35
35
  - `compression`: true by default. Can be set to false if applying compression
36
36
  differently.
37
- - `excludedRoutesRegex`: Routes to be excluded based on a regex
38
37
  - `trustProxy`: Enable trust proxy option, [see Fastify documentation for possible values](https://fastify.dev/docs/latest/Reference/Server/#trustproxy)
39
38
 
40
39
  #### Example configuration
@@ -46,61 +45,15 @@ module.exports = {
46
45
  },
47
46
  fastify: {
48
47
  compression: false,
48
+ routes: 'api/*.js',
49
49
  excludedRoutesRegex: /^(?!\/_next\/)/,
50
50
  trustProxy: true
51
51
  }
52
52
  }
53
53
  ```
54
54
 
55
- ### Middleware paths
56
-
57
- The `gasket.config.js` can contain a `middleware` property, which is an array of
58
- objects that map plugins to route or path patterns, allowing apps to tune which
59
- middleware are triggered for which requests.
60
-
61
- ```js
62
- middleware: [
63
- {
64
- plugin:'gasket-plugin-example', // Name of the Gasket plugin
65
- paths: ['/api']
66
- },
67
- {
68
- plugin:'@some/gasket-plugin-example',
69
- paths: [/\/default/]
70
- },
71
- {
72
- plugin: '@another/gasket-plugin-example',
73
- paths: ['/proxy', /\/home/]
74
- }
75
- ]
76
- ```
77
-
78
55
  ## Lifecycles
79
56
 
80
- ### middleware
81
-
82
- Executed when the `fastify` server has been created, it will apply all returned
83
- functions as middleware.
84
-
85
- ```js
86
- module.exports = {
87
- hooks: {
88
- /**
89
- * Add Fastify middleware
90
- *
91
- * @param {Gasket} gasket The Gasket API
92
- * @param {Fastify} app - Fastify app instance
93
- * @returns {function|function[]} middleware(s)
94
- */
95
- middleware: function (gasket, app) {
96
- return require('x-xss-protection')();
97
- }
98
- }
99
- }
100
- ```
101
-
102
- You may also return an `Array` to inject more than one middleware.
103
-
104
57
  ### fastify
105
58
 
106
59
  Executed **after** the `middleware` event for when you need full control over
@@ -0,0 +1,47 @@
1
+ /// <reference types="@gasket/plugin-https" />
2
+ /// <reference types="@gasket/plugin-logger" />
3
+
4
+ /**
5
+ * Create the Fastify instance and setup the lifecycle hooks.
6
+ * Fastify is compatible with express middleware out of the box, so we can
7
+ * use the same middleware lifecycles.
8
+ * @type {import('@gasket/core').HookHandler<'createServers'>}
9
+ */
10
+ // eslint-disable-next-line max-statements
11
+ module.exports = async function createServers(gasket, serverOpts) {
12
+ const fastify = require('fastify');
13
+ const { config, logger } = gasket;
14
+ const {
15
+ fastify: {
16
+ routes,
17
+ trustProxy = false
18
+ } = {},
19
+ http2
20
+ } = config;
21
+
22
+ // @ts-ignore
23
+ const app = fastify({ logger, trustProxy, http2 });
24
+
25
+ // allow consuming apps to directly append options to their server
26
+ await gasket.exec('fastify', app);
27
+
28
+ if (routes) {
29
+ for (const route of routes) {
30
+ if (typeof route !== 'function') {
31
+ throw new Error('Route must be a function');
32
+ }
33
+ await route(app);
34
+ }
35
+ }
36
+
37
+ const postRenderingStacks = (await gasket.exec('errorMiddleware')).filter(Boolean);
38
+ postRenderingStacks.forEach((stack) => app.use(stack));
39
+
40
+ return {
41
+ ...serverOpts,
42
+ handler: async function handler(...args) {
43
+ await app.ready();
44
+ app.server.emit('request', ...args);
45
+ }
46
+ };
47
+ };
package/lib/create.js ADDED
@@ -0,0 +1,34 @@
1
+ /// <reference types="@gasket/core" />
2
+
3
+ const { name, version, devDependencies } = require('../package.json');
4
+
5
+ /**
6
+ * Add files & extend package.json for new apps.
7
+ * @type {import('@gasket/core').HookHandler<'create'>}
8
+ */
9
+ module.exports = async function create(gasket, context) {
10
+ const generatorDir = `${__dirname}/../generator`;
11
+
12
+ context.gasketConfig.addPlugin('pluginFastify', name);
13
+
14
+ context.pkg.add('dependencies', {
15
+ [name]: `^${version}`,
16
+ fastify: devDependencies.fastify
17
+ });
18
+
19
+ if ('apiApp' in context && context.apiApp) {
20
+ context.gasketConfig.add('fastify', {
21
+ routes: []
22
+ });
23
+
24
+ if ('typescript' in context && context.typescript) {
25
+ context.files.add(`${generatorDir}/**/!(*.js)`);
26
+ } else {
27
+ context.files.add(`${generatorDir}/**/!(*.ts)`);
28
+ }
29
+
30
+ context.gasketConfig
31
+ .addImport('{ routes }', './routes/index.js')
32
+ .injectValue('fastify.routes', 'routes');
33
+ }
34
+ };
package/lib/index.d.ts CHANGED
@@ -1,18 +1,43 @@
1
- import type { MaybeAsync, MaybeMultiple } from '@gasket/engine';
2
- import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
1
+ import type { MaybeAsync, MaybeMultiple } from '@gasket/core';
2
+ import type {
3
+ FastifyInstance,
4
+ FastifyRequest,
5
+ FastifyReply,
6
+ FastifyServerOptions
7
+ } from 'fastify';
3
8
 
4
- declare module '@gasket/engine' {
9
+ export type AppRoutes = Array<MaybeAsync<(app: FastifyInstance) => void>>;
10
+
11
+ declare module '@gasket/core' {
5
12
  export interface GasketConfig {
6
- compression?: boolean,
7
- excludedRoutesRegex?: RegExp
13
+ fastify?: {
14
+ /** Enable compression */
15
+ compression?: boolean;
16
+ /** Filter for which request URLs invoke Gasket middleware */
17
+ middlewareInclusionRegex?: RegExp;
18
+ /** @deprecated */
19
+ excludedRoutesRegex?: RegExp;
20
+ /** Trust proxy configuration */
21
+ trustProxy?: FastifyServerOptions['trustProxy'];
22
+ /** Glob pattern for source files setting up fastify routes */
23
+ routes?: Array<MaybeAsync<(app: FastifyInstance) => void>>;
24
+ };
25
+ /** Middleware configuration */
26
+ middleware?: {
27
+ /** Plugin name */
28
+ plugin: string;
29
+ /** Paths for middleware */
30
+ paths?: (string | RegExp)[];
31
+ }[];
8
32
  }
9
33
 
10
- // The middie middleware is added for express compatibility
11
- type Handler = (
12
- req: FastifyRequest,
13
- res: FastifyReply,
14
- next: (error?: Error) => void
15
- ) => void;
34
+ /**
35
+ * Handler function type - The middie middleware is added for express
36
+ * compatibility
37
+ */
38
+ type Handler = (req: any, res: any, next: (error?: Error) => void) => void;
39
+
40
+ /** Error handler function type */
16
41
  type ErrorHandler = (
17
42
  error: Error,
18
43
  req: FastifyRequest,
@@ -21,8 +46,24 @@ declare module '@gasket/engine' {
21
46
  ) => void;
22
47
 
23
48
  export interface HookExecTypes {
24
- middleware(fastify: FastifyInstance): MaybeAsync<MaybeMultiple<Handler>>,
25
- fastify(fastify: FastifyInstance): MaybeAsync<void>,
26
- errorMiddleware(fastify: FastifyInstance): MaybeAsync<MaybeMultiple<ErrorHandler>>
49
+ middleware(
50
+ fastify: Fastify
51
+ ): MaybeAsync<MaybeMultiple<Handler> & { paths?: (string | RegExp)[] }>;
52
+ fastify(fastify: FastifyInstance): MaybeAsync<void>;
53
+ errorMiddleware(): MaybeAsync<MaybeMultiple<ErrorHandler>>;
27
54
  }
28
55
  }
56
+
57
+ declare module 'create-gasket-app' {
58
+ export interface CreateContext {
59
+ /** Flag indicating if API app is enabled */
60
+ apiApp?: boolean;
61
+ }
62
+ }
63
+
64
+ export default {
65
+ name: '@gasket/plugin-fastify',
66
+ version: '',
67
+ description: '',
68
+ hooks: {}
69
+ };
package/lib/index.js CHANGED
@@ -1,161 +1,75 @@
1
- const debug = require('diagnostics')('gasket:fastify');
2
- const { peerDependencies, name } = require('../package.json');
1
+ /// <reference types="@gasket/core" />
2
+ /// <reference types="@gasket/plugin-metadata" />
3
3
 
4
- module.exports = {
4
+ const {
5
5
  name,
6
- hooks: {
7
- /**
8
- * Add files & extend package.json for new apps.
9
- *
10
- * @param {Gasket} gasket - The gasket API.
11
- * @param {CreateContext} context - Create context
12
- * @param {PackageJson} context.pkg - The Gasket PackageJson API.
13
- * @public
14
- */
15
- create: async function create(gasket, context) {
16
- const generatorDir = `${ __dirname }/../generator`;
17
-
18
- context.pkg.add('dependencies', {
19
- fastify: peerDependencies.fastify
20
- });
21
-
22
- if (context.apiApp) {
23
- context.files.add(`${ generatorDir }/**/*`);
24
-
25
- context.gasketConfig.add('fastify', {
26
- routes: './routes/*'
27
- });
28
- }
29
- },
30
- /**
31
- * Create the Fastify instance and setup the lifecycle hooks.
32
- * Fastify is compatible with express middleware out of the box, so we can
33
- * use the same middleware lifecycles.
34
- *
35
- * @param {Gasket} gasket Gasket API.
36
- * @param {Object} serverOpts Server options.
37
- * @returns {Express} The web server.
38
- * @public
39
- */
40
- // eslint-disable-next-line max-statements
41
- createServers: async function createServers(gasket, serverOpts) {
42
- const fastify = require('fastify');
43
- const middie = require('middie');
44
- const cookieParser = require('cookie-parser');
45
- const compression = require('compression');
46
-
47
- const { logger, config } = gasket;
48
- const { middleware: middlewareConfig } = config;
49
- const trustProxy = config.fastify?.trustProxy ?? false;
50
- const excludedRoutesRegex = config.fastify && config.fastify.excludedRoutesRegex;
51
- const app = fastify({ logger, trustProxy });
52
-
53
- // Enable middleware for fastify@3
54
- await app.register(middie);
55
-
56
- // Add express-like `res.locals` object attaching data
57
- app.use(function attachLocals(req, res, next) {
58
- res.locals = {};
59
- next();
60
- });
61
-
62
- if (excludedRoutesRegex) {
63
- app.use(excludedRoutesRegex, cookieParser());
64
- } else {
65
- app.use(cookieParser());
66
- }
67
-
68
- const { compression: compressionConfig = true } = config.fastify || {};
69
- if (compressionConfig) {
70
- app.use(compression());
71
- }
72
-
73
- const middlewares = [];
74
- await gasket.execApply('middleware', async (plugin, handler) => {
75
- const middleware = await handler(app);
76
- if (middleware) {
77
- if (middlewareConfig) {
78
- const pluginName = plugin && plugin.name ? plugin.name : '';
79
- const mwConfig = middlewareConfig.find(mw => mw.plugin === pluginName);
80
- if (mwConfig) {
81
- middleware.paths = mwConfig.paths;
82
- if (excludedRoutesRegex) {
83
- middleware.paths.push(excludedRoutesRegex);
84
- }
85
- }
86
- }
87
- middlewares.push(middleware);
88
- }
89
- });
6
+ version,
7
+ description
8
+ } = require('../package.json');
9
+ const create = require('./create');
10
+ const createServers = require('./create-servers');
90
11
 
91
- debug('applied %s middleware layers to fastify', middlewares.length);
92
- middlewares.forEach(layer => {
93
- const { paths } = layer;
94
- if (paths) {
95
- app.use(paths, layer);
96
- } else if (excludedRoutesRegex) {
97
- app.use(excludedRoutesRegex, layer);
98
- } else {
99
- app.use(layer);
100
- }
101
- });
102
-
103
- // allow consuming apps to directly append options to their server
104
- await gasket.exec('fastify', app);
105
-
106
- const postRenderingStacks = (await gasket.exec('errorMiddleware')).filter(Boolean);
107
- postRenderingStacks.forEach(stack => app.use(stack));
108
-
109
- return {
110
- ...serverOpts,
111
- handler: async function handler(...args) {
112
- await app.ready();
113
- app.server.emit('request', ...args);
114
- }
115
- };
116
- },
12
+ /** @type {import('@gasket/core').Plugin} */
13
+ const plugin = {
14
+ name,
15
+ version,
16
+ description,
17
+ hooks: {
18
+ create,
19
+ createServers,
117
20
  metadata(gasket, meta) {
118
21
  return {
119
22
  ...meta,
120
- lifecycles: [{
121
- name: 'middleware',
122
- method: 'exec',
123
- description: 'Add Express style middleware for Fastify',
124
- link: 'README.md#middleware',
125
- parent: 'createServers'
126
- }, {
127
- name: 'fastify',
128
- method: 'exec',
129
- description: 'Modify the Fastify instance to for adding endpoints',
130
- link: 'README.md#express',
131
- parent: 'createServers',
132
- after: 'middleware'
133
- }, {
134
- name: 'errorMiddleware',
135
- method: 'exec',
136
- description: 'Add Express style middleware for handling errors with Fastify',
137
- link: 'README.md#errorMiddleware',
138
- parent: 'createServers',
139
- after: 'express'
140
- }],
141
- configurations: [{
142
- name: 'fastify',
143
- link: 'README.md#configuration',
144
- description: 'Fastify configuration object',
145
- type: 'object'
146
- }, {
147
- name: 'fastify.compression',
148
- link: 'README.md#configuration',
149
- description: 'Automatic compression',
150
- type: 'boolean',
151
- default: true
152
- }, {
153
- name: 'fastify.excludedRoutesRegex',
154
- link: 'README.md#configuration',
155
- description: 'Routes to be excluded based on a regex',
156
- type: 'RegExp'
157
- }]
23
+ lifecycles: [
24
+ {
25
+ name: 'middleware',
26
+ method: 'exec',
27
+ description: 'Add Express style middleware for Fastify',
28
+ link: 'README.md#middleware',
29
+ parent: 'createServers'
30
+ },
31
+ {
32
+ name: 'fastify',
33
+ method: 'exec',
34
+ description: 'Modify the Fastify instance to for adding endpoints',
35
+ link: 'README.md#express',
36
+ parent: 'createServers',
37
+ after: 'middleware'
38
+ },
39
+ {
40
+ name: 'errorMiddleware',
41
+ method: 'exec',
42
+ description:
43
+ 'Add Express style middleware for handling errors with Fastify',
44
+ link: 'README.md#errorMiddleware',
45
+ parent: 'createServers',
46
+ after: 'express'
47
+ }
48
+ ],
49
+ configurations: [
50
+ {
51
+ name: 'fastify',
52
+ link: 'README.md#configuration',
53
+ description: 'Fastify configuration object',
54
+ type: 'object'
55
+ },
56
+ {
57
+ name: 'fastify.compression',
58
+ link: 'README.md#configuration',
59
+ description: 'Automatic compression',
60
+ type: 'boolean',
61
+ default: true
62
+ },
63
+ {
64
+ name: 'fastify.excludedRoutesRegex',
65
+ link: 'README.md#configuration',
66
+ description: 'Routes to be excluded based on a regex',
67
+ type: 'RegExp'
68
+ }
69
+ ]
158
70
  };
159
71
  }
160
72
  }
161
73
  };
74
+
75
+ module.exports = plugin;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@gasket/plugin-fastify",
3
- "version": "7.0.0-next.4",
3
+ "version": "7.0.0-next.41",
4
4
  "description": "Adds fastify support to your application",
5
- "main": "lib",
5
+ "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
8
8
  "lib"
@@ -13,7 +13,9 @@
13
13
  "test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict' jest",
14
14
  "test:watch": "jest --watch",
15
15
  "test:coverage": "jest --coverage",
16
- "posttest": "npm run lint"
16
+ "posttest": "npm run lint && npm run typecheck",
17
+ "typecheck": "tsc",
18
+ "typecheck:watch": "tsc --watch"
17
19
  },
18
20
  "repository": {
19
21
  "type": "git",
@@ -36,22 +38,17 @@
36
38
  "url": "https://github.com/godaddy/gasket/issues"
37
39
  },
38
40
  "homepage": "https://github.com/godaddy/gasket/tree/main/packages/gasket-plugin-fastify",
39
- "dependencies": {
40
- "compression": "^1.7.4",
41
- "cookie-parser": "^1.4.6",
42
- "diagnostics": "^2.0.2",
43
- "middie": "^5.4.0"
44
- },
45
41
  "devDependencies": {
46
- "@gasket/engine": "^7.0.0-next.4",
42
+ "@gasket/core": "^7.0.0-next.41",
47
43
  "cross-env": "^7.0.3",
48
44
  "eslint": "^8.56.0",
49
- "eslint-config-godaddy": "^7.0.2",
45
+ "eslint-config-godaddy": "^7.1.0",
50
46
  "eslint-plugin-jest": "^27.6.3",
51
47
  "eslint-plugin-json": "^3.1.0",
52
48
  "eslint-plugin-unicorn": "^44.0.0",
53
49
  "fastify": "^3.3.0",
54
- "jest": "^29.7.0"
50
+ "jest": "^29.7.0",
51
+ "typescript": "^5.4.5"
55
52
  },
56
53
  "peerDependencies": {
57
54
  "fastify": "^3.0.0"
@@ -59,10 +56,12 @@
59
56
  "eslintConfig": {
60
57
  "extends": [
61
58
  "godaddy",
62
- "plugin:jest/recommended"
59
+ "plugin:jest/recommended",
60
+ "plugin:jsdoc/recommended-typescript-flavor"
63
61
  ],
64
62
  "plugins": [
65
- "unicorn"
63
+ "unicorn",
64
+ "jsdoc"
66
65
  ],
67
66
  "rules": {
68
67
  "unicorn/filename-case": "error"
@@ -71,5 +70,5 @@
71
70
  "eslintIgnore": [
72
71
  "generator"
73
72
  ],
74
- "gitHead": "5a76c18917da4d37c2aa2f9b9a70e2514ee81398"
73
+ "gitHead": "60168b97e936fbc85a1eb9863f6bf202bb055a81"
75
74
  }