{"version":3,"file":"search-image-i8eZ4P0l.mjs","names":[],"sources":["../src/commands/search-image.ts"],"sourcesContent":["import { defineCommand } from \"citty\";\nimport { consola } from \"consola\";\nimport { sanitizeTerminalText } from \"../tui.ts\";\nimport { providerApiKeyEnvVar } from \"../core/providers.ts\";\nimport {\n  AuthError,\n  EmptyImageUrlError,\n  ImageSearchNotSupportedError,\n  InvalidImageUrlError,\n  UnknownProviderError,\n} from \"../core/errors.ts\";\nimport type { ImageSearchResult } from \"../core/types.ts\";\n\nexport default defineCommand({\n  meta: {\n    name: \"search-image\",\n    description: \"Find public pages from an image URL\",\n  },\n  args: {\n    url: {\n      type: \"positional\",\n      description: \"Public image URL\",\n      required: true,\n    },\n    provider: {\n      type: \"string\",\n      description: \"Reverse image search provider\",\n    },\n    \"max-results\": {\n      type: \"string\",\n      description: \"Maximum number of results\",\n      default: \"10\",\n    },\n    json: {\n      type: \"boolean\",\n      description: \"Output as JSON\",\n      default: false,\n    },\n  },\n  async run({ args }) {\n    const image = await import(\"../core/image.ts\");\n    const maxResults = parseMaxResults(args[\"max-results\"]);\n    try {\n      const results = await image.searchByImage(args.url, {\n        provider: args.provider?.trim() || undefined,\n        maxResults,\n      });\n      writeImageSearchResults(results, args.json);\n    } catch (error) {\n      handleImageSearchError(error, image);\n    }\n  },\n});\n\nfunction parseMaxResults(input: string): number {\n  if (!/^\\d+$/.test(input))\n    return exitWithError(\"Invalid --max-results value. Expected a positive integer.\");\n  const value = Number.parseInt(input, 10);\n  if (value < 1) return exitWithError(\"Invalid --max-results value. Expected a positive integer.\");\n  return value;\n}\n\nfunction writeImageSearchResults(\n  results: readonly Readonly<ImageSearchResult>[],\n  json: boolean,\n): void {\n  if (json) {\n    process.stdout.write(`${JSON.stringify(results, null, 2)}\\n`);\n    return;\n  }\n  if (results.length === 0) {\n    consola.info(\"No image matches found.\");\n    return;\n  }\n  for (const result of results) {\n    consola.log(\n      `\\x1B[1m\\x1B[36m${sanitizeTerminalText(result.title || \"(no title)\", 2048)}\\x1B[0m`,\n    );\n    consola.log(`  ${sanitizeTerminalText(result.pageUrl, 2048)}`);\n    consola.log(`  \\x1B[90m${sanitizeTerminalText(result.imageUrl, 2048)}\\x1B[0m`);\n    consola.log(\"\");\n  }\n}\n\nfunction handleImageSearchError(\n  error: unknown,\n  image: Readonly<Pick<typeof import(\"../core/image.ts\"), \"imageSearchProviderNames\">>,\n): never {\n  if (error instanceof EmptyImageUrlError || error instanceof InvalidImageUrlError) {\n    return exitWithError(error.message);\n  }\n  if (error instanceof AuthError) {\n    const envVar = providerApiKeyEnvVar(error.provider);\n    if (envVar !== null) consola.info(`Set the ${envVar} environment variable.`);\n    return exitWithError(`Authentication failed for provider \"${error.provider}\".`);\n  }\n  if (error instanceof UnknownProviderError) {\n    consola.info(`Reverse image search providers: ${image.imageSearchProviderNames.join(\", \")}`);\n    return exitWithError(`Unknown provider: ${error.provider}`);\n  }\n  if (error instanceof ImageSearchNotSupportedError) return exitWithError(error.message);\n  throw error;\n}\n\nfunction exitWithError(message: string): never {\n  consola.error(message);\n  process.exit(1);\n}\n"],"mappings":";;;;;;AAaA,IAAA,uBAAe,cAAc;CAC3B,MAAM;EACJ,MAAM;EACN,aAAa;CACf;CACA,MAAM;EACJ,KAAK;GACH,MAAM;GACN,aAAa;GACb,UAAU;EACZ;EACA,UAAU;GACR,MAAM;GACN,aAAa;EACf;EACA,eAAe;GACb,MAAM;GACN,aAAa;GACb,SAAS;EACX;EACA,MAAM;GACJ,MAAM;GACN,aAAa;GACb,SAAS;EACX;CACF;CACA,MAAM,IAAI,EAAE,QAAQ;EAClB,MAAM,QAAQ,MAAM,OAAO;EAC3B,MAAM,aAAa,gBAAgB,KAAK,cAAc;EACtD,IAAI;GAKF,wBAAwB,MAJF,MAAM,cAAc,KAAK,KAAK;IAClD,UAAU,KAAK,UAAU,KAAK,KAAK,KAAA;IACnC;GACF,CAAC,GACgC,KAAK,IAAI;EAC5C,SAAS,OAAO;GACd,uBAAuB,OAAO,KAAK;EACrC;CACF;AACF,CAAC;AAED,SAAS,gBAAgB,OAAuB;CAC9C,IAAI,CAAC,QAAQ,KAAK,KAAK,GACrB,OAAO,cAAc,2DAA2D;CAClF,MAAM,QAAQ,OAAO,SAAS,OAAO,EAAE;CACvC,IAAI,QAAQ,GAAG,OAAO,cAAc,2DAA2D;CAC/F,OAAO;AACT;AAEA,SAAS,wBACP,SACA,MACM;CACN,IAAI,MAAM;EACR,QAAQ,OAAO,MAAM,GAAG,KAAK,UAAU,SAAS,MAAM,CAAC,EAAE,GAAG;EAC5D;CACF;CACA,IAAI,QAAQ,WAAW,GAAG;EACxB,QAAQ,KAAK,yBAAyB;EACtC;CACF;CACA,KAAK,MAAM,UAAU,SAAS;EAC5B,QAAQ,IACN,kBAAkB,qBAAqB,OAAO,SAAS,cAAc,IAAI,EAAE,QAC7E;EACA,QAAQ,IAAI,KAAK,qBAAqB,OAAO,SAAS,IAAI,GAAG;EAC7D,QAAQ,IAAI,aAAa,qBAAqB,OAAO,UAAU,IAAI,EAAE,QAAQ;EAC7E,QAAQ,IAAI,EAAE;CAChB;AACF;AAEA,SAAS,uBACP,OACA,OACO;CACP,IAAI,iBAAiB,sBAAsB,iBAAiB,sBAC1D,OAAO,cAAc,MAAM,OAAO;CAEpC,IAAI,iBAAiB,WAAW;EAC9B,MAAM,SAAS,qBAAqB,MAAM,QAAQ;EAClD,IAAI,WAAW,MAAM,QAAQ,KAAK,WAAW,OAAO,uBAAuB;EAC3E,OAAO,cAAc,uCAAuC,MAAM,SAAS,GAAG;CAChF;CACA,IAAI,iBAAiB,sBAAsB;EACzC,QAAQ,KAAK,mCAAmC,MAAM,yBAAyB,KAAK,IAAI,GAAG;EAC3F,OAAO,cAAc,qBAAqB,MAAM,UAAU;CAC5D;CACA,IAAI,iBAAiB,8BAA8B,OAAO,cAAc,MAAM,OAAO;CACrF,MAAM;AACR;AAEA,SAAS,cAAc,SAAwB;CAC7C,QAAQ,MAAM,OAAO;CACrB,QAAQ,KAAK,CAAC;AAChB"}