@swell/cli
Version:
Swell's command line interface/utility
179 lines (178 loc) • 6.04 kB
JavaScript
import { Separator, confirm, select } from '@inquirer/prompts';
import { CLIError } from '@oclif/errors';
import config from './config.js';
import style from './style.js';
/**
* Builds a list of stores while also highlighting the current store.
*
* @example <caption>Example output:</caption>
*
* > Stores you are logged in to:
* >
* > - Test Store, test
* > - Another Test, another-test (current)
*
* @param stores - The stores to build the display for
* @param currentStoreId - The ID of the default store
* @returns A list of stores ready to display.
*/
function showStores(stores, currentStoreId) {
if (stores.length === 0) {
throw new CLIError('You are not logged in to any store.');
}
function currentStoreLabel(store) {
if (stores.length === 1 || store.storeId !== currentStoreId) {
return '';
}
return `(${style.basicHighlight('current')})`;
}
let storesOutput = '';
for (const [index, store] of stores.entries()) {
// builds each line of the output, for every store
// e.g. - Another Test, another-test (current)
storesOutput += [
`- ${store.name},`,
`${style.storeId(store.storeId)}`,
`${style.storeId(currentStoreLabel(store))}`,
// don't add a newline on the last line:
index === stores.length - 1 ? null : '\n',
]
.filter(Boolean)
.join(' ');
}
return storesOutput;
}
/**
* Select the store to login to from a CLI prompt.
*
* By default it will only show stores for which we don't already have a
* session id. If `force` is true, show all stores to pull the session id
* again.
*
* @param currentStoreId - The ID of the default store
* @param authorizations - The authorizations for the current user
* @param force - Whether to show all stores or not
*
* @returns The store ID to login to
*/
async function selectStoreId({ authorizations, currentStoreId, force = false, }) {
let selectStoreChoices;
let selectedStoreId;
// eslint-disable-next-line unicorn/prefer-ternary
if (force) {
// show all stores
selectStoreChoices = authorizations.map((auth) => ({
name: auth.client_name +
(auth.client_id === currentStoreId
? ` (${style.basicHighlight('current')})`
: ''),
value: auth.client_id,
}));
}
else {
// only show the stores for which we don't already have a session id
// eslint-disable-next-line unicorn/no-array-reduce
selectStoreChoices = authorizations.reduce((acc, auth) => {
if (!config.getSessionId(auth.client_id)) {
acc.push({
name: auth.client_name,
value: auth.client_id,
});
}
return acc;
}, []);
}
// if more than one option, show the select options, otherwise just return
// the available one
if (selectStoreChoices.length > 1) {
selectedStoreId = await select({
choices: selectStoreChoices,
message: 'Which store do you want to login to on the CLI?',
});
}
else if (selectStoreChoices.length === 1) {
selectedStoreId = selectStoreChoices[0].value;
}
// we can also return `undefined` when we already have sessions for all
// stores: no force and no selectStoreChoices
return selectedStoreId;
}
/**
* Select the store to switch to from a CLI prompt from the list of
* already logged in stores.
*
* @param message Store selection message
* @returns The store ID to switch to
* @throws CLIError - If there are no stores to switch to
*/
async function selectLoggedInStoreId(message) {
const currentStoreId = config.getDefaultStore();
const loggedInStores = config.get('stores') || [];
if (loggedInStores.length === 0) {
throw new CLIError(`You are not logged in. Run ${style.command('swell login')} to continue.`);
}
const selectStoreChoices = loggedInStores.map((store) => ({
name: `${store.name} (${store.storeId})` +
(store.storeId === currentStoreId
? ` [${style.basicHighlight('current')}]`
: ''),
value: store.storeId,
}));
return select({
choices: [
...selectStoreChoices,
new Separator(),
{ name: 'Login to another account', value: '' },
],
loop: false,
message: message || 'Which store do you want to switch to?',
pageSize: 25,
});
}
/**
* Select an environment.
*
* @param message Environment selection message
* @returns Environment to switch to
* @throws CLIError - If there are no stores to switch to
*/
async function selectEnvironmentId(message) {
return select({
choices: [
{
name: 'Live',
value: '',
},
{
name: 'Test',
value: 'test',
},
],
message: message || 'Which environment?',
});
}
/**
* Ask the user if they want to make the given store id the default store.
*
* If there is no current store id, it will always be set as the default
* without asking.
*
* @param storeParams -
* currentStoreId - The ID of the default store
* storeId - The ID of the store to set as the default
* @param force - True to force
*
* @returns void
*/
async function modifyDefaultStore({ currentStoreId, storeId, }, force = false) {
let modifyDefault = false;
if (!force && currentStoreId && currentStoreId !== storeId) {
modifyDefault = await confirm({
message: `Do you want to make ${style.storeId(storeId)} your default store?`,
});
}
if (force || !currentStoreId || modifyDefault) {
config.setDefaultStore(storeId);
}
}
export { modifyDefaultStore, selectEnvironmentId, selectLoggedInStoreId, selectStoreId, showStores, };