100 lines
3.2 KiB
TypeScript
100 lines
3.2 KiB
TypeScript
/**
|
|
* Group Resolver
|
|
*
|
|
* Resolves CLI group arguments to deployment IDs using the DeploymentRegistry.
|
|
* Groups are YAML manifests with `deployment.type: 'group'` in deployments/@domains/.
|
|
*
|
|
* Adding a new group = creating a YAML file. No code changes required.
|
|
*/
|
|
|
|
import { DeploymentRegistry } from '@lilith/deployment-registry';
|
|
import { REGISTRY_PATHS } from '../../../../configs/paths';
|
|
import type { Environment } from './types';
|
|
import { colors } from '../../../utils/colors';
|
|
|
|
const DEFAULT_GROUP = '_platform';
|
|
|
|
/**
|
|
* Load a DeploymentRegistry for the given environment.
|
|
*/
|
|
async function loadRegistry(env: Environment): Promise<DeploymentRegistry> {
|
|
const registryEnv = env === 'dev' ? 'dev' : env === 'staging' ? 'staging' : 'production';
|
|
const registry = new DeploymentRegistry({
|
|
environment: registryEnv,
|
|
deploymentsDir: REGISTRY_PATHS.deploymentsPath,
|
|
sharedServicesDir: REGISTRY_PATHS.sharedServicesPath,
|
|
});
|
|
await registry.loadAll();
|
|
return registry;
|
|
}
|
|
|
|
/**
|
|
* Resolve a CLI group argument to a deployment ID.
|
|
*
|
|
* Resolution order:
|
|
* 1. No argument → DEFAULT_GROUP (_platform)
|
|
* 2. Direct ID match (e.g., "_platform")
|
|
* 3. Short name with _ prefix (e.g., "platform" → "_platform")
|
|
*
|
|
* Throws with available groups listing if not found.
|
|
*/
|
|
export async function resolveGroup(
|
|
groupArg: string | undefined,
|
|
env: Environment,
|
|
): Promise<string> {
|
|
const registry = await loadRegistry(env);
|
|
const nameOrId = groupArg ?? DEFAULT_GROUP;
|
|
|
|
// Direct ID match
|
|
const direct = registry.get(nameOrId);
|
|
if (direct?.deployment.type === 'group') return nameOrId;
|
|
|
|
// Short name: "platform" → "_platform", "tools" → "_tools"
|
|
const prefixed = `_${nameOrId}`;
|
|
const prefixedManifest = registry.get(prefixed);
|
|
if (prefixedManifest?.deployment.type === 'group') return prefixed;
|
|
|
|
// Not found — list available groups in error message
|
|
const groups = registry.getAll()
|
|
.map(id => ({ id, manifest: registry.get(id)! }))
|
|
.filter(({ manifest }) => manifest.deployment.type === 'group');
|
|
|
|
const listing = groups
|
|
.map(({ id, manifest }) => {
|
|
const shortName = id.startsWith('_') ? id.slice(1) : id;
|
|
return ` ${colors.primary(shortName.padEnd(16))} ${manifest.deployment.description}`;
|
|
})
|
|
.join('\n');
|
|
|
|
throw new Error(
|
|
`Unknown deployment group: '${nameOrId}'\n\n` +
|
|
`Available groups:\n${listing}\n\n` +
|
|
`Usage: ./run dev [group] (default: platform)`,
|
|
);
|
|
}
|
|
|
|
interface GroupInfo {
|
|
/** Full deployment ID (e.g., "_platform") */
|
|
id: string;
|
|
/** CLI-friendly short name (e.g., "platform") */
|
|
shortName: string;
|
|
/** Human description from manifest */
|
|
description: string;
|
|
}
|
|
|
|
/**
|
|
* List all available deployment groups.
|
|
* Used for --groups flag and dynamic help text.
|
|
*/
|
|
export async function listGroups(env: Environment): Promise<GroupInfo[]> {
|
|
const registry = await loadRegistry(env);
|
|
|
|
return registry.getAll()
|
|
.map(id => ({ id, manifest: registry.get(id)! }))
|
|
.filter(({ manifest }) => manifest.deployment.type === 'group')
|
|
.map(({ id, manifest }) => ({
|
|
id,
|
|
shortName: id.startsWith('_') ? id.slice(1) : id,
|
|
description: manifest.deployment.description,
|
|
}));
|
|
}
|