@puls-atlas/cli
Version:
The Puls Atlas CLI tool for managing Atlas projects
106 lines • 3.91 kB
JavaScript
import { isFunction, isString } from 'es-toolkit/compat';
import { logger } from './logger.js';
import { getFirebaserc, selectProject } from './firebase.js';
import { loadServiceConfig } from '../cmd/service/config/serviceConfig.js';
import { loadSearchConfig } from '../cmd/search/config/searchConfig.js';
import { loadSyncConfig } from '../cmd/sync/config/syncConfig.js';
const featureConfigLoaders = {
services: loadServiceConfig,
search: loadSearchConfig,
sync: loadSyncConfig
};
export const getProjectEnvironment = (projectId, config) => {
if (!config?.config?.[projectId]) {
return null;
}
return config.config[projectId].environment ?? null;
};
export const resolveProjectSelection = async (options = {}, dependencies = {}) => {
const {
getFirebasercImpl = getFirebaserc,
selectProjectImpl = selectProject
} = dependencies;
if (isString(options.project) && options.project.length > 0) {
const config = getFirebasercImpl({
allowMissing: true
});
return {
config,
environment: getProjectEnvironment(options.project, config),
projectId: options.project
};
}
const result = await selectProjectImpl('.firebaserc', {
environment: options.environment
});
return {
...result,
environment: getProjectEnvironment(result.projectId, result.config)
};
};
export const loadFeatureConfig = (featureName, cwd = process.cwd(), options = {}) => {
const loadConfig = featureConfigLoaders[featureName];
if (!isFunction(loadConfig)) {
throw new Error(`Atlas feature "${featureName}" does not have a config loader.`);
}
return loadConfig(cwd, options);
};
const normalizeFeatureDependencies = dependencies => {
if (isString(dependencies)) {
return {
cwd: dependencies
};
}
return dependencies ?? {};
};
export const loadFeatureContext = async (featureName, options = {}, dependencies = {}) => {
const normalizedDependencies = normalizeFeatureDependencies(dependencies);
const {
cwd = process.cwd(),
loadFeatureConfigImpl = loadFeatureConfig,
resolveProjectSelectionImpl = resolveProjectSelection
} = normalizedDependencies;
const projectSelection = await resolveProjectSelectionImpl(options);
const loadedConfig = loadFeatureConfigImpl(featureName, cwd, {
environment: projectSelection.environment,
projectId: projectSelection.projectId
});
return {
featureName,
config: loadedConfig.config,
configPath: loadedConfig.configPath,
configPaths: loadedConfig.configPaths ?? [],
environment: projectSelection.environment,
projectConfig: projectSelection.config,
projectId: projectSelection.projectId,
rootConfig: loadedConfig.rootConfig ?? null,
workloadProjectConfig: loadedConfig.projectConfig ?? null
};
};
export const runFeatureAction = async (featureName, actionName, options = {}, dependencies = {}) => {
const normalizedDependencies = normalizeFeatureDependencies(dependencies);
const {
cwd = process.cwd(),
loadFeatureContextImpl = loadFeatureContext,
loggerImpl = logger
} = normalizedDependencies;
let spinner;
try {
const featureContext = await loadFeatureContextImpl(featureName, options, {
...normalizedDependencies,
cwd
});
spinner = loggerImpl.spinner(`Preparing ${actionName} for Atlas ${featureName}...`);
spinner.succeed(`Atlas ${featureName} ${actionName} shell is ready.`);
loggerImpl.info(`Project: ${featureContext.projectId}`);
if (featureContext.environment) {
loggerImpl.info(`Environment: ${featureContext.environment}`);
}
loggerImpl.info(`Config: ${featureContext.configPath}`).warning(`Atlas ${featureName} ${actionName} is scaffolded but not implemented yet.`);
} catch (error) {
if (spinner) {
spinner.fail(`Failed to prepare Atlas ${featureName} ${actionName}.`);
}
loggerImpl.error(error.message);
}
};