@gasket/plugin-fastify 7.4.5 → 7.5.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/EXAMPLES.md ADDED
@@ -0,0 +1,144 @@
1
+ # @gasket/plugin-fastify Examples
2
+
3
+ This document provides working examples for all exported interfaces from `@gasket/plugin-fastify`.
4
+
5
+ ## Plugin Installation and Configuration
6
+
7
+ ### Basic Plugin Setup
8
+
9
+ ```js
10
+ // gasket.js
11
+ import { makeGasket } from '@gasket/core';
12
+ import pluginFastify from '@gasket/plugin-fastify';
13
+
14
+ export default makeGasket({
15
+ plugins: [
16
+ pluginFastify
17
+ ]
18
+ });
19
+ ```
20
+
21
+ ### Plugin Configuration
22
+
23
+ ```js
24
+ // gasket.js
25
+ export default makeGasket({
26
+ plugins: [
27
+ pluginFastify
28
+ ],
29
+ fastify: {
30
+ compression: true,
31
+ trustProxy: true,
32
+ disableRequestLogging: false
33
+ }
34
+ });
35
+ ```
36
+
37
+ ## Lifecycle Hooks
38
+
39
+ ### `fastify` Lifecycle Hook
40
+
41
+ Access and modify the Fastify instance:
42
+
43
+ ```js
44
+ // Example plugin or lifecycle file
45
+ export default {
46
+ name: 'my-fastify-plugin',
47
+ hooks: {
48
+ fastify: async function (gasket, app) {
49
+ // Register plugins
50
+ app.register(require('@fastify/cors'), {
51
+ origin: true
52
+ });
53
+
54
+ // Add hooks
55
+ app.addHook('preHandler', async (request, reply) => {
56
+ console.log('Processing request:', request.url);
57
+ });
58
+
59
+ // Add custom decorators
60
+ app.decorate('customMethod', function() {
61
+ return 'custom value';
62
+ });
63
+
64
+ // Add routes
65
+ app.get('/hello', async (request, reply) => {
66
+ return { hello: 'world' };
67
+ });
68
+ }
69
+ }
70
+ };
71
+ ```
72
+
73
+ ### `errorMiddleware` Lifecycle Hook
74
+
75
+ Add Express-style error handling middleware:
76
+
77
+ ```js
78
+ // Example plugin
79
+ export default {
80
+ name: 'my-error-handler',
81
+ hooks: {
82
+ errorMiddleware: function (gasket) {
83
+ return (error, req, res, next) => {
84
+ gasket.logger.error('Request error:', error);
85
+
86
+ // Handle different error types
87
+ if (error.statusCode) {
88
+ res.status(error.statusCode);
89
+ } else {
90
+ res.status(500);
91
+ }
92
+
93
+ res.send({
94
+ error: 'Internal Server Error',
95
+ message: error.message
96
+ });
97
+ };
98
+ }
99
+ }
100
+ };
101
+ ```
102
+
103
+ ## Configuration Examples
104
+
105
+ ### Route Plugin Example
106
+
107
+ ```js
108
+ // plugins/routes-plugin.js
109
+ export default {
110
+ name: 'routes-plugin',
111
+ hooks: {
112
+ fastify: async function (gasket, app) {
113
+ // API routes
114
+ app.get('/api/health', async (request, reply) => {
115
+ return {
116
+ status: 'healthy',
117
+ timestamp: new Date().toISOString(),
118
+ version: process.env.npm_package_version
119
+ };
120
+ });
121
+
122
+ app.get('/api/config', async (request, reply) => {
123
+ return {
124
+ environment: gasket.config.env,
125
+ features: gasket.config.features || {}
126
+ };
127
+ });
128
+
129
+ // Protected route example
130
+ app.get('/api/protected', {
131
+ preHandler: async (request, reply) => {
132
+ const auth = request.headers.authorization;
133
+ if (!auth || !auth.startsWith('Bearer ')) {
134
+ reply.code(401).send({ error: 'Unauthorized' });
135
+ return;
136
+ }
137
+ }
138
+ }, async (request, reply) => {
139
+ return { message: 'Protected data' };
140
+ });
141
+ }
142
+ }
143
+ };
144
+ ```
@@ -0,0 +1,21 @@
1
+ Object.defineProperty(exports, "__esModule", {
2
+ value: true
3
+ });
4
+ Object.defineProperty(exports, "default", {
5
+ enumerable: true,
6
+ get: function() {
7
+ return _default;
8
+ }
9
+ });
10
+ const _utils = require("./utils.cjs");
11
+ const actions = {
12
+ /**
13
+ * @deprecated
14
+ * @param {import('@gasket/core').Gasket} gasket - Gasket instance
15
+ * @returns {import('fastify').FastifyInstance} - Fastify instance
16
+ */ getFastifyApp (gasket) {
17
+ gasket.logger.warn(`DEPRECATED \`getFastifyApp\` action will not be support in future major release.`);
18
+ return (0, _utils.getAppInstance)(gasket);
19
+ }
20
+ };
21
+ const _default = actions;
@@ -0,0 +1,34 @@
1
+ /// <reference types="@gasket/plugin-https" />
2
+ /// <reference types="@gasket/plugin-logger" />
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, /**
7
+ * Create the Fastify instance and setup the lifecycle hooks.
8
+ * Fastify is compatible with express middleware out of the box, so we can
9
+ * use the same middleware lifecycles.
10
+ * @type {import('@gasket/core').HookHandler<'createServers'>}
11
+ */ "default", {
12
+ enumerable: true,
13
+ get: function() {
14
+ return createServers;
15
+ }
16
+ });
17
+ const _utils = require("./utils.cjs");
18
+ async function createServers(gasket, serverOpts) {
19
+ /** Cast to Fastify + Express hybrid because Gasket adds `.use()` via @fastify/express plugin */ const app = /** @type {import('fastify').FastifyInstance & { use: Function }} */ (0, _utils.getAppInstance)(gasket);
20
+ // allow consuming apps to directly append options to their server
21
+ await gasket.exec('fastify', app);
22
+ const postRenderingStacks = (await gasket.exec('errorMiddleware')).filter(Boolean);
23
+ postRenderingStacks.forEach((stack)=>{
24
+ /** @type {import('connect').NextHandleFunction} */ const middleware = stack;
25
+ app.use(middleware);
26
+ });
27
+ return {
28
+ ...serverOpts,
29
+ handler: async function handler(...args) {
30
+ await app.ready();
31
+ app.server.emit('request', ...args);
32
+ }
33
+ };
34
+ }
package/cjs/create.cjs ADDED
@@ -0,0 +1,72 @@
1
+ /// <reference types="@gasket/core" />
2
+ /// <reference types="create-gasket-app" />
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, /**
7
+ * Add files & extend package.json for new apps.
8
+ * @type {import('@gasket/core').HookHandler<'create'>}
9
+ */ "default", {
10
+ enumerable: true,
11
+ get: function() {
12
+ return create;
13
+ }
14
+ });
15
+ const _url = require("url");
16
+ const _path = require("path");
17
+ const _packagejson = /*#__PURE__*/ _interop_require_default(require("../package.json"));
18
+ function _interop_require_default(obj) {
19
+ return obj && obj.__esModule ? obj : {
20
+ default: obj
21
+ };
22
+ }
23
+ const __filename1 = (0, _url.fileURLToPath)(require("url").pathToFileURL(__filename).toString());
24
+ const __dirname = (0, _path.dirname)(__filename1);
25
+ const { name, version, devDependencies } = _packagejson.default;
26
+ const createTestFiles = ({ files, generatorDir, testPlugins, globIgnore })=>{
27
+ if (!testPlugins || testPlugins.length === 0) return;
28
+ const unit = [
29
+ 'jest',
30
+ 'mocha',
31
+ 'vitest'
32
+ ];
33
+ const integration = [
34
+ 'cypress'
35
+ ];
36
+ const frameworks = [
37
+ ...unit,
38
+ ...integration
39
+ ];
40
+ const frameworksRegex = new RegExp(frameworks.join('|'));
41
+ testPlugins.forEach((testPlugin)=>{
42
+ const match = frameworksRegex.exec(testPlugin);
43
+ if (match) {
44
+ const matchedFramework = match[0];
45
+ if (unit.includes(matchedFramework)) {
46
+ files.add(`${generatorDir}/${matchedFramework}/*`, `${generatorDir}/${matchedFramework}/**/${globIgnore}`);
47
+ } else {
48
+ files.add(`${generatorDir}/${matchedFramework}/*`, `${generatorDir}/${matchedFramework}/**/*`);
49
+ }
50
+ }
51
+ });
52
+ };
53
+ async function create(gasket, context) {
54
+ const { files, typescript, apiApp, addApiRoutes = true, testPlugins, pkg, gasketConfig } = context;
55
+ const generatorDir = `${__dirname}/../generator`;
56
+ gasketConfig.addPlugin('pluginFastify', name);
57
+ pkg.add('dependencies', {
58
+ [name]: `^${version}`,
59
+ fastify: devDependencies.fastify
60
+ });
61
+ if (apiApp && addApiRoutes) {
62
+ const globIgnore = typescript ? '!(*.js)' : '!(*.ts)';
63
+ files.add(`${generatorDir}/app/**/${globIgnore}`);
64
+ gasketConfig.addPlugin('pluginRoutes', './plugins/routes-plugin.js');
65
+ createTestFiles({
66
+ files,
67
+ generatorDir,
68
+ testPlugins,
69
+ globIgnore
70
+ });
71
+ }
72
+ }
package/cjs/index.cjs ADDED
@@ -0,0 +1,84 @@
1
+ /// <reference types="@gasket/core" />
2
+ /// <reference types="@gasket/plugin-metadata" />
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function() {
9
+ return _default;
10
+ }
11
+ });
12
+ const _create = /*#__PURE__*/ _interop_require_default(require("./create.cjs"));
13
+ const _createservers = /*#__PURE__*/ _interop_require_default(require("./create-servers.cjs"));
14
+ const _actions = /*#__PURE__*/ _interop_require_default(require("./actions.cjs"));
15
+ const _packagejson = /*#__PURE__*/ _interop_require_default(require("../package.json"));
16
+ function _interop_require_default(obj) {
17
+ return obj && obj.__esModule ? obj : {
18
+ default: obj
19
+ };
20
+ }
21
+ const { name, version, description } = _packagejson.default;
22
+ /** @type {import('@gasket/core').Plugin} */ const plugin = {
23
+ name,
24
+ version,
25
+ description,
26
+ actions: _actions.default,
27
+ hooks: {
28
+ create: _create.default,
29
+ createServers: _createservers.default,
30
+ metadata (gasket, meta) {
31
+ return {
32
+ ...meta,
33
+ actions: [
34
+ {
35
+ name: 'getFastifyApp',
36
+ description: 'Get the Fastify app instance',
37
+ link: 'README.md#getFastifyApp',
38
+ deprecated: true
39
+ }
40
+ ],
41
+ lifecycles: [
42
+ {
43
+ name: 'fastify',
44
+ method: 'exec',
45
+ description: 'Modify the Fastify instance to for adding endpoints',
46
+ link: 'README.md#express',
47
+ parent: 'createServers',
48
+ after: 'middleware'
49
+ },
50
+ {
51
+ name: 'errorMiddleware',
52
+ method: 'exec',
53
+ description: 'Add Express style middleware for handling errors with Fastify',
54
+ link: 'README.md#errorMiddleware',
55
+ parent: 'createServers',
56
+ after: 'express'
57
+ }
58
+ ],
59
+ configurations: [
60
+ {
61
+ name: 'fastify',
62
+ link: 'README.md#configuration',
63
+ description: 'Fastify configuration object',
64
+ type: 'object'
65
+ },
66
+ {
67
+ name: 'fastify.compression',
68
+ link: 'README.md#configuration',
69
+ description: 'Automatic compression',
70
+ type: 'boolean',
71
+ default: true
72
+ },
73
+ {
74
+ name: 'fastify.excludedRoutesRegex',
75
+ link: 'README.md#configuration',
76
+ description: 'Routes to be excluded based on a regex',
77
+ type: 'RegExp'
78
+ }
79
+ ]
80
+ };
81
+ }
82
+ }
83
+ };
84
+ const _default = plugin;
@@ -0,0 +1 @@
1
+ {}
package/cjs/utils.cjs ADDED
@@ -0,0 +1,66 @@
1
+ // @ts-nocheck
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: all[name]
9
+ });
10
+ }
11
+ _export(exports, {
12
+ alignLogger: function() {
13
+ return alignLogger;
14
+ },
15
+ getAppInstance: function() {
16
+ return getAppInstance;
17
+ },
18
+ testClearAppInstance: function() {
19
+ return testClearAppInstance;
20
+ }
21
+ });
22
+ const _fastify = /*#__PURE__*/ _interop_require_default(require("fastify"));
23
+ function _interop_require_default(obj) {
24
+ return obj && obj.__esModule ? obj : {
25
+ default: obj
26
+ };
27
+ }
28
+ const fallbackMap = {
29
+ fatal: 'error',
30
+ trace: 'debug'
31
+ };
32
+ /**
33
+ * A helper function to ensure that all the required log levels
34
+ * for a Fastify server are present.
35
+ * @type {import('@gasket/plugin-fastify').alignLogger}
36
+ */ function alignLogger(logger) {
37
+ const fastifyLogger = logger;
38
+ [
39
+ 'fatal',
40
+ 'trace'
41
+ ].map((level)=>{
42
+ if (!logger[level]) {
43
+ fastifyLogger[level] = logger[fallbackMap[level]];
44
+ }
45
+ });
46
+ return fastifyLogger;
47
+ }
48
+ let instance = null;
49
+ function getAppInstance(gasket) {
50
+ if (!instance) {
51
+ const { fastify: fastifyConfig = {}, http2, https } = gasket.config;
52
+ const { trustProxy = false, disableRequestLogging = true } = fastifyConfig;
53
+ const fastifyLogger = alignLogger(gasket.logger);
54
+ instance = (0, _fastify.default)({
55
+ logger: fastifyLogger,
56
+ trustProxy,
57
+ https,
58
+ http2,
59
+ disableRequestLogging
60
+ });
61
+ }
62
+ return instance;
63
+ }
64
+ function testClearAppInstance() {
65
+ instance = null;
66
+ }
package/lib/actions.js CHANGED
@@ -1,4 +1,4 @@
1
- const { getAppInstance } = require('./utils.js');
1
+ import { getAppInstance } from './utils.js';
2
2
 
