UNPKG

serverless-offline

Version:

Emulate AWS λ and API Gateway locally when developing your Serverless project

83 lines (75 loc) 3.23 kB
'use strict'; const jsonPath = require('./jsonPath'); const jsEscapeString = require('js-string-escape'); const isPlainObject = require('lodash').isPlainObject; function escapeJavaScript(x) { if (typeof x === 'string') return jsEscapeString(x).replace(/\\n/g, '\n'); // See #26, else if (isPlainObject(x)) { const result = {}; for (let key in x) { // eslint-disable-line prefer-const result[key] = jsEscapeString(x[key]); } return JSON.stringify(result); // Is this really how APIG does it? } else if (typeof x.toString === 'function') return escapeJavaScript(x.toString()); return x; } /* Returns a context object that mocks APIG mapping template reference http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html */ module.exports = function createVelocityContext(request, options, payload) { const path = x => jsonPath(payload || {}, x); const authPrincipalId = request.auth && request.auth.credentials && request.auth.credentials.user; // Capitalize request.headers as NodeJS use lowercase headers // however API Gateway always pass capitalize headers const headers = {}; for (let key in request.headers) { // eslint-disable-line prefer-const headers[key.replace(/((?:^|-)[a-z])/g, x => x.toUpperCase())] = request.headers[key]; } return { context: { apiId: 'offlineContext_apiId', authorizer: { principalId: authPrincipalId || process.env.PRINCIPAL_ID || 'offlineContext_authorizer_principalId', // See #24 }, httpMethod: request.method.toUpperCase(), identity: { accountId: 'offlineContext_accountId', apiKey: 'offlineContext_apiKey', caller: 'offlineContext_caller', cognitoAuthenticationProvider: 'offlineContext_cognitoAuthenticationProvider', cognitoAuthenticationType: 'offlineContext_cognitoAuthenticationType', sourceIp: request.info.remoteAddress, user: 'offlineContext_user', userAgent: request.headers['user-agent'] || '', userArn: 'offlineContext_userArn', }, requestId: `offlineContext_requestId_${Math.random().toString(10).slice(2)}`, resourceId: 'offlineContext_resourceId', resourcePath: request.route.path, stage: options.stage, }, input: { body: payload, // Not a string yet, todo json: x => JSON.stringify(path(x)), params: x => typeof x === 'string' ? request.params[x] || request.query[x] || headers[x] : { path: Object.assign({}, request.params), querystring: Object.assign({}, request.query), header: headers, }, path, }, stageVariables: options.stageVariables, util: { escapeJavaScript, urlEncode: encodeURI, urlDecode: decodeURI, base64Encode: x => new Buffer(x.toString(), 'binary').toString('base64'), base64Decode: x => new Buffer(x.toString(), 'base64').toString('binary'), parseJson: JSON.parse, }, }; };