@gasket/plugin-fastify 7.0.0-next.9 → 7.0.1-canary.10

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.
@@ -0,0 +1,94 @@
1
+ /// <reference types="@gasket/plugin-https" />
2
+ /// <reference types="@gasket/plugin-logger" />
3
+
4
+ const fastify = require('fastify');
5
+ const middie = require('middie');
6
+ const cookieParser = require('cookie-parser');
7
+ const compression = require('compression');
8
+ const debug = require('diagnostics')('gasket:fastify');
9
+
10
+ /**
11
+ * Create the Fastify instance and setup the lifecycle hooks.
12
+ * Fastify is compatible with express middleware out of the box, so we can
13
+ * use the same middleware lifecycles.
14
+ * @type {import('@gasket/core').HookHandler<'createServers'>}
15
+ */
16
+ // eslint-disable-next-line max-statements
17
+ module.exports = async function createServers(gasket, serverOpts) {
18
+ const { logger, config } = gasket;
19
+ const { middleware: middlewareConfig } = config;
20
+ const trustProxy = config.fastify?.trustProxy ?? false;
21
+ const excludedRoutesRegex =
22
+ config.fastify && config.fastify.excludedRoutesRegex;
23
+ // @ts-ignore
24
+ const app = fastify({ logger, trustProxy });
25
+
26
+ // Enable middleware for fastify@3
27
+ await app.register(middie);
28
+
29
+ // Add express-like `res.locals` object attaching data
30
+ app.use(function attachLocals(req, res, next) {
31
+ res.locals = {};
32
+ next();
33
+ });
34
+
35
+ if (excludedRoutesRegex) {
36
+ app.use(excludedRoutesRegex, cookieParser());
37
+ } else {
38
+ app.use(cookieParser());
39
+ }
40
+
41
+ const { compression: compressionConfig = true } = config.fastify || {};
42
+ if (compressionConfig) {
43
+ app.use(compression());
44
+ }
45
+
46
+ const middlewares = [];
47
+
48
+ await gasket.execApply('middleware', async (plugin, handler) => {
49
+ const middleware = await handler(app);
50
+ if (middleware) {
51
+ if (middlewareConfig) {
52
+ const pluginName = plugin && plugin.name ? plugin.name : '';
53
+ const mwConfig = middlewareConfig.find(
54
+ (mw) => mw.plugin === pluginName
55
+ );
56
+ if (mwConfig) {
57
+ middleware.paths = mwConfig.paths;
58
+ if (excludedRoutesRegex) {
59
+ middleware.paths.push(excludedRoutesRegex);
60
+ }
61
+ }
62
+ }
63
+ middlewares.push(middleware);
64
+ }
65
+ });
66
+
67
+ debug('applied %s middleware layers to fastify', middlewares.length);
68
+ middlewares.forEach((layer) => {
69
+ const { paths } = layer;
70
+ if (paths) {
71
+ app.use(paths, layer);
72
+ } else if (excludedRoutesRegex) {
73
+ app.use(excludedRoutesRegex, layer);
74
+ } else {
75
+ app.use(layer);
76
+ }
77
+ });
78
+
79
+ // allow consuming apps to directly append options to their server
80
+ await gasket.exec('fastify', app);
81
+
82
+ const postRenderingStacks = (await gasket.exec('errorMiddleware')).filter(
83
+ Boolean
84
+ );
85
+ postRenderingStacks.forEach((stack) => app.use(stack));
86
+
87
+ return {
88
+ ...serverOpts,
89
+ handler: async function handler(...args) {
90
+ await app.ready();
91
+ app.server.emit('request', ...args);
92
+ }
93
+ };
94
+ };
package/lib/index.d.ts CHANGED
@@ -1,18 +1,39 @@
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
+ Fastify,
4
+ FastifyRequest,
5
+ FastifyReply,
6
+ FastifyServerOptions
7
+ } from 'fastify';
3
8
 