3
3
  const actions = {
4
4
  /**
@@ -14,4 +14,4 @@ const actions = {
14
14
  }
15
15
  };
16
16
 
17
- module.exports = actions;
17
+ export default actions;
@@ -1,14 +1,15 @@
1
1
  /// <reference types="@gasket/plugin-https" />
2
2
  /// <reference types="@gasket/plugin-logger" />
3
3
 
4
- const { getAppInstance } = require('./utils.js');
4
+ import { getAppInstance } from './utils.js';
5
+
5
6
  /**
6
7
  * Create the Fastify instance and setup the lifecycle hooks.
7
8
  * Fastify is compatible with express middleware out of the box, so we can
8
9
  * use the same middleware lifecycles.
9
10
  * @type {import('@gasket/core').HookHandler<'createServers'>}
10
11
  */
11
- module.exports = async function createServers(gasket, serverOpts) {
12
+ export default async function createServers(gasket, serverOpts) {
12
13
  /** Cast to Fastify + Express hybrid because Gasket adds `.use()` via @fastify/express plugin */
13
14
  const app = /** @type {import('fastify').FastifyInstance & { use: Function }} */ (getAppInstance(gasket));
14
15
 
@@ -29,4 +30,4 @@ module.exports = async function createServers(gasket, serverOpts) {
29
30
  app.server.emit('request', ...args);
30
31
  }
31
32
  };
32
- };
33
+ }
package/lib/create.js CHANGED
@@ -1,7 +1,12 @@
1
1
  /// <reference types="@gasket/core" />
