forked from dherault/serverless-offline
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctionHelper.js
94 lines (75 loc) · 2.81 KB
/
functionHelper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
'use strict';
const debugLog = require('./debugLog');
const path = require('path');
const execSync = require('child_process').execSync;
module.exports = {
getFunctionOptions(fun, funName, servicePath) {
// Split handler into method name and path i.e. handler.run
const handlerPath = fun.handler.split('.')[0];
const handlerName = fun.handler.split('/').pop().split('.')[1];
return {
funName,
handlerName, // i.e. run
handlerPath: `${servicePath}/${handlerPath}`,
funTimeout: (fun.timeout || 6) * 1000,
babelOptions: ((fun.custom || {}).runtime || {}).babel,
};
},
// Create a function handler
// The function handler is used to simulate Lambda functions
createHandler(funOptions, options) {
if (!options.skipCacheInvalidation) {
debugLog('Invalidating cache...');
for (const key in require.cache) {
// Require cache invalidation, brutal and fragile.
// Might cause errors, if so please submit an issue.
if (!key.match('node_modules')) delete require.cache[key];
}
}
const handler = options.verboseHandlerLoader ? this.verboseHandlerLoader(funOptions) : this.handlerLoader(funOptions);
if (typeof handler !== 'function') {
throw new Error(`Serverless-offline: handler for '${funOptions.funName}' is not a function`);
}
return handler;
},
// require module/handler from handlerPath
handlerLoader(funOptions) {
debugLog(`Loading handler... (${funOptions.handlerPath})`);
return require(funOptions.handlerPath)[funOptions.handlerName];
},
// Verbose Load lambda handler and better loading errors
// Attempts to load handlerPath
// On failure, it execs the handleFile and throw interpreter errors
// This is workaround for node 4.x, should be fixed in 6+
// https://github.com/nodejs/node/issues/2762
verboseHandlerLoader(funOptions) {
debugLog(`Loading handler (verbose)... (${funOptions.handlerPath})`);
let moduleLoadError,
handler;
// Basic to attempt to load handler
try {
handler = require(funOptions.handlerPath)[funOptions.handlerName];
}
catch (error) {
moduleLoadError = error;
}
// Let's try to get a better, more in depth error stack
if (moduleLoadError) {
try {
const ext = path.extname(funOptions.handlerPath);
execSync(`node ${funOptions.handlerPath}${ext ? '' : '.js'}`, { stdio: [null, null] });
}
catch (execError) {
// remove internal exec failed message (useless trace to Offline users)
const stack = execError.stack.split('\n');
stack.shift();
execError.stack = stack.join('\n');
throw execError;
}
// Unable to find deeper error from manually loading
// throwing require error
throw moduleLoadError;
}
return handler;
},
};