Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
biilmann committed Nov 13, 2017
0 parents commit 85e51ec
Show file tree
Hide file tree
Showing 7 changed files with 3,014 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
56 changes: 56 additions & 0 deletions bin/cmd.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#!/usr/bin/env node

/**
* Module dependencies.
*/

var program = require("commander");
var fs = require("fs");
var path = require("path");
var pkg = JSON.parse(
fs.readFileSync(path.join(__dirname, "..", "package.json"))
);
var build = require("../lib/build");
var serve = require("../lib/serve");

program.version(pkg.version);

program
.command("serve <dir>")
.description("serve and watch functions")
.action(function(cmd, options) {
console.log("Starting server");
var server = serve.listen(9000);
build.watch(cmd, function(err, stats) {
if (err) {
console.error(err);
return;
}

console.log(stats.compilation);
stats.compilation.chunks.forEach(function(chunk) {
server.clearCache(chunk.name);
});

console.log(stats.toString({ color: true }));
});
});

program
.command("build <dir>")
.description("build functions")
.action(function(cmd, options) {
console.log("Building functions");
build
.run(cmd)
.then(function(stats) {
console.log(stats.toString({ color: true }));
})
.catch(function(err) {
console.error(err);
process.exit(1);
});
});

console.log("hmm", process.argv);
program.parse(process.argv);
66 changes: 66 additions & 0 deletions lib/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
var fs = require("fs");
var path = require("path");
var conf = require("./config");
var webpack = require("webpack");

function webpackConfig(dir) {
var config = conf.load();
var webpackConfig = {
module: {
rules: [
{
test: /\.js?$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: "babel-loader",
options: {
cacheDirectory: true,
presets: ["es2015"],
plugins: [
"transform-class-properties",
"transform-object-assign",
"transform-object-rest-spread"
]
}
}
}
]
},
context: path.join(process.cwd(), dir),
entry: {},
target: "node",
plugins: [new webpack.IgnorePlugin(/vertx/)],
output: {
path: path.join(
process.cwd(),
config.build.functions || config.build.Functions
),
filename: "[name].js",
libraryTarget: "commonjs"
},
devtool: false
};
fs.readdirSync(path.join(process.cwd(), dir)).forEach(function(file) {
if (file.match(/\.js$/)) {
var name = file.replace(/\.js$/, "");
webpackConfig.entry[name] = "./" + name;
}
});
return webpackConfig;
}

exports.run = function(dir) {
return new Promise(function(resolve, reject) {
webpack(webpackConfig(dir), function(err, stats) {
if (err) {
return reject(err);
}
resolve(stats);
});
});
};

exports.watch = function(dir, cb) {
var compiler = webpack(webpackConfig(dir));
compiler.watch(webpackConfig(dir), cb);
};
15 changes: 15 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
var toml = require("toml");
var fs = require("fs");
var path = require("path");

exports.load = function() {
var configPath = path.join(process.cwd(), "netlify.toml");
if (!fs.existsSync(configPath)) {
console.error(
"No netlify.toml found. This is needed to configure the function settings"
);
process.exit(1);
}

return toml.parse(fs.readFileSync(configPath));
};
86 changes: 86 additions & 0 deletions lib/serve.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
var express = require("express");
var bodyParser = require("body-parser");
var expressLogging = require("express-logging");
var path = require("path");
var base64 = require("base-64");
var conf = require("./config");

function handleErr(err, response) {
response.statusCode = 500;
response.write("Function invocation failed: " + err.toString());
response.end();
console.log("Error during invocation: ", err);
return;
}

function createHandler(dir) {
return function(request, response) {
var func = request.path.split("/").filter(function(e) {
return e;
})[0];
var module = path.join(process.cwd(), dir, func);
var handler;
try {
handler = require(module);
} catch (err) {
handleErr(err, response);
return;
}

var isBase64 =
request.body &&
!(request.headers["content-type"] || "").match(/text|application/);
var lambdaRequest = {
path: request.path,
httpMethod: request.method,
queryStringParameters: request.query,
headers: request.headers,
body: isBase64 ? request.body : base64.encode(request.body),
isBase64Encoded: isBase64
};

handler.handler(lambdaRequest, {}, function(err, lambdaResponse) {
if (err) {
return handleErr(err, response);
}

response.statusCode = lambdaResponse.statusCode;
for (const key in lambdaResponse.headers) {
response.setHeader(key, lambdaResponse.headers[key]);
}
response.write(
lambdaResponse.isBase64Encoded
? base64.decode(lambdaResponse.body)
: lambdaResponse.body
);
response.end();
});
};
}

exports.listen = function(port) {
var config = conf.load();
var app = express();
var dir = config.build.functions || config.build.Functions;
app.use(bodyParser.raw());
app.use(expressLogging(console));

app.all("*", createHandler(dir));

app.listen(port, function(err) {
if (err) {
console.error("Unable to start lambda server: ", err);
process.exit(1);
}

console.log(`Lambda server is listening on ${port}`);
});

return {
clearCache: function(chunk) {
var module = path.join(process.cwd(), dir, chunk);
console.log("Clearing require cache: ", require.resolve(module));
delete require.cache[require.resolve(module)];
}
};
};
27 changes: 27 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"name": "netlify-lambda",
"version": "0.0.1",
"description": "Build and serve lambda function with webpack compilation",
"main": "bin/cmd.js",
"bin": {
"netlify-lambda": "bin/cmd.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Mathias Biilmann Christensen",
"license": "MIT",
"dependencies": {
"babel-plugin-transform-class-properties": "^6.24.1",
"babel-plugin-transform-object-assign": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"base-64": "^0.1.0",
"body-parser": "^1.18.2",
"commander": "^2.11.0",
"express": "^4.16.2",
"express-logging": "^1.1.1",
"toml": "^2.3.3",
"webpack": "^3.8.1"
}
}
Loading

0 comments on commit 85e51ec

Please sign in to comment.