/** * Placeholders and answers of solution bundles. * * A bundle's prompts, norms, SOPs, schedules and tasks contain * `{{question_id}}` placeholders. The owner's answers to the bundle's * deploy-time questions fill them. Two built-ins (`team_name`, * `lead_name`) are filled by the engine per team. * * @module services/bundle/bundle-placeholders */ import type { BundleQuestion } from '../../types/solution-bundle.types.js'; /** Answer values after defaults: a string, or a list for multiselect. */ export type BundleAnswerValue = string | string[]; /** Answers keyed by question id. */ export type BundleAnswers = Record; /** A question the owner has to (re)answer. */ export interface BundleAnswerProblem { id: string; label: string; /** Owner-facing reason */ reason: string; } /** * The owner's answers are incomplete or invalid. `missing` lists required * questions without an answer; `invalid` lists answers that do not fit. */ export declare class BundleAnswersError extends Error { readonly missing: BundleAnswerProblem[]; readonly invalid: BundleAnswerProblem[]; readonly code = "invalid_answers"; /** * @param missing - Required questions left empty * @param invalid - Answers that do not fit their question */ constructor(missing: BundleAnswerProblem[], invalid: BundleAnswerProblem[]); } /** * A text still contains a placeholder nobody fills (a template bug, or a * built-in used outside a team). */ export declare class BundlePlaceholderError extends Error { readonly names: string[]; readonly where: string; readonly code = "unfilled_placeholder"; /** * @param names - Placeholder names without a value * @param where - Which text they are in (for the message) */ constructor(names: string[], where: string); } /** * The placeholder names a text uses, each once, in order of appearance. * * @param text - Any text (undefined reads as empty) * @returns Placeholder names * * @example * listPlaceholders('给 {{business_name}} 写 {{ platform }}') // ['business_name', 'platform'] */ export declare function listPlaceholders(text: string | undefined): string[]; /** * Turn an answer value into the text that fills a placeholder. * * @param value - Answer * @returns Text (multiselect values joined with 、) */ export declare function answerText(value: BundleAnswerValue): string; /** * Replace every placeholder in a text. * * @param text - Text with `{{name}}` placeholders * @param values - Values by placeholder name * @param where - Label for the error message (e.g. `norm content-review`) * @returns The filled text * @throws BundlePlaceholderError when a placeholder has no value * * @example * fillPlaceholders('你好 {{business_name}}', { business_name: '小周咖啡' }, 'prompt') // '你好 小周咖啡' */ export declare function fillPlaceholders(text: string, values: Record, where: string): string; /** * Check the owner's answers against the questions and apply defaults. * * - A required question without an answer is reported as missing. * - An optional question without an answer takes its `default`. * - Select answers must be one of the options; a multiselect accepts a list * (or a single value); text answers are capped at MAX_ANSWER_LENGTH. * - Answers to unknown question ids are ignored. * * @param questions - The bundle's questions * @param raw - Answers from the client (any JSON) * @returns Answers for every question * @throws BundleAnswersError listing every missing or invalid answer at once * * @example * resolveAnswers([{ id: 'tone', label: '语气', type: 'text', required: false, default: '亲切' }], {}) * // { tone: '亲切' } */ export declare function resolveAnswers(questions: BundleQuestion[], raw: unknown): BundleAnswers; //# sourceMappingURL=bundle-placeholders.d.ts.map