serverless-offline-msk
Version:
A serverless offline plugin that enables AWS MSK events
206 lines (180 loc) • 6.03 kB
JavaScript
;
const p = require('path');
const os = require('os');
const fs = require('fs');
const _ = require('lodash');
const writeFileAtomic = require('write-file-atomic');
const uuid = require('uuid');
const { log } = require('./log');
const logDebug = log.get('config').debug;
let baseFilename = 'serverless';
if (process.env.SERVERLESS_PLATFORM_STAGE && process.env.SERVERLESS_PLATFORM_STAGE !== 'prod') {
baseFilename = `serverless${process.env.SERVERLESS_PLATFORM_STAGE.toLowerCase()}`;
baseFilename = baseFilename.trim();
}
baseFilename = `.${baseFilename}rc`;
const getLocalConfigPath = () => p.join(process.cwd(), baseFilename);
const getDefaultGlobalConfigPath = () => p.join(os.homedir(), baseFilename);
const getHomeConfigGlobalConfigPath = () => p.join(os.homedir(), '.config', baseFilename);
const getGlobalConfigPath = () => {
const homeConfigGlobalConfigPath = getHomeConfigGlobalConfigPath();
const defaultGlobalConfigPath = getDefaultGlobalConfigPath();
const homeConfigGlobalConfigExists = fs.existsSync(homeConfigGlobalConfigPath);
const defaultGlobalConfigExists = fs.existsSync(defaultGlobalConfigPath);
if (homeConfigGlobalConfigExists && defaultGlobalConfigExists) {
log.warning(`Found two global configuration files. Using: ${defaultGlobalConfigPath}`);
return defaultGlobalConfigPath;
}
if (homeConfigGlobalConfigExists) {
return homeConfigGlobalConfigPath;
}
return defaultGlobalConfigPath;
};
function storeConfig(config, configPath) {
config.meta = config.meta || {};
config.meta.updated_at = Math.round(Date.now() / 1000);
const jsonConfig = JSON.stringify(config, null, 2);
try {
writeFileAtomic.sync(configPath, jsonConfig);
} catch (error) {
logDebug(
`Unable to store serverless config: ${configPath} due to ${error.code} error`,
error.stack
);
}
}
function createDefaultGlobalConfig() {
const defaultConfig = {
userId: null, // currentUserId
frameworkId: uuid.v1(),
trackingDisabled: false,
enterpriseDisabled: false,
meta: {
created_at: Math.round(Date.now() / 1000), // config file creation date
updated_at: null, // config file updated date
},
};
storeConfig(defaultConfig, getDefaultGlobalConfigPath());
return defaultConfig;
}
function getLocalConfig() {
const localConfigPath = getLocalConfigPath();
try {
return JSON.parse(fs.readFileSync(localConfigPath));
} catch (error) {
if (error.code === 'ENOENT') return {};
log.warning(`Cannot resolve local config file.\nError: ${error.message}`);
try {
// try/catch to account for very unlikely race condition where file existed
// during readFileSync but no longer exists during rename
const backupServerlessrcPath = `${localConfigPath}.bak`;
fs.renameSync(localConfigPath, backupServerlessrcPath);
log.warning(
`Your previous local config was renamed to ${backupServerlessrcPath} for debugging.`
);
} catch {
// Ignore
}
}
return {};
}
function getGlobalConfig() {
const globalConfigPath = getGlobalConfigPath();
try {
return JSON.parse(fs.readFileSync(globalConfigPath));
} catch (error) {
// If the file does not exist, we want to recreate default global configuration
if (error.code !== 'ENOENT') {
log.warning(
`Cannot resolve global config file: ${globalConfigPath} \nError: ${error.message}`
);
try {
// try/catch to account for very unlikely race condition where file existed
// during readFileSync but no longer exists during rename
const backupServerlessrcPath = `${globalConfigPath}.bak`;
fs.renameSync(globalConfigPath, backupServerlessrcPath);
log.warning(
`Your previous global config was renamed to ${backupServerlessrcPath} for debugging. ` +
`Default global config will be recreated under ${getDefaultGlobalConfigPath()}`
);
} catch {
// Ignore
}
}
}
return createDefaultGlobalConfig();
}
function getConfig() {
const localConfig = getLocalConfig();
const globalConfig = getGlobalConfig();
return _.merge(globalConfig, localConfig);
}
function getConfigForUpdate() {
const localConfigPath = getLocalConfigPath();
const localConfigExists = fs.existsSync(localConfigPath);
if (localConfigExists) {
return {
config: getLocalConfig(),
configPath: localConfigPath,
};
}
return {
config: getGlobalConfig(),
configPath: getGlobalConfigPath(),
};
}
function set(key, value) {
const configForUpdate = getConfigForUpdate();
let { config } = configForUpdate;
const { configPath } = configForUpdate;
if (key && typeof key === 'string' && typeof value !== 'undefined') {
config = _.set(config, key, value);
} else if (_.isObject(key)) {
config = _.merge(config, key);
} else if (typeof value !== 'undefined') {
config = _.merge(config, value);
}
storeConfig(config, configPath);
return getConfig();
}
function deleteValue(key) {
const configForUpdate = getConfigForUpdate();
let { config } = configForUpdate;
const { configPath } = configForUpdate;
if (key && typeof key === 'string') {
config = _.omit(config, [key]);
} else if (key && Array.isArray(key)) {
config = _.omit(config, key);
}
storeConfig(config, configPath);
return getConfig();
}
function get(path) {
const config = getConfig();
return _.get(config, path);
}
function getLoggedInUser() {
const config = getConfig();
if (!config.userId) {
return null;
}
const user = _.get(config, ['users', config.userId, 'dashboard']);
if (!user || !user.username) {
return null; // user is logged out
}
return {
userId: config.userId,
username: user.username,
accessKeys: user.accessKeys,
idToken: user.idToken,
refreshToken: user.refreshToken,
};
}
module.exports = {
set,
get,
delete: deleteValue,
getConfig,
getLoggedInUser,
CONFIG_FILE_NAME: baseFilename,
};