diff --git a/__tests__/integration.js b/__tests__/integration.js index 698ffebf..3f2e495d 100644 --- a/__tests__/integration.js +++ b/__tests__/integration.js @@ -22,13 +22,13 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo serverlessExpressInstance = serverlessExpress({ app }) }) - test('handler returns promise', () => { + test('serverlessExpressInstance returns promise', () => { const event = makeEvent({ eventSourceName, path: '/', httpMethod: 'GET' }) - const response = serverlessExpressInstance.handler(event) + const response = serverlessExpressInstance(event) expect(response.then).toBeTruthy() }) @@ -452,7 +452,7 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo // expect(customLogger.debug.mock.calls.length).toBe(0) }) - test('legacy/deprecated usage', async () => { + test('legacy/deprecated createServer', async () => { const serverlessExpressMiddleware = require('../src/middleware') app = express() router = express.Router() @@ -484,4 +484,60 @@ describe.each(EACH_MATRIX)('%s:%s: integration tests', (eventSourceName, framewo }) expect(response).toEqual(expectedResponse) }) + + test('legacy/deprecated handler', async () => { + const serverlessExpressMiddleware = require('../src/middleware') + router.use(serverlessExpressMiddleware.eventContext()) + router.get('/users', (req, res) => { + const { event } = req.apiGateway + const eventPath = event.path || event.rawPath || event.Records[0].cf.request.uri + res.json({ + path: eventPath + }) + }) + const event = makeEvent({ + eventSourceName, + path: '/users', + httpMethod: 'GET' + }) + const response = await serverlessExpressInstance.handler(event) + const expectedResponse = makeResponse({ + eventSourceName, + body: JSON.stringify({ path: '/users' }), + multiValueHeaders: { + 'content-length': ['17'], + etag: ['W/"11-eM8YArY+qNwdvTL2ppeAaFc4Oq8"'] + }, + statusCode: 200 + }) + expect(response).toEqual(expectedResponse) + }) + + test('legacy/deprecated proxy', async () => { + const serverlessExpressMiddleware = require('../src/middleware') + router.use(serverlessExpressMiddleware.eventContext()) + router.get('/users', (req, res) => { + const { event } = req.apiGateway + const eventPath = event.path || event.rawPath || event.Records[0].cf.request.uri + res.json({ + path: eventPath + }) + }) + const event = makeEvent({ + eventSourceName, + path: '/users', + httpMethod: 'GET' + }) + const response = await serverlessExpressInstance.proxy({ event }) + const expectedResponse = makeResponse({ + eventSourceName, + body: JSON.stringify({ path: '/users' }), + multiValueHeaders: { + 'content-length': ['17'], + etag: ['W/"11-eM8YArY+qNwdvTL2ppeAaFc4Oq8"'] + }, + statusCode: 200 + }) + expect(response).toEqual(expectedResponse) + }) }) diff --git a/src/configure.d.ts b/src/configure.d.ts index 045177bb..6bbb86ea 100644 --- a/src/configure.d.ts +++ b/src/configure.d.ts @@ -1,8 +1,17 @@ import { RequestListener } from "http" import { Handler } from "aws-lambda" import Logger from "./logger" -import ProxyParams from "./proxy" +interface ProxyParams { + app: RequestListener, + binaryMimeTypes?: string[], + binarySettings?: BinarySettings +} + +interface BinarySettings { + isBinary?: Function | boolean, + contentTypes?: string[] +} interface ConfigureParams { app: RequestListener, binaryMimeTypes?: string[], @@ -22,4 +31,6 @@ interface ConfigureResult { declare function configure(configureParams: ConfigureParams): ConfigureResult +// declare function proxy(proxyParams: ProxyParams): Promise + export default configure \ No newline at end of file diff --git a/src/configure.js b/src/configure.js index 08138814..db9e9672 100644 --- a/src/configure.js +++ b/src/configure.js @@ -1,6 +1,21 @@ -const { getFramework } = require('./frameworks') +const util = require('util') const logger = require('./logger') -const proxy = require('./proxy') +const { setCurrentInvoke } = require('./current-invoke') +const { getEventSource } = require('./event-sources') +const { getEventSourceNameBasedOnEvent } = require('./event-sources/utils') +const { getFramework } = require('./frameworks') +const makeResolver = require('./make-resolver') +const { forwardRequestToNodeServer, respondToEventSourceWithError } = require('./transport') + +const DEFAULT_BINARY_ENCODINGS = ['gzip', 'deflate', 'br'] +const DEFAULT_BINARY_CONTENT_TYPES = ['image/*'] + +function getDefaultBinarySettings (deprecatedBinaryMimeTypes) { + return { + contentTypes: deprecatedBinaryMimeTypes || DEFAULT_BINARY_CONTENT_TYPES, + contentEncodings: DEFAULT_BINARY_ENCODINGS + } +} function configure ({ app: configureApp, @@ -12,44 +27,93 @@ function configure ({ resolutionMode: configureResolutionMode = 'PROMISE', eventSourceName: configureEventSourceName, eventSource: configureEventFns, - respondWithErrors: configureRespondWithErrors = process.env.NODE_ENV === 'development', - proxy: configureProxy = ({ - app: configureProxyApp = configureApp, - framework: configureProxyFramework = configureFramework, + respondWithErrors: configureRespondWithErrors = process.env.NODE_ENV === 'development' +} = {}) { + function proxy ({ + app = configureApp, + framework = configureFramework, + event = {}, + context = {}, + callback = null, resolutionMode = configureResolutionMode, - event, - context, - callback, - eventSourceName = configureEventSourceName, + eventSourceName = configureEventSourceName || getEventSourceNameBasedOnEvent({ event }), binaryMimeTypes = configureBinaryMimeTypes, - binarySettings = configureBinarySettings, - eventSource = configureEventFns, + binarySettings = configureBinarySettings || getDefaultBinarySettings(binaryMimeTypes), + eventSource = configureEventFns || getEventSource({ eventSourceName }), log = configureLog, respondWithErrors = configureRespondWithErrors - } = {}) => proxy({ - app: configureProxyApp, - framework: configureProxyFramework, - event, - context, - resolutionMode, - callback, - eventSourceName, - binaryMimeTypes, - binarySettings, - eventSource, - log, - respondWithErrors - }), - handler: configureHandler = (event, context, callback) => configureProxy({ - event, - context, - callback - }) -} = {}) { - configureHandler.handler = configureHandler - configureHandler.proxy = configureProxy - configureHandler.log = configureLog - return configureHandler + }) { + log.debug('SERVERLESS_EXPRESS:PROXY', { + event: util.inspect(event, { depth: null }), + context: util.inspect(context, { depth: null }), + resolutionMode, + eventSourceName, + binarySettings, + respondWithErrors + }) + + if (binaryMimeTypes) { + console.warn('[DEPRECATION NOTICE] { binaryMimeTypes: [] } is deprecated. base64 encoding is now automatically determined based on response content-type and content-encoding. If you need to manually set binary content types, instead, use { binarySettings: { contentTypes: [] } }') + } + + setCurrentInvoke({ event, context }) + return new Promise((resolve, reject) => { + const promise = { + resolve, + reject + } + const resolver = makeResolver({ + context, + callback, + promise, + resolutionMode + }) + + try { + forwardRequestToNodeServer({ + app, + framework, + event, + context, + resolver, + eventSourceName, + binarySettings, + eventSource, + log + }) + } catch (error) { + respondToEventSourceWithError({ + error, + resolver, + log, + respondWithErrors, + eventSource + }) + } + }) + } + + function handler (event, context, callback) { + return proxy({ + event, + context, + callback + }) + } + + handler.handler = (...params) => { + console.warn('[DEPRECATION NOTICE] You\'re using the deprecated `serverlessExpress({...}).handler({...})` method. This will be removed in a future version of @vendia/serverless-express. Instead, simply return `serverlessExpress({...})` as your handler.') + return handler(...params) + } + + handler.proxy = (...params) => { + console.warn('[DEPRECATION NOTICE] You\'re using the deprecated `serverlessExpress({...}).proxy({...})` method. This will be removed in a future version of @vendia/serverless-express. Instead, simply return `serverlessExpress({...})` as your handler.') + return proxy(...params) + } + + handler.log = configureLog + + return handler } module.exports = configure diff --git a/src/index.js b/src/index.js index 164ad408..e33efd3f 100644 --- a/src/index.js +++ b/src/index.js @@ -8,7 +8,7 @@ module.exports.configure = configure // Legacy/deprecated: function createServer (app, serverListenCallback, binaryMimeTypes) { - console.warn('You\'re using the deprecated createServer method that will be removed in the next major version. See https://github.com/vendia/serverless-express/blob/mainline/UPGRADE.md to upgrade.') + console.warn('[DEPRECATION NOTICE] You\'re using the deprecated createServer method that will be removed in the next major version. See https://github.com/vendia/serverless-express/blob/mainline/UPGRADE.md to upgrade.') if (serverListenCallback) { throw new Error('serverListenCallback is no longer supported.') diff --git a/src/proxy.d.ts b/src/proxy.d.ts deleted file mode 100644 index f68d076b..00000000 --- a/src/proxy.d.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { RequestListener } from "http" - -interface ProxyParams { - app: RequestListener, - binaryMimeTypes?: string[], - binarySettings?: BinarySettings -} - -interface BinarySettings { - isBinary?: Function | boolean, - contentTypes?: string[] -} - -declare function proxy(proxyParams: ProxyParams): Promise - -export default ProxyParams diff --git a/src/proxy.js b/src/proxy.js deleted file mode 100644 index 32076ce8..00000000 --- a/src/proxy.js +++ /dev/null @@ -1,83 +0,0 @@ -const util = require('util') -const { setCurrentInvoke } = require('./current-invoke') -const { getEventSource } = require('./event-sources') -const { getEventSourceNameBasedOnEvent } = require('./event-sources/utils') -const { getFramework } = require('./frameworks') -const makeResolver = require('./make-resolver') -const { forwardRequestToNodeServer, respondToEventSourceWithError } = require('./transport') - -const DEFAULT_BINARY_ENCODINGS = ['gzip', 'deflate', 'br'] -const DEFAULT_BINARY_CONTENT_TYPES = ['image/*'] - -function getDefaultBinarySettings (deprecatedBinaryMimeTypes) { - return { - contentTypes: deprecatedBinaryMimeTypes || DEFAULT_BINARY_CONTENT_TYPES, - contentEncodings: DEFAULT_BINARY_ENCODINGS - } -} - -function proxy ({ - app, - framework = getFramework({ app }), - event = {}, - context = {}, - callback = null, - resolutionMode = 'PROMISE', - eventSourceName = getEventSourceNameBasedOnEvent({ event }), - binaryMimeTypes, - binarySettings = getDefaultBinarySettings(binaryMimeTypes), - eventSource = getEventSource({ eventSourceName }), - log, - respondWithErrors -}) { - log.debug('SERVERLESS_EXPRESS:PROXY', { - event: util.inspect(event, { depth: null }), - context: util.inspect(context, { depth: null }), - resolutionMode, - eventSourceName, - binarySettings, - respondWithErrors - }) - - if (binaryMimeTypes) { - console.warn('{ binaryMimeTypes: [] } is deprecated. base64 encoding is now automatically determined based on response content-type and content-encoding. If you need to manually set binary content types, instead, use { binarySettings: { contentTypes: [] } }') - } - - setCurrentInvoke({ event, context }) - return new Promise((resolve, reject) => { - const promise = { - resolve, - reject - } - const resolver = makeResolver({ - context, - callback, - promise, - resolutionMode - }) - - try { - forwardRequestToNodeServer({ - app, - framework, - event, - context, - resolver, - eventSourceName, - binarySettings, - eventSource, - log - }) - } catch (error) { - respondToEventSourceWithError({ - error, - resolver, - log, - respondWithErrors, - eventSource - }) - } - }) -} - -module.exports = proxy