mirror of
https://github.com/serverless/serverless.git
synced 2026-01-18 14:58:43 +00:00
180 lines
4.8 KiB
JavaScript
180 lines
4.8 KiB
JavaScript
'use strict';
|
|
|
|
const SError = require('./Error'),
|
|
RuntimeBase = require('./RuntimeBase'),
|
|
SCli = require('./utils/cli'),
|
|
_ = require('lodash'),
|
|
BbPromise = require('bluebird'),
|
|
chalk = require('chalk'),
|
|
context = require('./utils/context'),
|
|
path = require('path'),
|
|
fs = BbPromise.promisifyAll(require('fs'));
|
|
let SUtils;
|
|
|
|
class ServerlessRuntimeNode extends RuntimeBase {
|
|
|
|
constructor(S) {
|
|
super( S, 'nodejs' );
|
|
SUtils = S.utils;
|
|
}
|
|
|
|
/**
|
|
* Scaffold
|
|
* - Create scaffolding for new Node.js function
|
|
*/
|
|
|
|
scaffold(func) {
|
|
const handlerPath = path.join(this.S.getServerlessPath(), 'templates', 'nodejs', 'handler.js');
|
|
|
|
return fs.readFileAsync(handlerPath)
|
|
.then(handlerJs => BbPromise.all([
|
|
SUtils.writeFile(func.getRootPath('handler.js'), handlerJs),
|
|
SUtils.writeFile(func.getRootPath('event.json'), {})
|
|
]));
|
|
}
|
|
|
|
/**
|
|
* Run
|
|
* - Run this function locally
|
|
*/
|
|
|
|
run(func) {
|
|
|
|
let _this = this,
|
|
functionEvent,
|
|
functionCall;
|
|
|
|
return BbPromise.try(function() {
|
|
|
|
// Load Event
|
|
functionEvent = SUtils.readFileSync(func.getRootPath('event.json'));
|
|
|
|
// Load Function
|
|
let handlerArr = func.handler.split('/').pop().split('.'),
|
|
functionFile = func.getRootPath(handlerArr[0] + '.js'),
|
|
functionHandler = handlerArr[1];
|
|
|
|
functionCall = require(functionFile)[functionHandler];
|
|
})
|
|
.then(() => _this.getEnvVars(func))
|
|
.then(function(envVars) {
|
|
|
|
// Add ENV vars (from no stage/region) to environment
|
|
for (var key in envVars) {
|
|
process.env[key] = envVars[key];
|
|
}
|
|
})
|
|
.then(() => {
|
|
|
|
return new BbPromise(resolve => {
|
|
|
|
// Call Function
|
|
functionCall(functionEvent, context(func, (err, result) => {
|
|
|
|
SCli.log(`-----------------`);
|
|
|
|
// Show error
|
|
if (err) {
|
|
SCli.log(chalk.bold('Failed - This Error Was Returned:'));
|
|
SCli.log(err.message);
|
|
SCli.log(err.stack);
|
|
|
|
return resolve({
|
|
status: 'error',
|
|
response: err.message,
|
|
error: err
|
|
});
|
|
}
|
|
|
|
// Show success response
|
|
SCli.log(chalk.bold('Success! - This Response Was Returned:'));
|
|
SCli.log(JSON.stringify(result, null, 4));
|
|
return resolve({
|
|
status: 'success',
|
|
response: result
|
|
});
|
|
}));
|
|
})
|
|
})
|
|
.catch((err) => {
|
|
SCli.log(`-----------------`);
|
|
|
|
SCli.log(chalk.bold('Failed - This Error Was Thrown:'));
|
|
SCli.log(err.stack || err);
|
|
|
|
return {
|
|
status: 'error',
|
|
response: err.message,
|
|
error: err
|
|
};
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Build
|
|
* - Build the function in this runtime
|
|
*/
|
|
|
|
build(func, stage, region) {
|
|
|
|
// Validate
|
|
if (!func._class || func._class !== 'Function') return BbPromise.reject(new SError('A function instance is required'));
|
|
|
|
let pathDist;
|
|
|
|
return this.createDistDir(func.name)
|
|
.then(function(distDir) { pathDist = distDir })
|
|
.then(() => this.copyFunction(func, pathDist, stage, region))
|
|
.then(() => this._addEnvVarsInline(func, pathDist, stage, region))
|
|
.then(() => this.generatePaths(func, pathDist));
|
|
}
|
|
|
|
/**
|
|
* Get Handler
|
|
*/
|
|
|
|
getHandler(func) {
|
|
return path.join(path.dirname(func.handler), "_serverless_handler.handler").replace(/\\/g, '/');
|
|
}
|
|
|
|
/**
|
|
* Install NPM Dependencies
|
|
*/
|
|
|
|
installDependencies(dir) {
|
|
SCli.log(`Installing NPM dependencies in dir: ${dir}`);
|
|
SCli.log(`-----------------`);
|
|
SUtils.npmInstall(this.S.getProject().getRootPath(dir));
|
|
SCli.log(`-----------------`);
|
|
}
|
|
|
|
/**
|
|
* Add ENV Vars In-line
|
|
* - Adds a new handler that loads in ENV vars before running the main handler
|
|
*/
|
|
|
|
_addEnvVarsInline(func, pathDist, stage, region) {
|
|
|
|
return this.getEnvVars(func, stage, region)
|
|
.then(envVars => {
|
|
|
|
const handlerArr = func.handler.split('.'),
|
|
handlerDir = path.dirname(func.handler),
|
|
handlerFile = handlerArr[0].split('/').pop(),
|
|
handlerMethod = handlerArr[1];
|
|
|
|
const loader = `
|
|
var envVars = ${JSON.stringify(envVars, null, 2)};
|
|
for (var key in envVars) {
|
|
process.env[key] = envVars[key];
|
|
}
|
|
exports.handler = require("./${handlerFile}")["${handlerMethod}"];
|
|
`;
|
|
|
|
return fs.writeFileAsync(path.join(pathDist, handlerDir, '_serverless_handler.js'), loader);
|
|
});
|
|
}
|
|
}
|
|
|
|
module.exports = ServerlessRuntimeNode;
|