Skip to content

Commit

Permalink
Documentation & type fixes (#637)
Browse files Browse the repository at this point in the history
* Documentation & type fixes

- Create alternative for misnamed `excludedRoutesRegex` config property
- Document `routes` config property
- Include typing support for these

* Add deprecation warning

* Fix test that deprecation logging broke
  • Loading branch information
jpage-godaddy authored Dec 15, 2023
1 parent 00d5815 commit f23a394
Show file tree
Hide file tree
Showing 7 changed files with 430 additions and 405 deletions.
733 changes: 343 additions & 390 deletions package-lock.json

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions packages/gasket-plugin-express/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# `@gasket/plugin-express`

- Add missing type definition for `routes` config property
- Add `middlewareInclusionRegex` config property, deprecating `excludedRoutesRegex`

### 6.41.2

- Fix ordering of error middlewares so they come after API routes
Expand Down
7 changes: 5 additions & 2 deletions packages/gasket-plugin-express/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ All the configurations for the plugin are added under `express` in the config:

- `compression`: true by default. Can be set to false if applying compression
differently.
- `excludedRoutesRegex`: Routes to be excluded based on a regex
- `excludedRoutesRegex`: (deprecated) renamed to more correct `middlewareInclusionRegex`.
- `middlewareInclusionRegex`: RegExp filter to apply toward request URLs to determine when Gasket middleware will run. You can use negative lookahead patterns to exclude routes like static resource paths.
- `routes`: [Glob pattern](https://github.com/isaacs/node-glob#glob-primer) for source files exporting route-defining functions. These functions will be passed the express `app` object, and therein they can attach handlers and middleware.

#### Example configuration

Expand All @@ -50,7 +52,8 @@ module.exports = {
},
express: {
compression: false,
excludedRoutesRegex: /^(?!\/_next\/)/
routes: 'api/*.js',
middlewareInclusionRegex: /^(?!\/_next\/)/,
}
}
```
Expand Down
6 changes: 6 additions & 0 deletions packages/gasket-plugin-express/lib/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import type { Application, ErrorRequestHandler, Handler } from 'express';

declare module '@gasket/engine' {
export interface GasketConfig {
/** Whether responses are compressed (true by default) */
compression?: boolean,
/** Filter for which request URLs invoke Gasket middleware */
middlewareInclusionRegex?: RegExp,
/** Glob pattern for source files setting up express routes */
routes?: string,
/** @deprecated */
excludedRoutesRegex?: RegExp
}

Expand Down
48 changes: 37 additions & 11 deletions packages/gasket-plugin-express/lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,25 @@ module.exports = {
const cookieParser = require('cookie-parser');
const compression = require('compression');

const { config } = gasket;
const { root, express: { routes } = {}, http2, middleware: middlewareConfig } = config;
const excludedRoutesRegex = config.express && config.express.excludedRoutesRegex;
const { config, logger } = gasket;
const {
root,
express: {
routes,
excludedRoutesRegex,
middlewareInclusionRegex,
compression: compressionConfig = true
} = {},
http2,
middleware: middlewareConfig
} = config;

if (excludedRoutesRegex) {
// eslint-disable-next-line no-console
const warn = logger ? logger.warning : console.warn;
warn('DEPRECATED express config `excludedRoutesRegex` - use `middlewareInclusionRegex`');
}

const app = http2 ? require('http2-express-bridge')(express) : express();

if (http2) {
Expand All @@ -66,13 +82,13 @@ module.exports = {
});
}

if (excludedRoutesRegex) {
app.use(excludedRoutesRegex, cookieParser());
const middlewarePattern = middlewareInclusionRegex || excludedRoutesRegex;
if (middlewarePattern) {
app.use(middlewarePattern, cookieParser());
} else {
app.use(cookieParser());
}

const { compression: compressionConfig = true } = config.express || {};
if (compressionConfig) {
app.use(compression());
}
Expand All @@ -87,8 +103,8 @@ module.exports = {
const mwConfig = middlewareConfig.find(mw => mw.plugin === pluginName);
if (mwConfig) {
middleware.paths = mwConfig.paths;
if (excludedRoutesRegex) {
middleware.paths.push(excludedRoutesRegex);
if (middlewarePattern) {
middleware.paths.push(middlewarePattern);
}
}
}
Expand All @@ -101,8 +117,8 @@ module.exports = {
const { paths } = layer;
if (paths) {
app.use(paths, layer);
} else if (excludedRoutesRegex) {
app.use(excludedRoutesRegex, layer);
} else if (middlewarePattern) {
app.use(middlewarePattern, layer);
} else {
app.use(layer);
}
Expand Down Expand Up @@ -171,10 +187,20 @@ module.exports = {
description: 'Automatic compression',
type: 'boolean',
default: true
}, {
name: 'express.routes',
link: 'README.md#configuration',
description: 'Glob pattern for route setup code',
type: 'string'
}, {
name: 'express.excludedRoutesRegex',
link: 'README.md#configuration',
description: 'Routes to be excluded based on a regex'
description: 'Routes to be included for Gasket middleware, based on a regex',
deprecated: true
}, {
name: 'express.middlewareInclusionRegex',
link: 'README.md#configuration',
description: 'Routes to be included for Gasket middleware, based on a regex'
}]
};
}
Expand Down
16 changes: 14 additions & 2 deletions packages/gasket-plugin-express/test/plugin.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ describe('createServers', () => {

gasket = {
middleware: {},
logger: {},
logger: {
warning: jest.fn()
},
config: {},
exec: jest.fn().mockImplementation((lifecycle, ...args) => lifecycles[lifecycle](args)),
execApply: sandbox.mockImplementation(async function (lifecycle, fn) {
Expand Down Expand Up @@ -176,7 +178,17 @@ describe('createServers', () => {

const cookieParserUsage = findCall(
app.use,
(path, mw) => mw === cookieParserMiddleware);
(url, mw) => mw === cookieParserMiddleware);
expect(cookieParserUsage).not.toBeNull();
});

it('supports the deprecated property name', async () => {
gasket.config.express = { middlewareInclusionRegex: /^(?!\/_next\/)/ };
await plugin.hooks.createServers(gasket, {});

const cookieParserUsage = findCall(
app.use,
(url, mw) => mw === cookieParserMiddleware);
expect(cookieParserUsage).not.toBeNull();
});

Expand Down
22 changes: 22 additions & 0 deletions packages/gasket-typescript-tests/test/plugin-express.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,28 @@ describe('@gasket/plugin-express', () => {
};
});

it('adds an middlewareInclusionRegex config property', () => {
const badConfig: GasketConfigFile = {
// @ts-expect-error
middlewareInclusionRegex: '/api/*'
};

const goodConfig: GasketConfigFile = {
middlewareInclusionRegex: /^(?!\/_next\/)/
};
});

it('adds an routes config property', () => {
const badConfig: GasketConfigFile = {
// @ts-expect-error
routes: /^\/api\/\.*$/
};

const goodConfig: GasketConfigFile = {
routes: '/api/*.js'
};
});

it('declares the middleware lifecycle', () => {
const hook: Hook<'middleware'> = (gasket: Gasket, app) => {
return [];
Expand Down

0 comments on commit f23a394

Please sign in to comment.