4
- declare module '@gasket/engine' {
9
+ declare module '@gasket/core' {
5
10
  export interface GasketConfig {
6
- compression?: boolean,
7
- excludedRoutesRegex?: RegExp
11
+ fastify?: {
12
+ /** Enable compression */
13
+ compression?: boolean;
14
+ /** Regular expression for excluded routes */
15
+ excludedRoutesRegex?: RegExp;
16
+ /** Trust proxy configuration */
17
+ trustProxy?: FastifyServerOptions['trustProxy'];
18
+ /** Glob pattern for source files setting up fastify routes */
19
+ routes?: string;
20
+ };
21
+ /** Middleware configuration */
22
+ middleware?: {
23
+ /** Plugin name */
24
+ plugin: string;
25
+ /** Paths for middleware */
26
+ paths?: (string | RegExp)[];
27
+ }[];
8
28
  }
9
29
 
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;
30
+ /**
31
+ * Handler function type - The middie middleware is added for express
32
+ * compatibility
33
+ */
34
+ type Handler = (req: any, res: any, next: (error?: Error) => void) => void;
35
+
36
+ /** Error handler function type */
16
37
  type ErrorHandler = (
17
38
  error: Error,
18
39
  req: FastifyRequest,
@@ -21,8 +42,22 @@ declare module '@gasket/engine' {
21
42
  ) => void;
22
43
 
23
44
  export interface HookExecTypes {
24
- middleware(fastify: FastifyInstance): MaybeAsync<MaybeMultiple<Handler>>,
25
- fastify(fastify: FastifyInstance): MaybeAsync<void>,
26
- errorMiddleware(fastify: FastifyInstance): MaybeAsync<MaybeMultiple<ErrorHandler>>
45
+ middleware(
46
+ fastify: Fastify
47
+ ): MaybeAsync<MaybeMultiple<Handler> & { paths?: (string | RegExp)[] }>;
48
+ fastify(fastify: Fastify): MaybeAsync<void>;
49
+ errorMiddleware(): MaybeAsync<MaybeMultiple<ErrorHandler>>;
27
50
  }
28
51
  }
52
+
53
+ declare module 'create-gasket-app' {
54
+ export interface CreateContext {
55
+ /** Flag indicating if API app is enabled */
56
+ apiApp?: boolean;
57
+ }
58
+ }
59
+
60
+ export default {
61
+ name: '@gasket/plugin-fastify',
62
+ hooks: {}
63
+ };
package/lib/index.js CHANGED
@@ -1,161 +1,82 @@
1
- const debug = require('diagnostics')('gasket:fastify');
1
+ /// <reference types="@gasket/core" />
2
+ /// <reference types="@gasket/plugin-metadata" />
3
+
2
4
  const { peerDependencies, name } = require('../package.json');
5
+ const createServers = require('./create-servers');
3
6
 
4
- module.exports = {
7
+ /** @type {import('@gasket/core').Plugin} */
8
+ const plugin = {
5
9
  name,
6
10
  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
11
  create: async function create(gasket, context) {
16
- const generatorDir = `${ __dirname }/../generator`;
12
+ const generatorDir = `${__dirname}/../generator`;
17
13
 
18
14
  context.pkg.add('dependencies', {
19
15
  fastify: peerDependencies.fastify
20
16
  });
21
17
 
22
- if (context.apiApp) {
23
- context.files.add(`${ generatorDir }/**/*`);
18
+ if ('apiApp' in context && context.apiApp) {
19
+ context.files.add(`${generatorDir}/**/*`);
24
20
 
25
21
  context.gasketConfig.add('fastify', {
26
22
  routes: './routes/*'
27
23
  });
28
24
  }
29
25
  },
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
- });
90
-
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
- },
26
+ createServers,
117
27
  metadata(gasket, meta) {
118
28
  return {
119
29
  ...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
- }]
30
+ lifecycles: [
31
+ {
32
+ name: 'middleware',
33
+ method: 'exec',
34
+ description: 'Add Express style middleware for Fastify',
35
+ link: 'README.md#middleware',
36
+ parent: 'createServers'
37
+ },
38
+ {
39
+ name: 'fastify',
40
+ method: 'exec',
41
+ description: 'Modify the Fastify instance to for adding endpoints',
42
+ link: 'README.md#express',
43
+ parent: 'createServers',
44
+ after: 'middleware'
45
+ },
46
+ {
47
+ name: 'errorMiddleware',
48
+ method: 'exec',
49
+ description:
50
+ 'Add Express style middleware for handling errors with Fastify',
51
+ link: 'README.md#errorMiddleware',
52
+ parent: 'createServers',
53
+ after: 'express'
54
+ }
55
+ ],
56
+ configurations: [
57
+ {
58
+ name: 'fastify',
59
+ link: 'README.md#configuration',
60
+ description: 'Fastify configuration object',
61
+ type: 'object'
62
+ },
63
+ {
64
+ name: 'fastify.compression',
65
+ link: 'README.md#configuration',
66
+ description: 'Automatic compression',
67
+ type: 'boolean',
68
+ default: true
69
+ },
70
+ {
71
+ name: 'fastify.excludedRoutesRegex',
72
+ link: 'README.md#configuration',
73
+ description: 'Routes to be excluded based on a regex',
74
+ type: 'RegExp'
75
+ }
76
+ ]
158
77
  };
159
78
  }
160
79
  }
161
80
  };
81
+
82
+ 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.9",
3
+ "version": "7.0.1-canary.10",
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",
@@ -43,15 +45,16 @@
43
45
  "middie": "^5.4.0"
44
46
  },
45
47
  "devDependencies": {
46
- "@gasket/engine": "^7.0.0-next.9",
48
+ "@gasket/core": "^7.0.1-canary.10",
47
49
  "cross-env": "^7.0.3",
48
50
  "eslint": "^8.56.0",
49
- "eslint-config-godaddy": "^7.0.2",
51
+ "eslint-config-godaddy": "^7.1.0",
50
52
  "eslint-plugin-jest": "^27.6.3",
51
53
  "eslint-plugin-json": "^3.1.0",
52
54
  "eslint-plugin-unicorn": "^44.0.0",
53
55
  "fastify": "^3.3.0",
54
- "jest": "^29.7.0"
56
+ "jest": "^29.7.0",
57
+ "typescript": "^5.4.5"
55
58
  },
56
59
  "peerDependencies": {
57
60
  "fastify": "^3.0.0"
@@ -59,10 +62,12 @@
59
62
  "eslintConfig": {
60
63
  "extends": [
61
64
  "godaddy",
62
- "plugin:jest/recommended"
65
+ "plugin:jest/recommended",
66
+ "plugin:jsdoc/recommended-typescript-flavor"
63
67
  ],
64
68
  "plugins": [
65
- "unicorn"
69
+ "unicorn",
70
+ "jsdoc"
66
71
  ],
67
72
  "rules": {
68
73
  "unicorn/filename-case": "error"
@@ -71,5 +76,5 @@
71
76
  "eslintIgnore": [
72
77
  "generator"
73
78
  ],
74
- "gitHead": "d993b3d02586581fee56576d860eb2a8393e601c"
79
+ "gitHead": "ade41f0398f6adedb73d47a4a2dc9bff30e12437"
75
80
  }