Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PFX-350]: Upgrade to Fastify v4 #727

Merged
merged 26 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
80e3f88
fastify v4 and logger updates for fastify compatibility
bbetts-godaddy Mar 25, 2024
46d4439
merge with v7
bbetts-godaddy Mar 27, 2024
a0220ad
merge v7 and resolve package-lock conflicts
bbetts-godaddy Apr 3, 2024
6e4f990
merge v7
bbetts-godaddy Apr 9, 2024
d47662e
fix lint error in winston package
bbetts-godaddy Apr 11, 2024
4eb6479
merge v7
bbetts-godaddy Jul 30, 2024
2ce0133
run npm ci
bbetts-godaddy Aug 5, 2024
179ea81
merge v7
bbetts-godaddy Aug 5, 2024
b317aec
fix test version
bbetts-godaddy Aug 5, 2024
0e98c9c
update type def for winston logger
bbetts-godaddy Aug 6, 2024
1663629
update nextjs fastify setup
bbetts-godaddy Aug 6, 2024
f9dbdc9
fix typecheck in fastify plugin
bbetts-godaddy Aug 8, 2024
91957d5
merge v7
bbetts-godaddy Aug 8, 2024
613b632
remove stale test and update README with appropriate swagger definitions
bbetts-godaddy Aug 13, 2024
36fe6c7
update version of @fastify/swagger-ui
bbetts-godaddy Aug 13, 2024
6a97eac
merge v7
bbetts-godaddy Aug 13, 2024
683ce93
remove middie line
bbetts-godaddy Aug 13, 2024
4c76920
merge v7
bbetts-godaddy Aug 14, 2024
1ab6f3e
update fastify type
bbetts-godaddy Aug 14, 2024
597fb25
fix typescript test and service worker type
bbetts-godaddy Aug 14, 2024
df16688
update type for cachekeys
bbetts-godaddy Aug 14, 2024
fb959dd
remove fastify specific logger methods
bbetts-godaddy Aug 14, 2024
f03fbe6
create util for aligning fastify logger
bbetts-godaddy Aug 14, 2024
2d2d189
use fallback map instead of log levels
bbetts-godaddy Aug 16, 2024
06f5e63
merge v7 and update swagger type
bbetts-godaddy Aug 16, 2024
a8cc9f0
merge v7
bbetts-godaddy Aug 19, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,672 changes: 707 additions & 965 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions packages/gasket-plugin-fastify/lib/create-servers.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
/// <reference types="@gasket/plugin-https" />
/// <reference types="@gasket/plugin-logger" />

const { alignLogger } = require('./utils');

