@swell/cli
Version:
Swell's command line interface/utility
188 lines (187 loc) • 5.45 kB
JavaScript
import Conf from 'conf';
import Configstore from 'configstore';
import { homedir } from 'node:os';
import path from 'node:path';
import localEnv from '../env/local.js';
import prodEnv from '../env/production.js';
import reviewEnv from '../env/review.js';
import stagingEnv from '../env/staging.js';
import style from './style.js';
const configPath = process.env.NODE_ENV === 'test'
? path.resolve(process.cwd(), 'test', '.swell', 'config.json')
: path.resolve(homedir(), '.swell', 'config.json');
const configDir = process.env.NODE_ENV === 'test'
? path.resolve(process.cwd(), 'test', 'fixtures')
: homedir();
const configStore = new Configstore('swell', {
// user: {...},
// defaultStore: '<store_id>',
// stores: [
// {
// storeId: '<store_id>',
// sessionId: '<session_id>',
// name: '<store_name>',
// }
// ]
}, {
configPath,
});
const env = new Conf({
configName: 'env',
cwd: path.join(configDir, '.swell'),
projectName: 'swell',
projectSuffix: '',
});
function setEnv(name, reviewBranch) {
let newEnv = {};
if (name.startsWith('prod')) {
newEnv = { ...prodEnv };
}
else if (name.startsWith('stag')) {
newEnv = { ...stagingEnv };
}
else if (name.startsWith('local')) {
newEnv = { ...localEnv };
}
else if (name.startsWith('rev') || name.startsWith('ra')) {
if (reviewBranch) {
const reviewAppEnv = { ...reviewEnv };
const reviewDomain = reviewBranch.replaceAll('/', '-');
for (const key of Object.keys(reviewAppEnv)) {
reviewAppEnv[key] = reviewAppEnv[key].replace('${REVIEW_DOMAIN}', reviewDomain);
}
newEnv = reviewAppEnv;
}
else {
throw new Error('Review environment requires a branch name.');
}
}
else {
throw new Error(`Invalid environment '${name}'. Should be one of 'prod', 'staging', 'review', or 'local'.`);
}
env.set(newEnv);
return newEnv;
}
/**
* Get specified attributes for given object.
*
* @param object - The object to get attributes from
* @param attributes - The attributes to get from the
*
* @returns An array of the values of the specified attributes
*/
function selectAttributes(object, attributes) {
// eslint-disable-next-line unicorn/no-array-reduce
return attributes.reduce((acc, key) => {
acc[key] = object[key];
return acc;
}, {});
}
async function ensureLoggedIn(storeId) {
const currentStore = storeId || getDefaultStore();
const sessionId = getSessionId(currentStore);
// still not logged in
if (!sessionId) {
const message = [
`You are not logged in to store ${style.storeId(currentStore)}.`,
`Use ${style.command('swell login')} to authenticate.`,
].join(' ');
throw new Error(message);
}
return sessionId;
}
function get(key) {
return configStore.get(key);
}
function getAll() {
return configStore.all;
}
function getDefaultStore() {
return configStore.get('defaultStore');
}
function setDefaultStore(storeId) {
return configStore.set('defaultStore', storeId);
}
function getDefaultStorefront(appPath) {
const storeId = getDefaultStore();
const defaultStorefronts = configStore.get('defaultStorefronts') || {};
const value = defaultStorefronts[storeId]?.[appPath];
// Backward compatibility with env, which was only used in test env before 3/2025
if (typeof value === 'string') {
return { id: value, env: 'test' };
}
return value;
}
function setDefaultStorefront(appPath, storefrontId, env) {
const storeId = getDefaultStore();
const defaultStorefronts = configStore.get('defaultStorefronts') || {};
defaultStorefronts[storeId] = defaultStorefronts[storeId] || {};
defaultStorefronts[storeId][appPath] = {
id: storefrontId,
env,
};
return configStore.set('defaultStorefronts', defaultStorefronts);
}
function getSessionId(storeId) {
if (!configStore.has('stores'))
return;
const store = configStore
.get('stores')
.find((store) => store.storeId === storeId);
return store?.sessionId;
}
/**
* Set store data for later access.
*
* It replaces the previous store value if it exists and only stores the
* following attributes:
*
* - sessionId
* - storeId
* - name
*
* @param store - The store to set
* @returns {void}
*/
function setStore(store) {
const stores = configStore.get('stores') || [];
const storeIndex = stores.findIndex((s) => s.storeId === store.storeId);
const storeConfig = selectAttributes(store, [
'storeId',
'sessionId',
'name',
'email',
]);
if (storeIndex === -1) {
stores.push(storeConfig);
}
else {
stores[storeIndex] = storeConfig;
}
return configStore.set('stores', stores);
}
function getUser() {
return configStore.get('user');
}
function setUser(user) {
const userConfig = selectAttributes(user, ['name', 'email']);
return configStore.set('user', userConfig);
}
function clear() {
return configStore.clear();
}
const config = {
clear,
ensureLoggedIn,
get,
getAll,
getDefaultStore,
getDefaultStorefront,
getSessionId,
getUser,
setDefaultStore,
setDefaultStorefront,
setStore,
setUser,
};
export { config as default, env, setEnv };