{"version":3,"file":"suggestions.mjs","names":[],"sources":["../../src/extension/suggestions.ts"],"sourcesContent":["import { resolveCommand, suggestSimilar } from '../core/commands.ts';\nimport { RoutingError } from '../core/errors.ts';\nimport { defineInterceptor } from '../core/interceptors.ts';\nimport { thenMaybe } from '../core/results.ts';\nimport { getKnownOptionNames } from '../core/validate.ts';\nimport type { AnyPadroneBuilder, AnyPadroneCommand, CommandTypesBase } from '../types/index.ts';\n\nfunction formatSuggestions(names: string[], prefix = ''): string {\n  if (names.length === 0) return '';\n  const quoted = names.map((n) => `\"${prefix}${n}\"`);\n  if (quoted.length === 1) return `Did you mean ${quoted[0]}?`;\n  return `Did you mean ${quoted.slice(0, -1).join(', ')} or ${quoted.at(-1)}?`;\n}\n\nfunction findSourceCommand(commandPath: string | undefined, root: AnyPadroneCommand): AnyPadroneCommand {\n  if (!commandPath || commandPath === root.name || commandPath === root.path) return root;\n  const parts = commandPath.split(' ');\n  let current = root;\n  for (const part of parts) {\n    const found = current.commands?.find((c) => {\n      resolveCommand(c);\n      return c.name === part || c.aliases?.includes(part);\n    });\n    if (found) current = found;\n    else break;\n  }\n  return current;\n}\n\nfunction enrichRoutingError(err: unknown, rootCommand: AnyPadroneCommand): unknown {\n  if (!(err instanceof RoutingError)) return err;\n\n  const unknownMatch = err.message.match(/^Unknown command: (\\S+)/);\n  const unexpectedMatch = err.message.match(/^Unexpected arguments for '[^']+': (\\S+)/);\n  const term = unknownMatch?.[1] ?? unexpectedMatch?.[1];\n  if (!term) return err;\n\n  const sourceCmd = findSourceCommand(err.command, rootCommand);\n\n  const candidateNames: string[] = [];\n  if (sourceCmd.commands) {\n    for (const cmd of sourceCmd.commands) {\n      resolveCommand(cmd);\n      if (!cmd.hidden) {\n        candidateNames.push(cmd.name);\n        if (cmd.aliases) candidateNames.push(...cmd.aliases);\n      }\n    }\n  }\n\n  const similar = suggestSimilar(term, candidateNames);\n  const suggestionText = formatSuggestions(similar);\n  if (!suggestionText) return err;\n\n  const suggestions = [suggestionText];\n  const enrichedMsg = `${err.message}\\n\\n  ${suggestionText}`;\n  return new RoutingError(enrichedMsg, { suggestions, command: err.command });\n}\n\nfunction enrichIssuesWithSuggestions(\n  issues: readonly { path?: readonly unknown[]; message: string }[],\n  knownOptions: () => string[],\n): typeof issues {\n  return issues.map((i: any) => {\n    // Handle direct unknown option detection (from checkUnknownArgs)\n    const unknownMatch = i.message?.match(/^Unknown option: \"([^\"]+)\"$/);\n    if (unknownMatch) {\n      const similar = suggestSimilar(unknownMatch[1], knownOptions());\n      if (similar.length) {\n        const hint = formatSuggestions(similar, '--');\n        return { ...i, message: `${i.message} ${hint}` };\n      }\n      return i;\n    }\n\n    // Handle Zod strict schema errors (Unrecognized key(s) in object: \"foo\")\n    const keys: string[] | undefined = i.keys ?? i.message?.match(/[Uu]nrecognized key(?:s)?[^\"]*\"([^\"]+)\"/)?.slice(1);\n    if (!keys?.length) return i;\n    const hints = keys.flatMap((k: string) => {\n      const similar = suggestSimilar(k, knownOptions());\n      return similar.length ? [formatSuggestions(similar, '--')] : [];\n    });\n    if (!hints.length) return i;\n    return { ...i, message: `${i.message} ${hints.join(' ')}` };\n  });\n}\n\nconst suggestionsInterceptor = defineInterceptor({ id: 'padrone:suggestions', name: 'padrone:suggestions', order: -500 }, () => ({\n  parse(ctx, next) {\n    try {\n      const result = next();\n      if (result instanceof Promise) {\n        return result.catch((err: unknown) => {\n          throw enrichRoutingError(err, ctx.command);\n        });\n      }\n      return result;\n    } catch (err) {\n      throw enrichRoutingError(err, ctx.command);\n    }\n  },\n  validate(ctx, next) {\n    const result = next();\n    return thenMaybe(result, (v) => {\n      if (!v.argsResult?.issues?.length) return v;\n      const enriched = enrichIssuesWithSuggestions(v.argsResult.issues, () => getKnownOptionNames(ctx.command));\n      return { ...v, argsResult: { ...v.argsResult, issues: enriched } } as typeof v;\n    });\n  },\n}));\n\nexport function padroneSuggestions(): <T extends CommandTypesBase>(builder: T) => T {\n  return ((builder: AnyPadroneBuilder) => builder.intercept(suggestionsInterceptor)) as any;\n}\n"],"mappings":"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"}