138 lines
4.3 KiB
JavaScript

'use strict';
const path = require('path');
const memoizee = require('memoizee');
const inquirer = require('@serverless/utils/inquirer');
const { log } = require('@serverless/utils/log');
const resolveProviderCredentials = require('@serverless/dashboard-plugin/lib/resolve-provider-credentials');
const isAuthenticated = require('@serverless/dashboard-plugin/lib/is-authenticated');
const hasLocalCredentials = require('../../aws/has-local-credentials');
const fsp = require('fs').promises;
const yamlExtensions = new Set(['.yml', '.yaml']);
const appPattern = /^(?:#\s*)?app\s*:.+/m;
const orgPattern = /^(?:#\s*)?org\s*:.+/m;
const consolePattern = /^(?:#\s*)?console\s*:(.*)/m;
const ServerlessError = require('../../serverless-error');
const resolveStage = require('../../utils/resolve-stage');
const resolveRegion = require('../../utils/resolve-region');
module.exports = {
confirm: async (message, options = {}) => {
const name = options.name || 'isConfirmed';
return (
await inquirer.prompt({
message,
type: 'confirm',
name,
})
)[name];
},
doesServiceInstanceHaveLinkedProvider: async ({ configuration, options }) => {
const region = resolveRegion({ configuration, options });
const stage = resolveStage({ configuration, options });
let result;
try {
result = await resolveProviderCredentials({ configuration, region, stage });
} catch (err) {
if (err.statusCode && err.statusCode >= 500) {
throw new ServerlessError(
'Serverless Dashboard is currently unavailable, please try again later',
'DASHBOARD_UNAVAILABLE'
);
}
throw err;
}
return Boolean(result);
},
resolveInitialContext: ({ configuration, serviceDir }) => {
return {
isInServiceContext: Boolean(serviceDir),
isLoggedIntoDashboard: isAuthenticated(),
hasLocalAwsCredentials: hasLocalCredentials(),
isDashboardEnabled: Boolean(
configuration &&
configuration.org &&
configuration.app &&
(!configuration.console || configuration.dashboard)
),
isConsoleEnabled: Boolean(configuration && configuration.org && configuration.console),
};
},
writeOrgAppAndConsole: async (
orgName,
appName,
isConsole,
{ configurationFilename, serviceDir, configuration }
) => {
const configurationFilePath = path.resolve(serviceDir, configurationFilename);
let ymlString = await (async () => {
if (!yamlExtensions.has(path.extname(configurationFilename))) return null; // Non YAML config
try {
return await fsp.readFile(configurationFilePath);
} catch (error) {
if (error.code === 'ENOENT') return null;
throw error;
}
})();
if (!ymlString) {
log.notice(
'Add the following settings to your serverless configuration file:\n\n' +
`org: ${orgName}${appName ? `\napp: ${appName}` : ''}${
isConsole ? '\nconsole: true' : ''
}`
);
return;
}
ymlString = ymlString.toString();
if (isConsole) {
const consoleMatch = ymlString.match(consolePattern);
if (consoleMatch) {
ymlString = ymlString.replace(
consoleMatch[0],
`console:${consoleMatch[1].trim() ? ' true' : ''}`
);
} else {
ymlString = `console: true\n${ymlString}`;
}
}
if (appName) {
const appMatch = ymlString.match(appPattern);
if (appMatch) {
ymlString = ymlString.replace(appMatch[0], `app: ${appName}`);
} else {
ymlString = `app: ${appName}\n${ymlString}`;
}
}
const orgMatch = ymlString.match(orgPattern);
if (orgMatch) {
ymlString = ymlString.replace(orgMatch[0], `org: ${orgName}`);
} else {
ymlString = `org: ${orgName}\n${ymlString}`;
}
await fsp.writeFile(configurationFilePath, ymlString);
configuration.org = orgName;
if (appName) configuration.app = appName;
if (isConsole) configuration.console = isConsole;
},
showOnboardingWelcome: memoizee(
(context) => {
const isConsole = Boolean(context.options.console || context.configuration.console);
log.notice(
`Onboarding "${context.configuration.service}" to the Serverless ${
isConsole ? 'Console' : 'Dashboard'
}`
);
log.notice();
},
{ length: 0 }
),
};