/** * Solution bundle manifest: validation and normalization. * * A bundle is an ordinary team template with a `bundle` section * (types/solution-bundle.types.ts). This module checks everything the apply * engine relies on, so a broken template is refused before anything is * written: roles, a lead per team, member refs, placeholders, cron * expressions, question shapes, connectors, file paths. * * @module services/bundle/bundle-manifest */ import { type TemplateRole } from '../../types/team-template.types.js'; import type { BundleTemplate } from '../../types/solution-bundle.types.js'; /** Result of validating a template's bundle section. */ export interface BundleValidation { ok: boolean; /** One line per problem, with a JSON-ish path */ errors: string[]; } /** A team of the bundle, normalized: the main team plus `bundle.teams`. */ export interface NormalizedBundleTeam { key: string; /** Name before placeholders are filled */ name: string; description: string; roles: TemplateRole[]; /** Role id of the team's lead (hierarchyLevel 1 + canDelegate) */ leadRole: string; } /** A parsed member reference (`role` or `team/role`). */ export interface MemberRef { teamKey: string; role: string; } /** Optional file access, to check `file` references of norms / SOPs. */ export interface BundleValidationOptions { /** Directory relative `file` paths resolve against */ dir?: string; /** Read a file (defaults to none: file contents are not checked) */ readFile?: (absolutePath: string) => string | null; } /** * Whether a raw template carries a `bundle` section. * * @param raw - Parsed template JSON * @returns True when `bundle` is an object */ export declare function hasBundleSection(raw: unknown): boolean; /** * Check a five-field cron expression (`*`, numbers, ranges, lists, steps). * * @param expression - Cron expression * @returns True when every field is valid and in range * * @example * isValidCronExpression('0 9 * * 1-5') // true */ export declare function isValidCronExpression(expression: string): boolean; /** * Parse a member reference. * * @param ref - `role` (main team) or `team/role` * @returns The team key and role */ export declare function parseMemberRef(ref: string): MemberRef; /** * The lead role of a list of roles: the first with hierarchyLevel 1 that can * delegate, else the first role. * * @param roles - Roles * @returns Role id, or '' when there are no roles */ export declare function leadRoleOf(roles: TemplateRole[]): string; /** * Every team of a bundle: the template's own roles as the main team, then * `bundle.teams`. * * @param template - A validated bundle template * @returns Teams, main first */ export declare function bundleTeams(template: BundleTemplate): NormalizedBundleTeam[]; /** * Validate a template that carries a `bundle` section. * * @param raw - Parsed template JSON * @param options - File access for `file` references (optional) * @returns `{ ok, errors }` * * @example * const { ok, errors } = validateBundleTemplate(JSON.parse(text), { dir, readFile }); */ export declare function validateBundleTemplate(raw: unknown, options?: BundleValidationOptions): BundleValidation; //# sourceMappingURL=bundle-manifest.d.ts.map