New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

serverless-offline

Package Overview
Dependencies
Maintainers
1
Versions
407
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

serverless-offline - npm Package Compare versions

Comparing version 2.2.7 to 2.2.8

6

package.json
{
"name": "serverless-offline",
"version": "2.2.7",
"version": "2.2.8",
"description": "Emulate AWS λ and API Gateway locally when developing your Serverless project",

@@ -48,8 +48,8 @@ "main": "src/index.js",

"coffee-script": "^1.10.0",
"hapi": "^13.2.2",
"hapi": "^13.3.0",
"js-string-escape": "^1.0.1",
"jsonpath-plus": "^0.15.0",
"lodash.isplainobject": "^4.0.3",
"lodash.isplainobject": "^4.0.4",
"velocityjs": "^0.7.5"
}
}
'use strict';
/*
Mimicks the lambda context object
http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
Mimicks the lambda context object
http://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-context.html
*/

@@ -7,0 +7,0 @@ module.exports = function createLambdaContext(fun, cb) {

'use strict';
const jsonPath = require('./jsonPath');
const escapeJavaScript = require('js-string-escape');
// const escapeJavaScript = require('js-string-escape');
const escapeJavaScript = require('jsesc');

@@ -6,0 +7,0 @@ /*

'use strict';
/*
I'm against monolithic code like this file but splitting it induces unneeded complexity
*/
module.exports = S => {
// One-line coffee-script support
require('coffee-script/register');
// Node dependencies
const fs = require('fs');
const path = require('path');
// External dependencies
const Hapi = require('hapi');
const isPlainObject = require('lodash.isplainobject');
const debugLog = require('./debugLog');
const serverlessLog = S.config && S.config.serverlessPath ?

@@ -17,2 +22,4 @@ require(path.join(S.config.serverlessPath, 'utils', 'cli')).log :

// Internal lib
const debugLog = require('./debugLog');
const jsonPath = require('./jsonPath');

@@ -36,6 +43,6 @@ const createLambdaContext = require('./createLambdaContext');

S.addAction(this.start.bind(this), {
handler: 'start',
context: 'offline', // calling 'sls offline'
contextAction: 'start', // followed by 'start'
handler: 'start', // will invoke the start method
description: 'Simulates API Gateway to call your lambda functions offline',
context: 'offline',
contextAction: 'start',
options: [

@@ -81,5 +88,6 @@ {

// Entry point for the plugin (sls offline start)
start(optionsAndData) {
// this._logAndExit(optionsAndData);
// Serverless version checking
const version = S._version;

@@ -91,12 +99,15 @@ if (!version.startsWith('0.5')) {

process.env.IS_OFFLINE = true;
this.envVars = {};
this.project = S.getProject();
this.requests = {}; // Will store the state of each request
// Internals
process.env.IS_OFFLINE = true; // Some users would like to know their environment outside of the handler
this.project = S.getProject(); // All the project data
this.requests = {}; // Maps a request id to the request's state (done: bool, timeout: timer)
this.envVars = {}; // Env vars are specific to each handler
this._setOptions();
this._registerBabel();
this._createServer();
this._createRoutes();
this._listen();
// Methods
this._setOptions(); // Will create meaningful options from cli options
this._registerBabel(); // Support for ES6
this._createServer(); // Hapijs boot
this._createRoutes(); // API Gateway emulation
this._create404Route(); // Not found handling
this._listen(); // Hapijs listen
}

@@ -117,2 +128,3 @@

// Applies defaults
this.options = {

@@ -122,4 +134,4 @@ port: userOptions.port || 3000,

stage: userOptions.stage || stagesKeys[0],
httpsProtocol: userOptions.httpsProtocol || '',
skipCacheInvalidation: userOptions.skipCacheInvalidation || false,
httpsProtocol: userOptions.httpsProtocol || '',
};

@@ -148,2 +160,3 @@

// Babel options can vary from handler to handler just like env vars
const options = isBabelRuntime ?

@@ -156,2 +169,3 @@ babelRuntimeOptions || { presets: ['es2015'] } :

// We invoke babel-register only once
if (!this.babelRegister) {

@@ -162,2 +176,3 @@ debugLog('For the first time');

// But re-set the options at each handler invocation
this.babelRegister(options);

@@ -169,2 +184,3 @@ }

// Hapijs server creation
this.server = new Hapi.Server({

@@ -181,2 +197,3 @@ connections: {

// HTTPS support
if (typeof httpsDir === 'string' && httpsDir.length > 0) connectionOptions.tls = {

@@ -187,2 +204,3 @@ key: fs.readFileSync(path.resolve(httpsDir, 'key.pem'), 'ascii'),

// Passes the configuration object to the server
this.server.connection(connectionOptions);

@@ -198,5 +216,9 @@ }

// Runtime checks
// No python :'(
// No python or Java :'(
const funRuntime = fun.runtime;
if (funRuntime !== 'nodejs' && funRuntime !== 'babel') return;
if (['nodejs', 'nodejs4.3', 'babel'].indexOf(funRuntime) === -1) {
console.log();
serverlessLog(`Warning: found unsupported runtime '${funRuntime}' for function '${fun.name}'`);
return;
}

@@ -226,3 +248,3 @@ // Templates population (with project variables)

// Add a route for each endpoint
// Adds a route for each endpoint
populatedFun.endpoints.forEach(endpoint => {

@@ -251,3 +273,3 @@

config,
handler: (request, reply) => {
handler: (request, reply) => { // Here we go
console.log();

@@ -260,3 +282,3 @@ serverlessLog(`${method} ${request.url.path} (λ: ${funName})`);

// Shared mutable state is the root of all evil
// Shared mutable state is the root of all evil they say
const requestId = Math.random().toString().slice(2);

@@ -276,5 +298,5 @@ this.requests[requestId] = { done: false };

/* ENVIRONMENT VARIABLES CONFIGURATION */
/* ENVIRONMENT VARIABLES DECLARATION */
// Clear old vars
// Clears old vars
for (let key in this.envVars) {

@@ -284,3 +306,3 @@ delete process.env[key];

// Declare new ones
// Declares new ones
this.envVars = isPlainObject(populatedFun.environment) ? populatedFun.environment : {};

@@ -297,3 +319,4 @@ for (let key in this.envVars) {

let handler;
let handler; // The lambda function
try {

@@ -304,3 +327,4 @@ if (!this.options.skipCacheInvalidation) {

for (let key in require.cache) {
// Require cache invalidation, brutal and fragile. Might cause errors, if so, please submit issue.
// Require cache invalidation, brutal and fragile.
// Might cause errors, if so please submit an issue.
if (!key.match('node_modules')) delete require.cache[key];

@@ -312,3 +336,3 @@ }

handler = require(handlerPath)[handlerParts[1]];
if (typeof handler !== 'function') throw new Error(`Serverless-offline: handler for function ${funName} is not a function`);
if (typeof handler !== 'function') throw new Error(`Serverless-offline: handler for '${funName}' is not a function`);
}

@@ -319,9 +343,10 @@ catch(err) {

/* REQUEST TEMPLATE PROCESSING (event population) */
let event = {};
/* REQUEST TEMPLATE PROCESSING (event population) */
if (requestTemplate) {
try {
debugLog('_____ REQUEST TEMPLATE PROCESSING _____');
// Velocity templating language parsing
const velocityContext = createVelocityContext(request, this.velocityContextOptions, request.payload || {});

@@ -340,11 +365,12 @@ event = renderVelocityTemplateObject(requestTemplate, velocityContext);

const lambdaContext = createLambdaContext(fun, (err, data) => {
// Everything in this block happens once the lambda function has resolved
debugLog('_____ HANDLER RESOLVED _____');
// Timeout resolving
// Timeout clearing if needed
if (this._clearTimeout(requestId)) return;
// User sould not call context.done twice
// User should not call context.done twice
if (this.requests[requestId].done) {
console.log();
serverlessLog('Warning: context.done called twice!');
serverlessLog(`Warning: context.done called twice within handler '${funName}'!`);
debugLog('requestId:', requestId);

@@ -365,4 +391,4 @@ return;

const errorMessage = err.message ? err.message.toString() : err.toString();
const errorMessage = (err.message || err).toString();
// Mocks Lambda errors

@@ -489,3 +515,2 @@ result = {

serverlessLog(`Warning: No statusCode found for response "${responseName}".`);
console.log();
}

@@ -515,2 +540,4 @@

// Now we are outside of createLambdaContext, so this happens before the handler gets called:
// We cannot use Hapijs's timeout feature because the logic above can take a significant time, so we implement it ourselves

@@ -542,2 +569,3 @@ this.requests[requestId].timeout = setTimeout(this._replyTimeout.bind(this, response, funName, funTimeout, requestId), funTimeout);

// All done, we can listen to incomming requests
_listen() {

@@ -547,6 +575,7 @@ this.server.start(err => {

console.log();
serverlessLog(`Offline listening on ${this.options.httpsProtocol ? 'https' : 'http'}://localhost:${this.options.port}`);
serverlessLog(`Offline listening on http${this.options.httpsProtocol ? 's' : ''}://localhost:${this.options.port}`);
});
}
// Bad news
_reply500(response, message, err, requestId) {

@@ -588,2 +617,21 @@

_create404Route() {
this.server.route({
method: '*',
path: '/{p*}',
config: { cors: true },
handler: (request, reply) => {
const response = reply({
statusCode: 404,
error: 'Serverless-offline: route not found.',
currentRoute: `${request.method} - ${request.path}`,
existingRoutes: this.server.table()[0].table
.filter(route => route.path !== '/{p*}') // Exclude this (404) route
.sort((a, b) => a.path <= b.path ? -1 : 1) // Sort by path
.map(route => `${route.method} - ${route.path}`), // Human-friendly result
});
response.statusCode = 404;
}
});
}
_logAndExit() {

@@ -590,0 +638,0 @@ console.log.apply(null, arguments);

@@ -6,2 +6,5 @@ 'use strict';

/*
Just a wrapper around an external dependency for debugging purposes
*/
module.exports = function jsonPath(json, path) {

@@ -8,0 +11,0 @@

@@ -12,3 +12,3 @@ 'use strict';

/*
Deeply traverses a plain object's keys (the serverless template, previously JSON)
Deeply traverses a Serverless-style JSON (Velocity) template
When it finds a string, assumes it's Velocity language and renders it.

@@ -63,6 +63,7 @@ */

// Haaaa Velocity... this language does love strings a lot
switch (renderResult) {
case 'undefined':
return undefined;
return undefined; // But we don't, we want JavaScript types

@@ -69,0 +70,0 @@ case 'null':

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc