/
getServerlessConfigFile.js
130 lines (116 loc) · 4.15 KB
/
getServerlessConfigFile.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
'use strict';
const _ = require('lodash');
const BbPromise = require('bluebird');
const path = require('path');
const resolveModulePath = require('ncjsm/resolve');
const memoizee = require('memoizee');
const spawn = require('child-process-ext/spawn');
const fileExists = require('./fs/fileExists');
const readFile = require('./fs/readFile');
const ServerlessError = require('../classes/Error').ServerlessError;
const getConfigFilePath = (servicePath, options = {}) => {
if (options.config) {
const customPath = path.join(servicePath, options.config);
return fileExists(customPath).then(exists => {
return exists ? customPath : null;
});
}
const jsonPath = path.join(servicePath, 'serverless.json');
const ymlPath = path.join(servicePath, 'serverless.yml');
const yamlPath = path.join(servicePath, 'serverless.yaml');
const jsPath = path.join(servicePath, 'serverless.js');
const tsPath = path.join(servicePath, 'serverless.ts');
return BbPromise.props({
json: fileExists(jsonPath),
yml: fileExists(ymlPath),
yaml: fileExists(yamlPath),
js: fileExists(jsPath),
ts: fileExists(tsPath),
}).then(exists => {
if (exists.yaml) {
return yamlPath;
} else if (exists.yml) {
return ymlPath;
} else if (exists.json) {
return jsonPath;
} else if (exists.js) {
return jsPath;
} else if (exists.ts) {
return tsPath;
}
return null;
});
};
const getServerlessConfigFilePath = serverless => {
return getConfigFilePath(
serverless.config.servicePath || process.cwd(),
serverless.processedInput.options
);
};
const resolveTsNode = serviceDir => {
const resolveModuleRealPath = (...args) =>
resolveModulePath(...args).then(({ realPath }) => realPath);
const ifNotFoundContinueWith = cb => error => {
if (error.code !== 'MODULE_NOT_FOUND') throw error;
return cb();
};
const resolveAsServerlessPeerDependency = () => resolveModuleRealPath(__dirname, 'ts-node');
const resolveAsServiceDependency = () => resolveModuleRealPath(serviceDir, 'ts-node');
const resolveAsGlobalInstallation = () =>
spawn('npm', ['root', '-g']).then(
({ stdoutBuffer }) => require.resolve(`${String(stdoutBuffer).trim()}/ts-node`),
error => {
if (error.code !== 'ENOENT') throw error;
throw Object.assign(new Error('npm not installed', { code: 'MODULE_NOT_FOUND' }));
}
);
const throwTsNodeError = () => {
throw new ServerlessError(
'Ensure "ts-node" dependency when working with TypeScript configuration files',
'TS_NODE_NOT_FOUND'
);
};
return resolveAsServerlessPeerDependency()
.catch(ifNotFoundContinueWith(resolveAsServiceDependency))
.catch(ifNotFoundContinueWith(resolveAsGlobalInstallation))
.catch(ifNotFoundContinueWith(throwTsNodeError));
};
const handleJsOrTsConfigFile = configFile =>
BbPromise.try(() => {
if (!configFile.endsWith('.ts')) return null;
return resolveTsNode(path.dirname(configFile)).then(tsNodePath => {
try {
require(tsNodePath).register();
} catch (error) {
throw new ServerlessError(
`Registering "ts-node" failed with: ${error && error.stack ? error.stack : error}`
);
}
});
}).then(() => {
try {
return require(configFile);
} catch (error) {
throw new ServerlessError(
`Loading ${configFile} failed with: ${error && error.stack ? error.stack : error}`
);
}
});
const getServerlessConfigFile = memoizee(serverless =>
getServerlessConfigFilePath(serverless).then(configFilePath => {
if (!configFilePath) return null;
const fileExtension = path.extname(configFilePath);
const isJSOrTsConfigFile = fileExtension === '.js' || fileExtension === '.ts';
return (isJSOrTsConfigFile
? handleJsOrTsConfigFile(configFilePath)
: readFile(configFilePath)
).then(config => {
if (_.isPlainObject(config)) return config;
throw new ServerlessError(
`${path.basename(configFilePath)} must export plain object`,
'INVALID_CONFIG_OBJECT_TYPE'
);
});
})
);
module.exports = { getConfigFilePath, getServerlessConfigFile, getServerlessConfigFilePath };