{"version":3,"file":"resolve-prompts.mjs","names":[],"sources":["../../src/lib/resolve-prompts.ts"],"sourcesContent":["import type { InternalOptionConfig } from '@cli-forge/parser';\nimport type {\n  PromptConfig,\n  PromptOption,\n  PromptOptionConfig,\n  PromptProvider,\n} from './prompt-types';\n\n/**\n * Collects options that need prompting, matches them to providers,\n * executes prompts, and returns the prompted values.\n */\nexport async function resolvePrompts(opts: {\n  configuredOptions: Record<string, InternalOptionConfig>;\n  configuredImplies: Record<string, Set<string>>;\n  promptConfigs: Map<string, PromptOptionConfig<any>>;\n  providers: PromptProvider[];\n  currentArgs: Record<string, unknown>;\n}): Promise<Record<string, unknown>> {\n  const {\n    configuredOptions,\n    configuredImplies,\n    promptConfigs,\n    providers,\n    currentArgs,\n  } = opts;\n\n  // Step 1: Collect promptable options\n  const promptableOptions: PromptOption[] = [];\n\n  for (const [name, config] of Object.entries(configuredOptions)) {\n    // Skip internal options\n    if (\n      name === 'help' ||\n      name === 'version' ||\n      name === 'unmatched' ||\n      name === '--'\n    ) {\n      continue;\n    }\n\n    // Already has a value — skip unless prompt is explicitly true/string\n    const hasValue = currentArgs[name] !== undefined;\n\n    const promptSetting = promptConfigs.get(name);\n    let resolved: PromptConfig | null | undefined;\n\n    if (typeof promptSetting === 'function') {\n      resolved = promptSetting(currentArgs);\n      // Callback: null/undefined treated as false\n      if (resolved === null || resolved === undefined) {\n        continue;\n      }\n    } else if (promptSetting !== undefined) {\n      // Static value\n      resolved = promptSetting;\n    } else {\n      // Not specified: prompt only if required and missing value\n      if (hasValue) continue;\n\n      const isRequired = config.required === true;\n      const isImplied = isOptionImplied(name, configuredImplies, currentArgs);\n\n      if (!isRequired && !isImplied) continue;\n      if (providers.length === 0) continue; // No providers, let validation handle it\n\n      resolved = true; // Will prompt\n    }\n\n    if (resolved === false) continue;\n    if (hasValue && resolved !== true && typeof resolved !== 'string') continue;\n\n    promptableOptions.push({\n      name,\n      config: {\n        ...config,\n        prompt: resolved === true ? true : resolved ?? undefined,\n      },\n    });\n  }\n\n  if (promptableOptions.length === 0) {\n    return {};\n  }\n\n  // Step 2: Match options to providers\n  const filteredProviders = providers.filter((p) => p.filter);\n  const fallbackProviders = providers.filter((p) => !p.filter);\n\n  const providerGroups = new Map<PromptProvider, PromptOption[]>();\n  const unmatchedOptions: PromptOption[] = [];\n\n  for (const option of promptableOptions) {\n    let matched = false;\n    for (const provider of filteredProviders) {\n      if (provider.filter!(option.name, option.config)) {\n        if (!providerGroups.has(provider)) {\n          providerGroups.set(provider, []);\n        }\n        providerGroups.get(provider)!.push(option);\n        matched = true;\n        break;\n      }\n    }\n    if (!matched) {\n      unmatchedOptions.push(option);\n    }\n  }\n\n  // Assign unmatched options to first fallback provider\n  if (unmatchedOptions.length > 0) {\n    if (fallbackProviders.length === 0) {\n      const names = unmatchedOptions.map((o) => `'${o.name}'`).join(', ');\n      throw new Error(\n        `Option(s) ${names} require prompting but no prompt provider is available`\n      );\n    }\n    const fallback = fallbackProviders[0];\n    if (!providerGroups.has(fallback)) {\n      providerGroups.set(fallback, []);\n    }\n    providerGroups.get(fallback)!.push(...unmatchedOptions);\n  }\n\n  // Step 3: Execute prompts\n  const results: Record<string, unknown> = {};\n\n  for (const [provider, options] of providerGroups) {\n    if (provider.promptBatch) {\n      const batchResults = await provider.promptBatch(options);\n      Object.assign(results, batchResults);\n    } else if (provider.prompt) {\n      for (const option of options) {\n        results[option.name] = await provider.prompt(option);\n      }\n    }\n  }\n\n  return results;\n}\n\n/**\n * Check if an option is implied by another option that has been set.\n */\nfunction isOptionImplied(\n  name: string,\n  configuredImplies: Record<string, Set<string>>,\n  currentArgs: Record<string, unknown>\n): boolean {\n  for (const [trigger, implied] of Object.entries(configuredImplies)) {\n    if (implied.has(name) && currentArgs[trigger] !== undefined) {\n      return true;\n    }\n  }\n  return false;\n}\n"],"mappings":";;;;;AAYA,eAAsB,eAAe,MAMA;CACnC,MAAM,EACJ,mBACA,mBACA,eACA,WACA,gBACE;CAGJ,MAAM,oBAAoC,EAAE;AAE5C,MAAK,MAAM,CAAC,MAAM,WAAW,OAAO,QAAQ,kBAAkB,EAAE;AAE9D,MACE,SAAS,UACT,SAAS,aACT,SAAS,eACT,SAAS,KAET;EAIF,MAAM,WAAW,YAAY,UAAU,KAAA;EAEvC,MAAM,gBAAgB,cAAc,IAAI,KAAK;EAC7C,IAAI;AAEJ,MAAI,OAAO,kBAAkB,YAAY;AACvC,cAAW,cAAc,YAAY;AAErC,OAAI,aAAa,QAAQ,aAAa,KAAA,EACpC;aAEO,kBAAkB,KAAA,EAE3B,YAAW;OACN;AAEL,OAAI,SAAU;GAEd,MAAM,aAAa,OAAO,aAAa;GACvC,MAAM,YAAY,gBAAgB,MAAM,mBAAmB,YAAY;AAEvE,OAAI,CAAC,cAAc,CAAC,UAAW;AAC/B,OAAI,UAAU,WAAW,EAAG;AAE5B,cAAW;;AAGb,MAAI,aAAa,MAAO;AACxB,MAAI,YAAY,aAAa,QAAQ,OAAO,aAAa,SAAU;AAEnE,oBAAkB,KAAK;GACrB;GACA,QAAQ;IACN,GAAG;IACH,QAAQ,aAAa,OAAO,OAAO,YAAY,KAAA;IAChD;GACF,CAAC;;AAGJ,KAAI,kBAAkB,WAAW,EAC/B,QAAO,EAAE;CAIX,MAAM,oBAAoB,UAAU,QAAQ,MAAM,EAAE,OAAO;CAC3D,MAAM,oBAAoB,UAAU,QAAQ,MAAM,CAAC,EAAE,OAAO;CAE5D,MAAM,iCAAiB,IAAI,KAAqC;CAChE,MAAM,mBAAmC,EAAE;AAE3C,MAAK,MAAM,UAAU,mBAAmB;EACtC,IAAI,UAAU;AACd,OAAK,MAAM,YAAY,kBACrB,KAAI,SAAS,OAAQ,OAAO,MAAM,OAAO,OAAO,EAAE;AAChD,OAAI,CAAC,eAAe,IAAI,SAAS,CAC/B,gBAAe,IAAI,UAAU,EAAE,CAAC;AAElC,kBAAe,IAAI,SAAS,CAAE,KAAK,OAAO;AAC1C,aAAU;AACV;;AAGJ,MAAI,CAAC,QACH,kBAAiB,KAAK,OAAO;;AAKjC,KAAI,iBAAiB,SAAS,GAAG;AAC/B,MAAI,kBAAkB,WAAW,GAAG;GAClC,MAAM,QAAQ,iBAAiB,KAAK,MAAM,IAAI,EAAE,KAAK,GAAG,CAAC,KAAK,KAAK;AACnE,SAAM,IAAI,MACR,aAAa,MAAM,wDACpB;;EAEH,MAAM,WAAW,kBAAkB;AACnC,MAAI,CAAC,eAAe,IAAI,SAAS,CAC/B,gBAAe,IAAI,UAAU,EAAE,CAAC;AAElC,iBAAe,IAAI,SAAS,CAAE,KAAK,GAAG,iBAAiB;;CAIzD,MAAM,UAAmC,EAAE;AAE3C,MAAK,MAAM,CAAC,UAAU,YAAY,eAChC,KAAI,SAAS,aAAa;EACxB,MAAM,eAAe,MAAM,SAAS,YAAY,QAAQ;AACxD,SAAO,OAAO,SAAS,aAAa;YAC3B,SAAS,OAClB,MAAK,MAAM,UAAU,QACnB,SAAQ,OAAO,QAAQ,MAAM,SAAS,OAAO,OAAO;AAK1D,QAAO;;;;;AAMT,SAAS,gBACP,MACA,mBACA,aACS;AACT,MAAK,MAAM,CAAC,SAAS,YAAY,OAAO,QAAQ,kBAAkB,CAChE,KAAI,QAAQ,IAAI,KAAK,IAAI,YAAY,aAAa,KAAA,EAChD,QAAO;AAGX,QAAO"}