/**
* Create the Fastify instance and setup the lifecycle hooks.
* Fastify is compatible with express middleware out of the box, so we can
Expand All @@ -10,7 +12,8 @@
// eslint-disable-next-line max-statements
module.exports = async function createServers(gasket, serverOpts) {
const fastify = require('fastify');
const { config, logger } = gasket;

const { config } = gasket;
const {
fastify: {
routes,
Expand All @@ -19,8 +22,10 @@ module.exports = async function createServers(gasket, serverOpts) {
http2
} = config;

const fastifyLogger = alignLogger(gasket.logger);

// @ts-ignore
const app = fastify({ logger, trustProxy, http2 });
const app = fastify({ logger: fastifyLogger, trustProxy, http2 });

// allow consuming apps to directly append options to their server
await gasket.exec('fastify', app);
Expand All @@ -35,6 +40,7 @@ module.exports = async function createServers(gasket, serverOpts) {
}

const postRenderingStacks = (await gasket.exec('errorMiddleware')).filter(Boolean);
// @ts-ignore
postRenderingStacks.forEach((stack) => app.use(stack));

return {
Expand Down
17 changes: 14 additions & 3 deletions packages/gasket-plugin-fastify/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import type { MaybeAsync, MaybeMultiple, Plugin } from '@gasket/core';
import { Logger } from '@gasket/plugin-logger';
import type {
FastifyInstance,
FastifyRequest,
FastifyReply,
FastifyServerOptions
} from 'fastify';
import { Http2SecureServer, Http2ServerRequest, Http2ServerResponse } from 'http2'

export type AppRoutes = Array<MaybeAsync<(app: FastifyInstance) => void>>;

Expand All @@ -20,7 +22,7 @@ declare module '@gasket/core' {
/** Trust proxy configuration */
trustProxy?: FastifyServerOptions['trustProxy'];
/** Glob pattern for source files setting up fastify routes */
routes?: Array<MaybeAsync<(app: FastifyInstance) => void>>;
routes?: Array<MaybeAsync<(app: FastifyInstance<Http2SecureServer, Http2ServerRequest, Http2ServerResponse>) => void>>;
};
/** Middleware configuration */
middleware?: {
Expand All @@ -47,13 +49,22 @@ declare module '@gasket/core' {

export interface HookExecTypes {
middleware(
fastify: Fastify
app: FastifyInstance<Http2SecureServer, Http2ServerRequest, Http2ServerResponse>
): MaybeAsync<MaybeMultiple<Handler> & { paths?: (string | RegExp)[] }>;
fastify(fastify: FastifyInstance): MaybeAsync<void>;
fastify(app: FastifyInstance<Http2SecureServer, Http2ServerRequest, Http2ServerResponse>): MaybeAsync<void>;
errorMiddleware(): MaybeAsync<MaybeMultiple<ErrorHandler>>;
}
}

type FastifyLogger = Logger & {
trace?: () => MaybeAsync<any>,
fatal?: () => MaybeAsync<any>
}

export function alignLogger(
logger: Logger
): FastifyLogger

declare module 'create-gasket-app' {
export interface CreateContext {
/** Flag indicating if API app is enabled */
Expand Down
25 changes: 25 additions & 0 deletions packages/gasket-plugin-fastify/lib/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/* eslint-disable no-console */
const fallbackMap = {
fatal: 'error',
trace: 'debug'
};

/**
* A helper function to ensure that all the required log levels
* for a Fastify server are present.
* @type {import('./index').alignLogger}
*/
function alignLogger(logger) {
const fastifyLogger = logger;
['fatal', 'trace'].map(level => {
if (!logger[level]) {
fastifyLogger[level] = logger[fallbackMap[level]];
}
});

return fastifyLogger;
}

module.exports = {
alignLogger
};
5 changes: 3 additions & 2 deletions packages/gasket-plugin-fastify/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,13 @@
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-unicorn": "^55.0.0",
"fastify": "^3.3.0",
"fastify": "^4.28.1",
"http2": "^3.3.7",
"jest": "^29.7.0",
"typescript": "^5.4.5"
},
"peerDependencies": {
"fastify": "^3.0.0"
"fastify": "^3 || ^4"
},
"eslintConfig": {
"extends": [
Expand Down
2 changes: 1 addition & 1 deletion packages/gasket-plugin-fastify/test/plugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ describe('create', () => {
expectCreatedWith(({ pkg }) => {
expect(pkg.add).toHaveBeenCalledWith('dependencies',
expect.objectContaining({
fastify: '^3.3.0'
fastify: '^4.28.1'
}));
})
);
Expand Down
4 changes: 4 additions & 0 deletions packages/gasket-plugin-logger/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,16 @@ jest.spyOn(console, 'error').mockImplementation(() => {});
jest.spyOn(console, 'warn').mockImplementation(() => {});
jest.spyOn(console, 'info').mockImplementation(() => {});
jest.spyOn(console, 'debug').mockImplementation(() => {});
jest.spyOn(console, 'trace').mockImplementation(() => {});

// Mock logger object
const mockLogger = {
debug: jest.fn(),
error: jest.fn(),
info: jest.fn(),
warn: jest.fn(),
fatal: jest.fn(),
trace: jest.fn(),
child: jest.fn()
};

Expand Down Expand Up @@ -46,6 +49,7 @@ describe('@gasket/plugin-logger', () => {
expect(gasket.logger).toEqual(fakeLogger);
});

// eslint-disable-next-line max-statements
it('should set logger to default if no loggers are hooked', async () => {
gasket.execSync.mockReturnValue([]);

Expand Down
7 changes: 4 additions & 3 deletions packages/gasket-plugin-middleware/lib/internal.d.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
import { Gasket } from '@gasket/core';
import type { Application as ExpressApp } from 'express';
import type { FastifyInstance as FastifyApp } from 'fastify';
import type { Http2SecureServer, Http2ServerRequest, Http2ServerResponse } from 'http2';

export function applyCookieParser(
app: ExpressApp | FastifyApp,
app: ExpressApp | FastifyApp<Http2SecureServer, Http2ServerRequest, Http2ServerResponse>,
middlewarePattern: RegExp
): void;

export function applyCompression(
app: ExpressApp | FastifyApp,
app: ExpressApp | FastifyAppFastifyApp<Http2SecureServer, Http2ServerRequest, Http2ServerResponse>,
compressionConfig: boolean
): void;

export function executeMiddlewareLifecycle(
gasket: Gasket,
app: ExpressApp | FastifyApp,
app: ExpressApp | FastifyAppFastifyApp<Http2SecureServer, Http2ServerRequest, Http2ServerResponse>,
middlewarePattern: RegExp
): void;
1 change: 1 addition & 0 deletions packages/gasket-plugin-middleware/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-unicorn": "^55.0.0",
"http2": "^3.3.7",
"jest": "^29.7.0",
"typescript": "^5.4.5"
},
Expand Down
12 changes: 6 additions & 6 deletions packages/gasket-plugin-nextjs/lib/fastify.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ module.exports = {
},
/** @type {import('@gasket/core').HookHandler<'fastify'>} */
handler: async function fastify(gasket, fastifyApp) {
const { exec } = gasket;

const app = await setupNextApp(gasket);

fastifyApp.decorate(['buildId', app.name].filter(Boolean).join('/'), {
getter() {
return app.buildId;
}
});
fastifyApp.decorate(
['buildId', app.name].filter(Boolean).join('/'), app.buildId
);

await gasket.exec('nextFastify', { next: app, fastify: fastifyApp });
await exec('nextFastify', { next: app, fastify: fastifyApp });

// TODO: Evaluate fix for this in Fastify4
fastifyApp.addHook('onResponse', function setNextLocale(req, res, next) {
Expand Down
2 changes: 1 addition & 1 deletion packages/gasket-plugin-nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@
"homepage": "https://github.com/godaddy/gasket/tree/main/packages/gasket-plugin-nextjs",
"dependencies": {
"@gasket/plugin-webpack": "7.0.0-next.56",
"fastify": "^4.26.2"
"fastify": "^4.28.1"
},
"devDependencies": {
"@babel/preset-react": "^7.23.3",
Expand Down
5 changes: 3 additions & 2 deletions packages/gasket-plugin-service-worker/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { IncomingMessage, OutgoingMessage, ServerResponse } from 'http';
import type { Request, Response } from 'express';
import type { FastifyRequest, FastifyReply } from 'fastify';
import type { FastifyRequest, FastifyReply, RouteHandlerMethod } from 'fastify';
import type { Options } from 'lru-cache';
import type { MinifyOptions } from 'uglify-js';
import type { MaybeAsync, MaybeMultiple, Plugin } from '@gasket/core';
import type { Http2SecureServer, Http2ServerRequest, Http2ServerResponse } from 'http2';

export interface ServiceWorkerConfig {
/** Name the service worker file. Default is /sw.js */
Expand Down Expand Up @@ -78,7 +79,7 @@ declare module 'express' {
}
}

export async function configureEndpoint(gasket: Gasket): (req: Request | FastifyRequest, res: Response | FastifyReply) => Promise<void>;
export async function configureEndpoint(gasket: Gasket): RouteHandlerMethod<Http2SecureServer, Http2ServerRequest, Http2ServerResponse> | Application<Record<string, any>>;

export async function serviceWorkerMiddleware(
req: Request & {
Expand Down
5 changes: 3 additions & 2 deletions packages/gasket-plugin-swagger/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export default makeGasket({
JSDocs in the configured files. See the [swagger-jsdocs] options for what is
supported.
- **`ui`** - (object) Optional custom UI options. See
[swagger-ui-express] / [fastify-swagger] options for what is supported.
[swagger-ui-express] options for what is supported.
- **`uiConfig`** - (object) Optional custom UI options. Only for use with Fastify. See [@fastify/swagger-ui] options for what is supported.

#### Example from JSDocs

Expand Down Expand Up @@ -84,5 +85,5 @@ export default makeGasket({

<!-- LINK -->
[swagger-ui-express]: https://github.com/scottie1984/swagger-ui-express
[fasitfy-swagger]: https://github.com/fastify/fastify-swagger
[@fastify/swagger-ui]: https://github.com/fastify/fastify-swagger-ui
[swagger-jsdocs]: https://github.com/Surnet/swagger-jsdoc/blob/master/docs/GETTING-STARTED.md
5 changes: 5 additions & 0 deletions packages/gasket-plugin-swagger/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { Plugin } from '@gasket/core';
import type { Options } from 'swagger-jsdoc'
import type { SwaggerUiOptions } from 'swagger-ui-express';
import type { FastifySwaggerUiOptions } from '@fastify/swagger-ui';

type SwaggerOptions = {
/** Target swagger spec file, either json or yaml. (Default:
Expand All @@ -18,6 +19,10 @@ type SwaggerOptions = {
/** Optional custom UI options. See swagger-ui-express options for what is
* supported. */
ui?: SwaggerUiOptions

/** Optional custom UI options (Fastify Only). See @fastify/swagger-ui options for what is
* supported. */
uiOptions?: FastifySwaggerUiOptions
}

declare module '@gasket/core' {
Expand Down
14 changes: 8 additions & 6 deletions packages/gasket-plugin-swagger/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,21 @@ const plugin = {
},
handler: async function fastify(gasket, app) {
const { swagger, root } = gasket.config;
const { ui = {}, apiDocsRoute, definitionFile } = swagger;
const { uiOptions = {}, apiDocsRoute = '/api-docs', definitionFile } = swagger;

const swaggerSpec = await loadSwaggerSpec(
root,
definitionFile,
gasket.logger
);

// @ts-ignore
app.register(require('@fastify/swagger'), {
prefix: apiDocsRoute,
swagger: swaggerSpec,
uiConfig: ui
await app.register(require('@fastify/swagger'), {
swagger: swaggerSpec
});

await app.register(require('@fastify/swagger-ui'), {
routePrefix: apiDocsRoute,
...uiOptions
});
}
},
Expand Down
5 changes: 3 additions & 2 deletions packages/gasket-plugin-swagger/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@
},
"homepage": "https://github.com/godaddy/gasket/tree/main/packages/gasket-plugin-swagger",
"dependencies": {
"@fastify/swagger": "^6.0.0",
"@fastify/swagger": "^8.14.0",
"@fastify/swagger-ui": "^4.0.1",
"@types/swagger-ui-express": "^4.1.6",
"express": "^4.18.2",
"swagger-jsdoc": "^4.0.0",
Expand All @@ -53,7 +54,7 @@
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-json": "^3.1.0",
"eslint-plugin-unicorn": "^55.0.0",
"fastify": "^3.0.0",
"fastify": "^4.28.1",
"jest": "^29.7.0",
"typescript": "^5.4.5"
},
Expand Down
17 changes: 6 additions & 11 deletions packages/gasket-plugin-swagger/test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ jest.mock('util', () => {
promisify: (f) => f
};
});

jest.mock('/path/to/app/swagger.json', () => ({ data: true }), {
virtual: true
});

const fastify = require('fastify')({ logger: true });
const { name, version, description } = require('../package');

describe('Swagger Plugin', function () {
Expand Down Expand Up @@ -254,18 +254,13 @@ describe('Swagger Plugin', function () {

it('sets the api docs route', async function () {
await plugin.hooks.fastify.handler(mockGasket, mockApp);
expect(mockApp.register).toHaveBeenCalledTimes(2);
expect(mockApp.register).toHaveBeenCalledWith(expect.any(Function), {
prefix: '/api-docs',
swagger: { data: true },
uiConfig: {}
routePrefix: '/api-docs'
});
expect(mockApp.register).toHaveBeenCalledWith(expect.any(Function), {
swagger: { data: true }
});
});

it('adds new routes to swagger paths', async function () {
await plugin.hooks.fastify.handler(mockGasket, fastify);
fastify.get('/hello-world', () => { });
await fastify.ready();
expect(fastify.swagger().paths).toHaveProperty('/hello-world');
});
});

Expand Down
10 changes: 9 additions & 1 deletion packages/gasket-plugin-winston/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import type { LoggerOptions } from 'winston';
import type { LoggerOptions, LeveledLogMethod } from 'winston';

declare module 'winston' {
export interface Logger {
fatal: LeveledLogMethod,
warn: LeveledLogMethod,
trace: LeveledLogMethod
}
}

declare module '@gasket/core' {
export interface GasketConfig {
Expand Down
3 changes: 2 additions & 1 deletion packages/gasket-plugin-winston/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
/// <reference types="create-gasket-app" />
/// <reference types="@gasket/plugin-metadata" />

const { createLogger, format, transports } = require('winston');
const { createLogger, format, transports, config: winstonConfig } = require('winston');
const {
name,
version,
Expand Down Expand Up @@ -49,6 +49,7 @@ const plugin = {
format:
config.winston?.format ??
format.combine(format.splat(), format.json()),
levels: Object.assign({ fatal: 0, warn: 4, trace: 7 }, winstonConfig.syslog.levels),
exitOnError: true
});
},
Expand Down
Loading
Loading