2
2
  /// <reference types="create-gasket-app" />
3
3
 
4
- const { name, version, devDependencies } = require('../package.json');
4
+ import { fileURLToPath } from 'url';
5
+ import { dirname } from 'path';
6
+ import packageJson from '../package.json' with { type: 'json' };
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ const { name, version, devDependencies } = packageJson;
5
10
 
6
11
  const createTestFiles = ({ files, generatorDir, testPlugins, globIgnore }) => {
7
12
  if (!testPlugins || testPlugins.length === 0) return;
@@ -27,7 +32,7 @@ const createTestFiles = ({ files, generatorDir, testPlugins, globIgnore }) => {
27
32
  * Add files & extend package.json for new apps.
28
33
  * @type {import('@gasket/core').HookHandler<'create'>}
29
34
  */
30
- module.exports = async function create(gasket, context) {
35
+ export default async function create(gasket, context) {
31
36
  const {
32
37
  files,
33
38
  typescript,
@@ -53,4 +58,4 @@ module.exports = async function create(gasket, context) {
53
58
 
54
59
  createTestFiles({ files, generatorDir, testPlugins, globIgnore });
55
60
  }
56
- };
61
+ }
package/lib/index.js CHANGED
@@ -1,10 +1,11 @@
1
1
  /// <reference types="@gasket/core" />
2
2
  /// <reference types="@gasket/plugin-metadata" />
3
3
 
4
- const { name, version, description } = require('../package.json');
5
- const create = require('./create');
6
- const createServers = require('./create-servers');
7
- const actions = require('./actions');
4
+ import create from './create.js';
5
+ import createServers from './create-servers.js';
6
+ import actions from './actions.js';
7
+ import packageJson from '../package.json' with { type: 'json' };
8
+ const { name, version, description } = packageJson;
8
9
 
9
10
  /** @type {import('@gasket/core').Plugin} */
10
11
  const plugin = {
@@ -71,4 +72,4 @@ const plugin = {
71
72
  }
72
73
  };
73
74
 
74
- module.exports = plugin;
75
+ export default plugin;
package/lib/utils.js CHANGED
@@ -1,5 +1,7 @@
1
1
  // @ts-nocheck
2
2
 
3
+ import fastify from 'fastify';
4
+
3
5
  const fallbackMap = {
4
6
  fatal: 'error',
5
7
  trace: 'debug'
@@ -28,9 +30,8 @@ let instance = null;
28
30
  * @param {import('@gasket/core').Gasket} gasket - Gasket instance
29
31
  * @returns {import('fastify').FastifyInstance} - Fastify instance
30
32
  */
31
- function getAppInstance(gasket) {
33
+ export function getAppInstance(gasket) {
32
34
  if (!instance) {
33
- const fastify = require('fastify');
34
35
  const { fastify: fastifyConfig = {}, http2, https } = gasket.config;
35
36
  const { trustProxy = false, disableRequestLogging = true } = fastifyConfig;
36
37
  const fastifyLogger = alignLogger(gasket.logger);
@@ -41,10 +42,8 @@ function getAppInstance(gasket) {
41
42
  return instance;
42
43
  }
43
44
 
44
- module.exports = {
45
- alignLogger,
46
- getAppInstance,
47
- testClearAppInstance: () => {
48
- instance = null;
49
- }
50
- };
45
+ export { alignLogger };
46
+
47
+ export function testClearAppInstance() {
48
+ instance = null;
49
+ }
package/package.json CHANGED
@@ -1,13 +1,24 @@
1
1
  {
2
2
  "name": "@gasket/plugin-fastify",
3
- "version": "7.4.5",
3
+ "version": "7.5.0",
4
4
  "description": "Adds fastify support to your application",
5
- "main": "lib/index.js",
6
- "types": "lib/index.d.ts",
5
+ "type": "module",
6
+ "main": "./lib/index.js",
7
+ "types": "./lib/index.d.ts",
7
8
  "files": [
9
+ "cjs",
8
10
  "generator",
9
- "lib"
11
+ "lib",
12
+ "EXAMPLES.md"
10
13
  ],
14
+ "exports": {
15
+ ".": {
16
+ "types": "./lib/index.d.ts",
17
+ "import": "./lib/index.js",
18
+ "require": "./cjs/index.cjs"
19
+ },
20
+ "./package.json": "./package.json"
21
+ },
11
22
  "repository": "godaddy/gasket.git",
12
23
  "publishConfig": {
13
24
  "access": "public"
@@ -28,26 +39,25 @@
28
39
  "devDependencies": {
29
40
  "@types/connect": "^3.4.38",
30
41
  "fastify": "^4.29.1",
31
- "jest": "^29.7.0",
32
- "@gasket/core": "^7.6.2",
33
- "@gasket/plugin-https": "^7.3.11",
34
- "@gasket/plugin-logger": "^7.3.7",
35
- "@gasket/plugin-metadata": "^7.5.3",
36
- "create-gasket-app": "^7.4.12"
42
+ "vitest": "^3.2.0",
43
+ "@gasket/cjs": "^7.1.0",
44
+ "@gasket/core": "^7.6.3",
45
+ "@gasket/plugin-https": "^7.4.0",
46
+ "@gasket/plugin-logger": "^7.4.0",
47
+ "@gasket/plugin-metadata": "^7.5.5",
48
+ "create-gasket-app": "^7.4.15"
37
49
  },
38
50
  "peerDependencies": {
39
51
  "fastify": "^4.29.1"
40
52
  },
41
- "jest": {
42
- "rootDir": "test"
43
- },
44
53
  "scripts": {
54
+ "build": "gasket-cjs ./lib",
45
55
  "lint": "eslint .",
46
56
  "lint:fix": "pnpm run lint --fix",
47
57
  "posttest": "pnpm run lint && pnpm run typecheck",
48
- "test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict' jest",
49
- "test:coverage": "jest --coverage",
50
- "test:watch": "jest --watch",
58
+ "test": "cross-env NODE_OPTIONS='--unhandled-rejections=strict' vitest run",
59
+ "test:coverage": "vitest run --coverage",
60
+ "test:watch": "vitest watch",
51
61
  "typecheck": "tsc",
52
62
  "typecheck:watch": "tsc --watch"
53
63
  }