@commerce-ai-tool/server 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +21 -0
  3. package/README.md +15 -0
  4. package/dist/cart-actions.d.ts +27 -0
  5. package/dist/cart-actions.d.ts.map +1 -0
  6. package/dist/cart-session.d.ts +16 -0
  7. package/dist/cart-session.d.ts.map +1 -0
  8. package/dist/checkout-actions.d.ts +17 -0
  9. package/dist/checkout-actions.d.ts.map +1 -0
  10. package/dist/chunk-GMYUJ2J6.js +339 -0
  11. package/dist/chunk-GMYUJ2J6.js.map +1 -0
  12. package/dist/chunk-PPWA5L7U.js +1321 -0
  13. package/dist/chunk-PPWA5L7U.js.map +1 -0
  14. package/dist/chunk-UGRFHLDW.js +21 -0
  15. package/dist/chunk-UGRFHLDW.js.map +1 -0
  16. package/dist/express.cjs +1306 -0
  17. package/dist/express.cjs.map +1 -0
  18. package/dist/express.d.cts +35 -0
  19. package/dist/express.d.ts +35 -0
  20. package/dist/express.d.ts.map +1 -0
  21. package/dist/express.js +164 -0
  22. package/dist/express.js.map +1 -0
  23. package/dist/flush.cjs +49 -0
  24. package/dist/flush.cjs.map +1 -0
  25. package/dist/flush.d.cts +2 -0
  26. package/dist/flush.d.ts +2 -0
  27. package/dist/flush.d.ts.map +1 -0
  28. package/dist/flush.js +11 -0
  29. package/dist/flush.js.map +1 -0
  30. package/dist/handler-response.d.ts +10 -0
  31. package/dist/handler-response.d.ts.map +1 -0
  32. package/dist/handlers.d.ts +29 -0
  33. package/dist/handlers.d.ts.map +1 -0
  34. package/dist/index.cjs +1613 -0
  35. package/dist/index.cjs.map +1 -0
  36. package/dist/index.d.cts +6 -0
  37. package/dist/index.d.ts +6 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +25 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/login-rate-limit.d.ts +22 -0
  42. package/dist/login-rate-limit.d.ts.map +1 -0
  43. package/dist/next.cjs +1511 -0
  44. package/dist/next.cjs.map +1 -0
  45. package/dist/next.d.cts +26 -0
  46. package/dist/next.d.ts +26 -0
  47. package/dist/next.d.ts.map +1 -0
  48. package/dist/next.js +9 -0
  49. package/dist/next.js.map +1 -0
  50. package/dist/observability/flush.d.ts +14 -0
  51. package/dist/observability/flush.d.ts.map +1 -0
  52. package/dist/observability/langfuse.d.ts +17 -0
  53. package/dist/observability/langfuse.d.ts.map +1 -0
  54. package/dist/order-actions.d.ts +8 -0
  55. package/dist/order-actions.d.ts.map +1 -0
  56. package/dist/payment-actions.d.ts +12 -0
  57. package/dist/payment-actions.d.ts.map +1 -0
  58. package/dist/route-actions.d.ts +43 -0
  59. package/dist/route-actions.d.ts.map +1 -0
  60. package/dist/server.d.ts +21 -0
  61. package/dist/server.d.ts.map +1 -0
  62. package/dist/utils/locale.d.ts +9 -0
  63. package/dist/utils/locale.d.ts.map +1 -0
  64. package/dist/utils/log-error.d.ts +3 -0
  65. package/dist/utils/log-error.d.ts.map +1 -0
  66. package/dist/utils/multipart.d.ts +14 -0
  67. package/dist/utils/multipart.d.ts.map +1 -0
  68. package/package.json +123 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/server.ts","../src/handler-response.ts","../src/route-actions.ts","../src/cart-session.ts","../src/login-rate-limit.ts","../src/observability/langfuse.ts","../src/observability/flush.ts","../src/utils/log-error.ts","../src/utils/locale.ts","../src/cart-actions.ts","../src/checkout-actions.ts","../src/payment-actions.ts","../src/order-actions.ts","../src/utils/multipart.ts","../src/handlers.ts","../src/next.ts"],"sourcesContent":["export {\n createCommerceAIServer,\n loadConfigFromEnv,\n type CommerceAIServer,\n type CommerceAIServerOptions,\n} from \"./server.js\";\nexport { createHandlers, type CommerceAIHandlers } from \"./handlers.js\";\nexport { createNextHandlers, type NextHandlers } from \"./next.js\";\nexport { CART_SESSION_HEADER } from \"./cart-session.js\";\nexport {\n flushLangfuse,\n registerLangfuseFlush,\n withRequestSpan,\n} from \"./observability/langfuse.js\";\n","import { ElevenLabsClient } from \"@elevenlabs/elevenlabs-js\";\nimport type { CommerceAIConfig, CommercetoolsClient, VoiceMode } from \"@commerce-ai-tool/core\";\nimport {\n createCommercetoolsClient,\n createSearchOrchestrator,\n isLangfuseEnabled,\n redactBinaryInput,\n withPipelineSpan,\n} from \"@commerce-ai-tool/core\";\nimport type { SearchOrchestrator } from \"@commerce-ai-tool/core\";\n\nexport interface CommerceAIServer {\n orchestrator: SearchOrchestrator;\n commercetools: CommercetoolsClient;\n cartDefaults: {\n currency: string;\n country?: string;\n catalogLocale: string;\n };\n cartSessionSecret: string;\n transcribeAudio(audio: Buffer, mimeType: string): Promise<string>;\n synthesizeSpeech(text: string): Promise<Buffer>;\n}\n\nexport interface CommerceAIServerOptions {\n config: CommerceAIConfig;\n corsOrigins?: string | string[];\n}\n\nexport function createCommerceAIServer(options: CommerceAIServerOptions): CommerceAIServer {\n const { config } = options;\n const voiceMode = resolveVoiceMode(config);\n const elevenlabs = config.elevenlabs ? createElevenLabsClient(config.elevenlabs) : null;\n\n const commercetools = createCommercetoolsClient(config.commercetools, {\n payments: config.payments,\n });\n const orchestrator = createSearchOrchestrator({\n config,\n commercetoolsClient: commercetools,\n transcribeAudio:\n voiceMode === \"elevenlabs-stt\" && elevenlabs\n ? async (audio, mimeType) =>\n withElevenLabsSpan(\"elevenlabs.stt\", { audio: redactBinaryInput(mimeType, audio) }, () =>\n transcribeWithElevenLabs(elevenlabs, audio, mimeType, config),\n )\n : undefined,\n });\n\n return {\n orchestrator,\n commercetools,\n cartDefaults: {\n currency: config.defaults?.currency ?? \"EUR\",\n country: config.defaults?.country,\n catalogLocale: config.defaults?.catalogLocale ?? config.defaults?.locale ?? \"en\",\n },\n cartSessionSecret:\n process.env.CAT_CART_SESSION_SECRET?.trim() || config.commercetools.clientSecret,\n async transcribeAudio(audio, mimeType) {\n if (!elevenlabs) {\n throw new Error(\"ElevenLabs is not configured\");\n }\n return withElevenLabsSpan(\n \"elevenlabs.stt\",\n { audio: redactBinaryInput(mimeType, audio) },\n () => transcribeWithElevenLabs(elevenlabs, audio, mimeType, config),\n );\n },\n async synthesizeSpeech(text) {\n if (!elevenlabs) {\n throw new Error(\"ElevenLabs is not configured\");\n }\n\n return withElevenLabsSpan(\"elevenlabs.tts\", { input: { textLength: text.length } }, async () => {\n const voiceId = config.elevenlabs?.ttsVoiceId ?? \"JBFqnCBsd6RMkjVDRZzb\";\n const audio = await elevenlabs.textToSpeech.convert(voiceId, {\n text,\n modelId: config.elevenlabs?.ttsModel ?? \"eleven_multilingual_v2\",\n outputFormat: \"mp3_44100_128\",\n });\n\n const chunks: Uint8Array[] = [];\n for await (const chunk of audio as AsyncIterable<Uint8Array>) {\n chunks.push(chunk);\n }\n\n return Buffer.concat(chunks);\n });\n },\n };\n}\n\nasync function withElevenLabsSpan<T>(\n name: string,\n attributes: { input?: unknown; audio?: unknown },\n fn: () => Promise<T>,\n): Promise<T> {\n return withPipelineSpan(\n name,\n {\n input: attributes.input ?? attributes.audio,\n metadata: { vendor: \"elevenlabs\" },\n },\n async (span) => {\n const result = await fn();\n if (typeof result === \"string\") {\n span?.update({ output: { transcriptLength: result.length } });\n } else if (Buffer.isBuffer(result)) {\n span?.update({ output: { byteLength: result.byteLength } });\n }\n return result;\n },\n );\n}\n\nfunction createElevenLabsClient(config: import(\"@commerce-ai-tool/core\").ElevenLabsConfig): ElevenLabsClient {\n return new ElevenLabsClient({ apiKey: config.apiKey });\n}\n\nasync function transcribeWithElevenLabs(\n elevenlabs: ElevenLabsClient,\n audio: Uint8Array,\n mimeType: string,\n config: CommerceAIConfig,\n): Promise<string> {\n const blob = new Blob([audio], { type: mimeType });\n const result = await elevenlabs.speechToText.convert({\n file: blob,\n modelId: getSttModelId(config.elevenlabs?.sttModel),\n });\n\n if (typeof result === \"string\") {\n return result;\n }\n\n if (\"text\" in result && typeof result.text === \"string\") {\n return result.text;\n }\n\n throw new Error(\"Failed to transcribe audio\");\n}\n\nfunction resolveVoiceMode(config: CommerceAIConfig): VoiceMode {\n if (config.voiceMode) {\n return config.voiceMode;\n }\n\n if (config.ai.provider === \"openrouter\") {\n return \"openrouter-audio\";\n }\n\n return \"elevenlabs-stt\";\n}\n\nfunction getSttModelId(model?: string): \"scribe_v2\" {\n return model === \"scribe_v2\" ? \"scribe_v2\" : \"scribe_v2\";\n}\n\nexport function loadConfigFromEnv(): CommerceAIConfig {\n const provider = (process.env.CAT_AI_PROVIDER ?? \"openrouter\") as \"openrouter\" | \"bedrock\";\n const voiceMode = process.env.CAT_VOICE_MODE as VoiceMode | undefined;\n const cacheTtlMs = process.env.CAT_CACHE_TTL_MS\n ? Number(process.env.CAT_CACHE_TTL_MS)\n : undefined;\n\n return {\n commercetools: {\n projectKey: requiredEnv(\"CTP_PROJECT_KEY\"),\n clientId: requiredEnv(\"CTP_CLIENT_ID\"),\n clientSecret: requiredEnv(\"CTP_CLIENT_SECRET\"),\n region: requiredEnv(\"CTP_REGION\"),\n },\n ai: {\n provider,\n openrouter:\n provider === \"openrouter\"\n ? {\n apiKey: requiredEnv(\"OPENROUTER_API_KEY\"),\n model: process.env.OPENROUTER_MODEL,\n visionModel: process.env.OPENROUTER_VISION_MODEL,\n voiceModel: process.env.OPENROUTER_VOICE_MODEL,\n jsonSchema: process.env.OPENROUTER_JSON_SCHEMA === \"false\" ? false : undefined,\n }\n : undefined,\n bedrock:\n provider === \"bedrock\"\n ? {\n region: requiredEnv(\"AWS_REGION\"),\n modelId: process.env.BEDROCK_MODEL_ID,\n visionModelId: process.env.BEDROCK_VISION_MODEL_ID,\n }\n : undefined,\n },\n elevenlabs: process.env.ELEVENLABS_API_KEY\n ? {\n apiKey: process.env.ELEVENLABS_API_KEY,\n sttModel: process.env.ELEVENLABS_STT_MODEL,\n ttsVoiceId: process.env.ELEVENLABS_TTS_VOICE_ID,\n ttsModel: process.env.ELEVENLABS_TTS_MODEL,\n }\n : undefined,\n defaults: {\n catalogLocale:\n process.env.CAT_CATALOG_LOCALE ?? process.env.CAT_DEFAULT_LOCALE ?? \"en\",\n locale: process.env.CAT_DEFAULT_LOCALE,\n currency: process.env.CAT_DEFAULT_CURRENCY ?? \"EUR\",\n country: process.env.CAT_DEFAULT_COUNTRY,\n limit: process.env.CAT_DEFAULT_LIMIT ? Number(process.env.CAT_DEFAULT_LIMIT) : 20,\n storeKey: process.env.CAT_STORE_KEY,\n },\n voiceMode,\n cache: cacheTtlMs\n ? {\n ttlMs: cacheTtlMs,\n maxEntries: process.env.CAT_CACHE_MAX_ENTRIES\n ? Number(process.env.CAT_CACHE_MAX_ENTRIES)\n : undefined,\n }\n : process.env.CAT_CACHE_ENABLED === \"true\"\n ? {}\n : undefined,\n missions:\n process.env.CAT_MISSIONS_ENABLED === \"true\"\n ? {\n enabled: true,\n maxIntents: process.env.CAT_MISSIONS_MAX_INTENTS\n ? Number(process.env.CAT_MISSIONS_MAX_INTENTS)\n : undefined,\n perIntentLimit: process.env.CAT_MISSIONS_PER_INTENT_LIMIT\n ? Number(process.env.CAT_MISSIONS_PER_INTENT_LIMIT)\n : undefined,\n minConfidence: process.env.CAT_MISSIONS_MIN_CONFIDENCE\n ? Number(process.env.CAT_MISSIONS_MIN_CONFIDENCE)\n : undefined,\n }\n : undefined,\n facets:\n process.env.CAT_FACETS_ENABLED === \"true\"\n ? {\n enabled: true,\n schemaTtlMs: process.env.CAT_FACET_SCHEMA_TTL_MS\n ? Number(process.env.CAT_FACET_SCHEMA_TTL_MS)\n : undefined,\n include: parseCsvEnv(process.env.CAT_FACET_INCLUDE),\n exclude: parseCsvEnv(process.env.CAT_FACET_EXCLUDE),\n maxAttributes: process.env.CAT_FACET_MAX_ATTRIBUTES\n ? Number(process.env.CAT_FACET_MAX_ATTRIBUTES)\n : undefined,\n }\n : undefined,\n payments:\n process.env.CAT_PAYMENT_REQUIRED === \"true\"\n ? { requiredForOrder: true }\n : process.env.CAT_PAYMENT_REQUIRED === \"false\"\n ? { requiredForOrder: false }\n : undefined,\n langfuse: {\n enabled: isLangfuseEnabled(),\n promptsEnabled: process.env.LANGFUSE_PROMPTS === \"true\",\n promptLabel: process.env.LANGFUSE_PROMPT_LABEL?.trim() || undefined,\n promptCacheTtlSeconds: (() => {\n const raw = process.env.LANGFUSE_PROMPT_CACHE_TTL_SECONDS;\n if (!raw) {\n return undefined;\n }\n const parsed = Number(raw);\n return Number.isFinite(parsed) && parsed >= 0 ? parsed : undefined;\n })(),\n },\n };\n}\n\nfunction parseCsvEnv(value: string | undefined): string[] | undefined {\n const values = value?.split(\",\").map((item) => item.trim()).filter(Boolean);\n return values?.length ? values : undefined;\n}\n\nfunction requiredEnv(name: string): string {\n const value = process.env[name];\n if (!value) {\n throw new Error(`Missing required environment variable: ${name}`);\n }\n return value;\n}\n","export interface HandlerResponse {\n status: number;\n headers?: Record<string, string>;\n body: string | Buffer;\n}\n\nexport function jsonResponse(data: unknown, status = 200): HandlerResponse {\n return {\n status,\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(data),\n };\n}\n\nexport function errorResponse(message: string, status = 500): HandlerResponse {\n return jsonResponse({ error: message }, status);\n}\n\nexport function toWebResponse(handlerResponse: HandlerResponse): Response {\n const headers = new Headers(handlerResponse.headers);\n const body =\n typeof handlerResponse.body === \"string\"\n ? handlerResponse.body\n : new Uint8Array(handlerResponse.body);\n\n return new Response(body, { status: handlerResponse.status, headers });\n}\n\nexport function toWebErrorResponse(\n message: string,\n status = 500,\n): Response {\n return Response.json({ error: message }, { status });\n}\n","import {\n CartAccessDeniedError,\n CartNotFoundError,\n CheckoutIncompleteError,\n InvalidCredentialsError,\n logSearchTrace,\n OrderNotFoundError,\n PaymentDeclinedError,\n PaymentNotConfiguredError,\n SearchTimeoutError,\n MissingPriceError,\n} from \"@commerce-ai-tool/core\";\nimport { InvalidCartSessionError } from \"./cart-session.js\";\nimport { TooManyRequestsError } from \"./login-rate-limit.js\";\nimport type {\n InterpretedSearchFilters,\n SuggestedFacet,\n VoiceSearchResult,\n} from \"@commerce-ai-tool/core\";\nimport {\n clampSuggestionsLimit,\n normalizeSuggestionsPrefix,\n} from \"@commerce-ai-tool/core\";\nimport { redactBinaryInput, withOptionalRequestSpan, withRequestSpan, shouldTraceSuggestions, flushLangfuse, isLangfuseEnabled } from \"./observability/langfuse.js\";\nimport type { CommerceAIServer } from \"./server.js\";\nimport { logServerError, logServerWarning } from \"./utils/log-error.js\";\nimport { parseSearchLocaleOptions } from \"./utils/locale.js\";\nimport type { ParsedMultipart } from \"./utils/multipart.js\";\n\nfunction parseOptionalBoolean(value: string | undefined): boolean | undefined {\n if (value === \"true\") {\n return true;\n }\n if (value === \"false\") {\n return false;\n }\n return undefined;\n}\n\nexport class ValidationError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ValidationError\";\n }\n}\n\nexport interface SearchRequestBody {\n query: string;\n queryLocale?: string;\n catalogLocale?: string;\n locale?: string;\n limit?: number;\n filters?: InterpretedSearchFilters;\n searchTerms?: string[];\n sort?: \"relevance\" | \"price_asc\" | \"price_desc\";\n refineQuery?: string;\n includeFacets?: boolean;\n suggestedFacets?: SuggestedFacet[];\n enableMissions?: boolean;\n}\n\nexport interface SuggestionsRequestBody {\n query: string;\n queryLocale?: string;\n catalogLocale?: string;\n locale?: string;\n limit?: number;\n}\n\nexport type VoiceSearchResponse = VoiceSearchResult & {\n ttsText?: string;\n audioSummary?: string;\n ttsPending: boolean;\n};\n\nexport function mapRouteError(\n error: unknown,\n context: string,\n fallback: string,\n extra?: Record<string, unknown>,\n): { message: string; status: number } {\n if (error instanceof SearchTimeoutError) {\n return { message: error.message, status: 504 };\n }\n\n if (error instanceof ValidationError || error instanceof CheckoutIncompleteError) {\n return { message: error.message, status: 400 };\n }\n\n if (error instanceof MissingPriceError) {\n return { message: error.message, status: 400 };\n }\n\n if (error instanceof PaymentDeclinedError) {\n return { message: error.message, status: 402 };\n }\n\n if (error instanceof PaymentNotConfiguredError) {\n return { message: error.message, status: 400 };\n }\n\n if (error instanceof CartNotFoundError || error instanceof OrderNotFoundError) {\n return { message: error.message, status: 404 };\n }\n\n if (error instanceof CartAccessDeniedError) {\n return { message: error.message, status: 403 };\n }\n\n if (error instanceof InvalidCredentialsError || error instanceof InvalidCartSessionError) {\n return { message: error.message, status: 401 };\n }\n\n if (error instanceof TooManyRequestsError) {\n return { message: error.message, status: 429 };\n }\n\n logServerError(context, error, extra);\n return {\n message: error instanceof Error ? error.message : fallback,\n status: 500,\n };\n}\n\nexport async function executeSearch(\n server: CommerceAIServer,\n body: SearchRequestBody,\n): Promise<unknown> {\n if (!body.query?.trim()) {\n throw new ValidationError(\"query is required\");\n }\n if (body.refineQuery && (!body.searchTerms || body.searchTerms.length === 0)) {\n throw new ValidationError(\"searchTerms are required for a refinement\");\n }\n\n const localeOptions = parseSearchLocaleOptions(body);\n logSearchTrace(\"handler\", {\n type: \"text\",\n query: body.query,\n queryLocale: localeOptions.queryLocale,\n catalogLocale: localeOptions.catalogLocale,\n });\n\n return withRequestSpan(\n \"commerce-ai.search\",\n {\n input: { query: body.query, refineQuery: body.refineQuery },\n metadata: {\n searchType: \"text\",\n queryLocale: localeOptions.queryLocale ?? \"\",\n catalogLocale: localeOptions.catalogLocale ?? \"\",\n },\n },\n () =>\n server.orchestrator.searchByText({\n query: body.query,\n ...localeOptions,\n limit: body.limit,\n filters: body.filters,\n searchTerms: body.searchTerms,\n sort: body.sort,\n refineQuery: body.refineQuery,\n includeFacets: body.includeFacets,\n suggestedFacets: body.suggestedFacets,\n enableMissions: body.enableMissions,\n }),\n );\n}\n\nexport async function executeFacetSchema(\n server: CommerceAIServer,\n options?: SearchRequestBody,\n): Promise<unknown> {\n if (!server.orchestrator.getFacetSchema) {\n throw new Error(\"Facet schema is not available\");\n }\n return server.orchestrator.getFacetSchema(options);\n}\n\nexport async function executeSearchSuggestions(\n server: CommerceAIServer,\n body: SuggestionsRequestBody,\n): Promise<unknown> {\n const normalizedQuery = normalizeSuggestionsPrefix(body.query ?? \"\");\n if (!normalizedQuery) {\n throw new ValidationError(\"query must be at least 2 characters\");\n }\n\n const localeOptions = parseSearchLocaleOptions(body);\n logSearchTrace(\"handler\", {\n type: \"suggest\",\n query: normalizedQuery,\n queryLocale: localeOptions.queryLocale,\n catalogLocale: localeOptions.catalogLocale,\n });\n\n return withOptionalRequestSpan(\n shouldTraceSuggestions(),\n \"commerce-ai.search.suggestions\",\n {\n input: { query: normalizedQuery },\n metadata: {\n searchType: \"suggest\",\n queryLocale: localeOptions.queryLocale ?? \"\",\n catalogLocale: localeOptions.catalogLocale ?? \"\",\n },\n },\n async () => {\n const result = await server.orchestrator.suggestByText({\n query: normalizedQuery,\n ...localeOptions,\n limit: clampSuggestionsLimit(body.limit),\n });\n\n // AI fallback emits generations even when the Suggest request span is skipped;\n // flush so serverless isolates do not drop them.\n if (!shouldTraceSuggestions() && result.aiFallbackUsed && isLangfuseEnabled()) {\n await flushLangfuse();\n }\n\n return result;\n },\n );\n}\n\nexport async function executeSearchVoice(\n server: CommerceAIServer,\n fields: Record<string, string>,\n file: ParsedMultipart[\"file\"],\n): Promise<VoiceSearchResponse> {\n if (!file) {\n throw new ValidationError(\"audio file is required\");\n }\n\n const localeOptions = parseSearchLocaleOptions(fields);\n logSearchTrace(\"handler\", {\n type: \"voice\",\n mimeType: file.mimeType,\n queryLocale: localeOptions.queryLocale,\n catalogLocale: localeOptions.catalogLocale,\n });\n\n return withRequestSpan(\n \"commerce-ai.search.voice\",\n {\n input: { audio: redactBinaryInput(file.mimeType, file.buffer) },\n metadata: {\n searchType: \"voice\",\n queryLocale: localeOptions.queryLocale ?? \"\",\n catalogLocale: localeOptions.catalogLocale ?? \"\",\n },\n },\n async () => {\n const result = await server.orchestrator.searchByVoice(\n new Uint8Array(file.buffer),\n file.mimeType,\n {\n ...localeOptions,\n limit: fields.limit ? Number(fields.limit) : undefined,\n enableTts: fields.enableTts !== \"false\",\n enableMissions: parseOptionalBoolean(fields.enableMissions),\n },\n );\n\n const blockingTts = fields.blockingTts === \"true\";\n let audioSummary: string | undefined;\n if (blockingTts && result.ttsText) {\n try {\n const audio = await server.synthesizeSpeech(result.ttsText);\n audioSummary = audio.toString(\"base64\");\n } catch (error) {\n logServerWarning(\"searchVoice\", \"TTS summary skipped\", {\n reason: error instanceof Error ? error.message : \"unknown\",\n });\n }\n }\n\n return {\n transcript: result.transcript,\n enhancedQuery: result.enhancedQuery,\n products: result.products,\n meta: result.meta,\n mission: result.mission,\n ttsText: result.ttsText,\n audioSummary,\n ttsPending: Boolean(result.ttsText && !audioSummary),\n };\n },\n );\n}\n\nexport async function executeSearchImage(\n server: CommerceAIServer,\n fields: Record<string, string>,\n file: ParsedMultipart[\"file\"],\n): Promise<unknown> {\n if (!file) {\n throw new ValidationError(\"image file is required\");\n }\n\n const localeOptions = parseSearchLocaleOptions(fields);\n logSearchTrace(\"handler\", {\n type: \"image\",\n mimeType: file.mimeType,\n queryLocale: localeOptions.queryLocale,\n catalogLocale: localeOptions.catalogLocale,\n });\n\n return withRequestSpan(\n \"commerce-ai.search.image\",\n {\n input: { image: redactBinaryInput(file.mimeType, file.buffer) },\n metadata: {\n searchType: \"image\",\n queryLocale: localeOptions.queryLocale ?? \"\",\n catalogLocale: localeOptions.catalogLocale ?? \"\",\n },\n },\n () =>\n server.orchestrator.searchByImage(new Uint8Array(file.buffer), file.mimeType, {\n ...localeOptions,\n limit: fields.limit ? Number(fields.limit) : undefined,\n enableMissions: parseOptionalBoolean(fields.enableMissions),\n }),\n );\n}\n\nexport async function executeTts(\n server: CommerceAIServer,\n text: string,\n): Promise<Buffer> {\n if (!text.trim()) {\n throw new ValidationError(\"text is required\");\n }\n\n return withRequestSpan(\n \"commerce-ai.tts\",\n {\n input: { textLength: text.length },\n metadata: { searchType: \"tts\" },\n },\n () => server.synthesizeSpeech(text),\n );\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport type { IncomingHttpHeaders } from \"node:http\";\nimport { CART_SESSION_HEADER } from \"@commerce-ai-tool/core\";\n\nexport { CART_SESSION_HEADER };\n\nexport function readCartSessionHeader(\n headers: Headers | IncomingHttpHeaders | undefined,\n): string | undefined {\n if (!headers) {\n return undefined;\n }\n\n if (typeof (headers as Headers).get === \"function\") {\n const value = (headers as Headers).get(CART_SESSION_HEADER);\n const trimmed = value?.trim();\n return trimmed || undefined;\n }\n\n const raw = (headers as IncomingHttpHeaders)[CART_SESSION_HEADER];\n const value = Array.isArray(raw) ? raw[0] : raw;\n const trimmed = value?.trim();\n return trimmed || undefined;\n}\n\nexport const CART_SESSION_TTL_SECONDS = 60 * 60 * 24 * 7;\n\nexport interface CartSessionPayload {\n customerId: string;\n email: string;\n exp: number;\n}\n\nexport class InvalidCartSessionError extends Error {\n constructor(message = \"Invalid cart session\") {\n super(message);\n this.name = \"InvalidCartSessionError\";\n }\n}\n\nexport function signCartSession(\n payload: Omit<CartSessionPayload, \"exp\">,\n secret: string,\n nowSeconds = Math.floor(Date.now() / 1000),\n): string {\n const body: CartSessionPayload = {\n customerId: payload.customerId,\n email: payload.email,\n exp: nowSeconds + CART_SESSION_TTL_SECONDS,\n };\n const encoded = Buffer.from(JSON.stringify(body), \"utf8\").toString(\"base64url\");\n const signature = createHmac(\"sha256\", secret).update(encoded).digest(\"base64url\");\n return `${encoded}.${signature}`;\n}\n\nexport function verifyCartSession(token: string, secret: string): CartSessionPayload {\n const [encoded, signature] = token.split(\".\");\n if (!encoded || !signature) {\n throw new InvalidCartSessionError();\n }\n\n const expected = createHmac(\"sha256\", secret).update(encoded).digest(\"base64url\");\n const actualBuffer = Buffer.from(signature);\n const expectedBuffer = Buffer.from(expected);\n if (actualBuffer.length !== expectedBuffer.length || !timingSafeEqual(actualBuffer, expectedBuffer)) {\n throw new InvalidCartSessionError();\n }\n\n let payload: CartSessionPayload;\n try {\n payload = JSON.parse(Buffer.from(encoded, \"base64url\").toString(\"utf8\")) as CartSessionPayload;\n } catch {\n throw new InvalidCartSessionError();\n }\n\n if (\n typeof payload.customerId !== \"string\" ||\n !payload.customerId ||\n typeof payload.email !== \"string\" ||\n typeof payload.exp !== \"number\"\n ) {\n throw new InvalidCartSessionError();\n }\n\n if (payload.exp < Math.floor(Date.now() / 1000)) {\n throw new InvalidCartSessionError(\"Cart session expired\");\n }\n\n return payload;\n}\n","export const LOGIN_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000;\nexport const LOGIN_RATE_LIMIT_MAX_ATTEMPTS = 10;\nexport const LOGIN_RATE_LIMIT_MESSAGE = \"Too many login attempts. Try again later.\";\n\nexport const ORDER_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000;\nexport const ORDER_RATE_LIMIT_MAX_ATTEMPTS = 20;\nexport const ORDER_RATE_LIMIT_MESSAGE = \"Too many order attempts. Try again later.\";\n\nexport const PAYMENT_RATE_LIMIT_WINDOW_MS = 15 * 60 * 1000;\nexport const PAYMENT_RATE_LIMIT_MAX_ATTEMPTS = 20;\nexport const PAYMENT_RATE_LIMIT_MESSAGE = \"Too many payment attempts. Try again later.\";\n\nexport class TooManyRequestsError extends Error {\n readonly retryAfterSeconds: number;\n\n constructor(retryAfterSeconds: number, message = LOGIN_RATE_LIMIT_MESSAGE) {\n super(message);\n this.name = \"TooManyRequestsError\";\n this.retryAfterSeconds = retryAfterSeconds;\n }\n}\n\nexport interface LoginAttemptLimiter {\n consume(key: string): void;\n}\n\nexport function createLoginAttemptLimiter(\n options: { windowMs?: number; limit?: number } = {},\n): LoginAttemptLimiter {\n const windowMs = options.windowMs ?? LOGIN_RATE_LIMIT_WINDOW_MS;\n const limit = options.limit ?? LOGIN_RATE_LIMIT_MAX_ATTEMPTS;\n const attempts = new Map<string, { count: number; resetAt: number }>();\n\n return {\n consume(key: string) {\n const now = Date.now();\n const current = attempts.get(key);\n\n if (!current || current.resetAt <= now) {\n attempts.set(key, { count: 1, resetAt: now + windowMs });\n return;\n }\n\n if (current.count >= limit) {\n throw new TooManyRequestsError(Math.max(1, Math.ceil((current.resetAt - now) / 1000)));\n }\n\n current.count += 1;\n },\n };\n}\n\nexport function clientKeyFromWebHeaders(headers: Headers): string {\n const forwarded = headers.get(\"x-forwarded-for\");\n if (forwarded) {\n const first = forwarded.split(\",\")[0]?.trim();\n if (first) {\n return first;\n }\n }\n\n const realIp = headers.get(\"x-real-ip\")?.trim();\n return realIp || \"local\";\n}\n","import {\n isLangfuseEnabled,\n redactBinaryInput,\n shouldTraceSuggestions,\n withPipelineSpan,\n} from \"@commerce-ai-tool/core\";\nimport { flushLangfuse } from \"./flush.js\";\n\nexport { flushLangfuse, registerLangfuseFlush } from \"./flush.js\";\n\nexport async function withRequestSpan<T>(\n name: string,\n attributes: { input?: unknown; metadata?: Record<string, unknown> },\n fn: () => Promise<T>,\n): Promise<T> {\n return withPipelineSpan(name, attributes, async (span) => {\n try {\n const result = await fn();\n span?.update({ output: summarizeResult(result) });\n return result;\n } finally {\n await flushLangfuse();\n }\n });\n}\n\n/**\n * Run a handler without creating a Langfuse span (still no flush).\n * Used for high-volume autocomplete unless LANGFUSE_TRACE_SUGGESTIONS=true.\n */\nexport async function withOptionalRequestSpan<T>(\n enabled: boolean,\n name: string,\n attributes: { input?: unknown; metadata?: Record<string, unknown> },\n fn: () => Promise<T>,\n): Promise<T> {\n if (!enabled) {\n return fn();\n }\n return withRequestSpan(name, attributes, fn);\n}\n\nexport { shouldTraceSuggestions };\n\nfunction summarizeResult(result: unknown): unknown {\n if (!result || typeof result !== \"object\") {\n return undefined;\n }\n\n const record = result as {\n meta?: {\n total?: number;\n traceId?: string;\n searchTerms?: string[];\n queryInterpretation?: string;\n };\n products?: unknown[];\n transcript?: string;\n interpretation?: string;\n };\n\n if (\"products\" in record || \"meta\" in record) {\n return {\n total: record.meta?.total,\n productCount: Array.isArray(record.products) ? record.products.length : undefined,\n traceId: record.meta?.traceId,\n hasTranscript: Boolean(record.transcript),\n transcript: typeof record.transcript === \"string\" ? record.transcript : undefined,\n searchTerms: record.meta?.searchTerms,\n interpretation: record.meta?.queryInterpretation ?? record.interpretation,\n };\n }\n\n if (Buffer.isBuffer(result)) {\n return { byteLength: result.byteLength };\n }\n\n return undefined;\n}\n\nexport { redactBinaryInput, isLangfuseEnabled };\n","type FlushFn = () => Promise<void>;\n\nconst FLUSH_GLOBAL_KEY = \"__commerceAiToolLangfuseFlush__\" as const;\n\ntype FlushGlobal = typeof globalThis & {\n [FLUSH_GLOBAL_KEY]?: FlushFn | null;\n};\n\n/**\n * Host apps (e.g. demo-next instrumentation) register LangfuseSpanProcessor.forceFlush here\n * so serverless handlers can flush before the isolate freezes.\n *\n * Uses globalThis so Next.js instrumentation can register without importing this package\n * (avoids pulling Express into the Edge instrumentation graph).\n */\nexport function registerLangfuseFlush(fn: FlushFn | null): void {\n (globalThis as FlushGlobal)[FLUSH_GLOBAL_KEY] = fn;\n}\n\nexport async function flushLangfuse(): Promise<void> {\n const hasKeys = Boolean(process.env.LANGFUSE_PUBLIC_KEY && process.env.LANGFUSE_SECRET_KEY);\n const registeredFlush = (globalThis as FlushGlobal)[FLUSH_GLOBAL_KEY];\n if (!hasKeys || !registeredFlush) {\n return;\n }\n await registeredFlush();\n}\n\n/** Shared key for hosts that register flush without importing this module. */\nexport const LANGFUSE_FLUSH_GLOBAL_KEY = FLUSH_GLOBAL_KEY;\n","function isDevLoggingEnabled(): boolean {\n return process.env.NODE_ENV !== \"production\" || process.env.CAT_DEBUG === \"true\";\n}\n\nfunction formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n\n if (typeof error === \"string\") {\n return error;\n }\n\n try {\n return JSON.stringify(error);\n } catch {\n return String(error);\n }\n}\n\nexport function logServerError(handler: string, error: unknown, context?: Record<string, unknown>): void {\n if (!isDevLoggingEnabled()) {\n return;\n }\n\n const prefix = `[commerce-ai-tool/server] ${handler}`;\n\n console.error(`${prefix} failed: ${formatError(error)}`);\n\n if (context && Object.keys(context).length > 0) {\n console.error(`${prefix} context:`, context);\n }\n\n if (error instanceof Error && error.stack) {\n console.error(error.stack);\n }\n\n if (error instanceof Error && error.cause) {\n console.error(`${prefix} caused by:`, error.cause);\n }\n}\n\nexport function logServerWarning(handler: string, message: string, context?: Record<string, unknown>): void {\n if (!isDevLoggingEnabled()) {\n return;\n }\n\n const prefix = `[commerce-ai-tool/server] ${handler}`;\n console.warn(`${prefix}: ${message}`);\n\n if (context && Object.keys(context).length > 0) {\n console.warn(`${prefix} context:`, context);\n }\n}\n","import type { SearchLocaleOptions } from \"@commerce-ai-tool/core\";\n\nexport interface SearchLocaleRequestFields {\n queryLocale?: string;\n catalogLocale?: string;\n /** @deprecated Use queryLocale */\n locale?: string;\n}\n\nexport function parseSearchLocaleOptions(\n fields: SearchLocaleRequestFields,\n): SearchLocaleOptions {\n return {\n queryLocale: fields.queryLocale ?? fields.locale,\n catalogLocale: fields.catalogLocale,\n locale: fields.locale,\n };\n}\n","import {\n MAX_LINE_ITEM_QUANTITY,\n type AddItemsToCartRequest,\n type AddToCartRequest,\n type CartLoginRequest,\n type CartMutationRequest,\n type CartSnapshot,\n type CustomerSnapshot,\n type GetCartRequest,\n type UpdateCartQuantityRequest,\n} from \"@commerce-ai-tool/core\";\nimport type { CommerceAIServer } from \"./server.js\";\nimport { ValidationError } from \"./route-actions.js\";\nimport { signCartSession, verifyCartSession } from \"./cart-session.js\";\n\nexport interface CartResponse {\n cart: CartSnapshot | null;\n}\n\nexport interface CartAuthResponse extends CartResponse {\n customer: CustomerSnapshot | null;\n sessionToken?: string;\n}\n\nexport const ANONYMOUS_ID_MAX_LENGTH = 128;\n\nfunction requiredAnonymousId(value: unknown): string {\n const anonymousId = requiredString(value, \"anonymousId\");\n if (anonymousId.length > ANONYMOUS_ID_MAX_LENGTH) {\n throw new ValidationError(\"anonymousId is too long\");\n }\n return anonymousId;\n}\n\nfunction optionalAnonymousId(value: unknown): string | undefined {\n if (typeof value !== \"string\" || !value.trim()) {\n return undefined;\n }\n if (value.trim().length > ANONYMOUS_ID_MAX_LENGTH) {\n throw new ValidationError(\"anonymousId is too long\");\n }\n return value.trim();\n}\n\nexport function requiredString(value: unknown, field: string): string {\n if (typeof value !== \"string\" || !value.trim()) {\n throw new ValidationError(`${field} is required`);\n }\n return value.trim();\n}\n\nexport function optionalString(value: unknown): string | undefined {\n if (typeof value !== \"string\") {\n return undefined;\n }\n const trimmed = value.trim();\n return trimmed || undefined;\n}\n\nfunction optionalNumber(value: unknown): number | undefined {\n if (value === undefined || value === null || value === \"\") {\n return undefined;\n }\n const parsed = typeof value === \"number\" ? value : Number(value);\n if (!Number.isFinite(parsed)) {\n throw new ValidationError(\"quantity must be a number\");\n }\n return parsed;\n}\n\nexport function resolveLocale(server: CommerceAIServer, catalogLocale?: string): string {\n return catalogLocale?.trim() || server.cartDefaults.catalogLocale;\n}\n\nexport interface ResolvedCartIdentity {\n anonymousId?: string;\n customerId?: string;\n}\n\nexport function resolveCartIdentity(\n server: CommerceAIServer,\n sessionToken: unknown,\n anonymousId: unknown,\n): ResolvedCartIdentity {\n const token = optionalString(sessionToken);\n if (token) {\n const session = verifyCartSession(token, server.cartSessionSecret);\n return { customerId: session.customerId };\n }\n\n return { anonymousId: requiredAnonymousId(anonymousId) };\n}\n\nexport async function executeGetCart(\n server: CommerceAIServer,\n body: GetCartRequest,\n): Promise<CartResponse> {\n const identity = resolveCartIdentity(server, body.sessionToken, body.anonymousId);\n const locale = resolveLocale(server, body.catalogLocale);\n const cart = identity.customerId\n ? await server.commercetools.getCustomerCart(identity.customerId, locale)\n : await server.commercetools.getCart(identity.anonymousId ?? \"\", locale);\n return { cart };\n}\n\nexport async function executeAddToCart(\n server: CommerceAIServer,\n body: AddToCartRequest,\n): Promise<CartResponse> {\n const identity = resolveCartIdentity(server, body.sessionToken, body.anonymousId);\n const sku = optionalString(body.sku);\n const productId = optionalString(body.productId);\n if (!sku && !productId) {\n throw new ValidationError(\"sku or productId is required\");\n }\n\n const quantity = optionalNumber(body.quantity) ?? 1;\n if (quantity < 1) {\n throw new ValidationError(\"quantity must be at least 1\");\n }\n\n const cart = await server.commercetools.addToCart({\n anonymousId: identity.anonymousId,\n customerId: identity.customerId,\n sku,\n productId,\n variantId: body.variantId,\n quantity,\n currency: optionalString(body.currency) ?? server.cartDefaults.currency,\n country: optionalString(body.country) ?? server.cartDefaults.country,\n catalogLocale: resolveLocale(server, body.catalogLocale),\n cartId: optionalString(body.cartId),\n });\n\n return { cart };\n}\n\nexport const MAX_ADD_ITEMS = 20;\n\nexport async function executeAddItemsToCart(\n server: CommerceAIServer,\n body: AddItemsToCartRequest,\n): Promise<CartResponse> {\n const identity = resolveCartIdentity(server, body.sessionToken, body.anonymousId);\n if (!Array.isArray(body.items) || body.items.length === 0) {\n throw new ValidationError(\"items is required\");\n }\n if (body.items.length > MAX_ADD_ITEMS) {\n throw new ValidationError(`items must not exceed ${MAX_ADD_ITEMS}`);\n }\n\n const items = body.items.map((item, index) => {\n const sku = optionalString(item.sku);\n const productId = optionalString(item.productId);\n if (!sku && !productId) {\n throw new ValidationError(`items[${index}]: sku or productId is required`);\n }\n const quantity = optionalNumber(item.quantity) ?? 1;\n if (quantity < 1) {\n throw new ValidationError(`items[${index}]: quantity must be at least 1`);\n }\n if (quantity > MAX_LINE_ITEM_QUANTITY) {\n throw new ValidationError(\n `items[${index}]: quantity must be at most ${MAX_LINE_ITEM_QUANTITY}`,\n );\n }\n return {\n sku,\n productId,\n variantId: item.variantId,\n quantity,\n };\n });\n\n const cart = await server.commercetools.addItemsToCart({\n anonymousId: identity.anonymousId,\n customerId: identity.customerId,\n items,\n currency: optionalString(body.currency) ?? server.cartDefaults.currency,\n country: optionalString(body.country) ?? server.cartDefaults.country,\n catalogLocale: resolveLocale(server, body.catalogLocale),\n cartId: optionalString(body.cartId),\n });\n\n return { cart };\n}\n\nexport async function executeRemoveFromCart(\n server: CommerceAIServer,\n body: CartMutationRequest,\n): Promise<CartResponse> {\n const identity = resolveCartIdentity(server, body.sessionToken, body.anonymousId);\n const lineItemId = requiredString(body.lineItemId, \"lineItemId\");\n\n const cart = await server.commercetools.removeLineItem({\n anonymousId: identity.anonymousId,\n customerId: identity.customerId,\n lineItemId,\n cartId: optionalString(body.cartId),\n cartVersion: body.cartVersion,\n catalogLocale: resolveLocale(server, body.catalogLocale),\n });\n\n return { cart };\n}\n\nexport async function executeUpdateCartQuantity(\n server: CommerceAIServer,\n body: UpdateCartQuantityRequest,\n): Promise<CartResponse> {\n const identity = resolveCartIdentity(server, body.sessionToken, body.anonymousId);\n const lineItemId = requiredString(body.lineItemId, \"lineItemId\");\n const quantity = optionalNumber(body.quantity);\n if (quantity === undefined || quantity < 0) {\n throw new ValidationError(\"quantity must be a non-negative number\");\n }\n\n const cart = await server.commercetools.changeLineItemQuantity({\n anonymousId: identity.anonymousId,\n customerId: identity.customerId,\n lineItemId,\n quantity,\n cartId: optionalString(body.cartId),\n cartVersion: body.cartVersion,\n catalogLocale: resolveLocale(server, body.catalogLocale),\n });\n\n return { cart };\n}\n\nexport async function executeLogin(\n server: CommerceAIServer,\n body: CartLoginRequest,\n): Promise<CartAuthResponse> {\n const email = requiredString(body.email, \"email\");\n const password = requiredString(body.password, \"password\");\n const locale = resolveLocale(server, body.catalogLocale);\n\n const result = await server.commercetools.loginAndMerge({\n email,\n password,\n anonymousId: optionalAnonymousId(body.anonymousId),\n cartId: optionalString(body.cartId),\n catalogLocale: locale,\n });\n\n const sessionToken = signCartSession(\n { customerId: result.customer.id, email: result.customer.email },\n server.cartSessionSecret,\n );\n\n return {\n cart: result.cart,\n customer: result.customer,\n sessionToken,\n };\n}\n\nexport async function executeLogout(): Promise<CartAuthResponse> {\n return { cart: null, customer: null };\n}\n","import type {\n CheckoutAddress,\n CheckoutRequest,\n CreateOrderRequest,\n OrderSnapshot,\n SetCartAddressesRequest,\n SetShippingMethodRequest,\n ShippingMethodSnapshot,\n} from \"@commerce-ai-tool/core\";\nimport type { CommerceAIServer } from \"./server.js\";\nimport {\n optionalString,\n requiredString,\n resolveCartIdentity,\n resolveLocale,\n} from \"./cart-actions.js\";\nimport { ValidationError } from \"./route-actions.js\";\n\nexport interface ShippingMethodsResponse {\n shippingMethods: ShippingMethodSnapshot[];\n}\n\nexport interface OrderResponse {\n order: OrderSnapshot;\n}\n\nfunction parseAddress(value: unknown, field: string): CheckoutAddress {\n if (!value || typeof value !== \"object\") {\n throw new ValidationError(`${field} is required`);\n }\n const address = value as Record<string, unknown>;\n const country = requiredString(address.country, `${field}.country`).toUpperCase();\n if (!/^[A-Z]{2}$/.test(country)) {\n throw new ValidationError(`${field}.country must be an ISO 3166-1 alpha-2 code`);\n }\n\n return {\n firstName: requiredString(address.firstName, `${field}.firstName`),\n lastName: requiredString(address.lastName, `${field}.lastName`),\n streetName: requiredString(address.streetName, `${field}.streetName`),\n additionalStreetInfo: optionalString(address.additionalStreetInfo),\n postalCode: requiredString(address.postalCode, `${field}.postalCode`),\n city: requiredString(address.city, `${field}.city`),\n region: optionalString(address.region),\n country,\n email: optionalString(address.email),\n phone: optionalString(address.phone),\n };\n}\n\nfunction checkoutIdentity(\n server: CommerceAIServer,\n body: CheckoutRequest,\n): CheckoutRequest {\n return {\n ...resolveCartIdentity(server, body.sessionToken, body.anonymousId),\n cartId: optionalString(body.cartId),\n catalogLocale: resolveLocale(server, body.catalogLocale),\n };\n}\n\nexport async function executeSetCartAddresses(\n server: CommerceAIServer,\n body: SetCartAddressesRequest,\n) {\n const cart = await server.commercetools.setCartAddresses({\n ...checkoutIdentity(server, body),\n shippingAddress: parseAddress(body.shippingAddress, \"shippingAddress\"),\n billingAddress: body.billingAddress\n ? parseAddress(body.billingAddress, \"billingAddress\")\n : undefined,\n });\n return { cart };\n}\n\nexport async function executeGetShippingMethods(\n server: CommerceAIServer,\n body: CheckoutRequest,\n): Promise<ShippingMethodsResponse> {\n const shippingMethods = await server.commercetools.getShippingMethods(\n checkoutIdentity(server, body),\n );\n return { shippingMethods };\n}\n\nexport async function executeSetShippingMethod(\n server: CommerceAIServer,\n body: SetShippingMethodRequest,\n) {\n const cart = await server.commercetools.setShippingMethod({\n ...checkoutIdentity(server, body),\n shippingMethodId: requiredString(body.shippingMethodId, \"shippingMethodId\"),\n });\n return { cart };\n}\n\nexport async function executeCreateOrder(\n server: CommerceAIServer,\n body: CreateOrderRequest,\n): Promise<OrderResponse> {\n const order = await server.commercetools.createOrder({\n ...checkoutIdentity(server, body),\n orderNumber: optionalString(body.orderNumber),\n });\n return { order };\n}\n","import type {\n AuthorizePaymentRequest,\n CartSnapshot,\n CheckoutRequest,\n PaymentMethodOption,\n PaymentSnapshot,\n} from \"@commerce-ai-tool/core\";\nimport type { CommerceAIServer } from \"./server.js\";\nimport {\n optionalString,\n requiredString,\n resolveCartIdentity,\n resolveLocale,\n} from \"./cart-actions.js\";\n\nexport interface PaymentMethodsResponse {\n paymentMethods: PaymentMethodOption[];\n}\n\nexport interface AuthorizePaymentResponse {\n payment: PaymentSnapshot;\n cart: CartSnapshot;\n}\n\nfunction paymentIdentity(\n server: CommerceAIServer,\n body: CheckoutRequest,\n): CheckoutRequest {\n return {\n ...resolveCartIdentity(server, body.sessionToken, body.anonymousId),\n cartId: optionalString(body.cartId),\n catalogLocale: resolveLocale(server, body.catalogLocale),\n };\n}\n\nexport async function executeGetPaymentMethods(\n server: CommerceAIServer,\n body: CheckoutRequest,\n): Promise<PaymentMethodsResponse> {\n const identity = paymentIdentity(server, body);\n const paymentMethods = await server.commercetools.listPaymentMethods({\n locale: identity.catalogLocale,\n country: server.cartDefaults.country,\n });\n return { paymentMethods };\n}\n\nexport async function executeAuthorizePayment(\n server: CommerceAIServer,\n body: AuthorizePaymentRequest,\n): Promise<AuthorizePaymentResponse> {\n return server.commercetools.authorizePayment({\n ...paymentIdentity(server, body),\n method: requiredString(body.method, \"method\"),\n orderNumber: optionalString(body.orderNumber),\n });\n}\n","import type { GetOrderRequest, OrderSnapshot } from \"@commerce-ai-tool/core\";\nimport type { CommerceAIServer } from \"./server.js\";\nimport {\n optionalString,\n resolveCartIdentity,\n resolveLocale,\n} from \"./cart-actions.js\";\n\nexport interface GetOrderResponse {\n order?: OrderSnapshot;\n orders?: OrderSnapshot[];\n}\n\nexport async function executeGetOrder(\n server: CommerceAIServer,\n body: GetOrderRequest,\n): Promise<GetOrderResponse> {\n const identity = resolveCartIdentity(server, body.sessionToken, body.anonymousId);\n const catalogLocale = resolveLocale(server, optionalString(body.catalogLocale));\n const anonymousId = identity.anonymousId ?? optionalString(body.anonymousId);\n const orderNumber = optionalString(body.orderNumber);\n\n if (!orderNumber) {\n const orders = await server.commercetools.listOrders({\n anonymousId,\n customerId: identity.customerId,\n catalogLocale,\n });\n return { orders };\n }\n\n const order = await server.commercetools.getOrder({\n orderNumber,\n anonymousId,\n customerId: identity.customerId,\n catalogLocale,\n });\n return { order };\n}\n","import Busboy from \"busboy\";\nimport type { IncomingMessage } from \"node:http\";\n\nexport interface ParsedMultipart {\n fields: Record<string, string>;\n file?: {\n buffer: Buffer;\n mimeType: string;\n filename: string;\n };\n}\n\nexport async function parseMultipart(req: IncomingMessage): Promise<ParsedMultipart> {\n return new Promise((resolve, reject) => {\n const fields: Record<string, string> = {};\n let file: ParsedMultipart[\"file\"];\n\n const busboy = Busboy({ headers: req.headers });\n const chunks: Buffer[] = [];\n\n busboy.on(\"field\", (name, value) => {\n fields[name] = value;\n });\n\n busboy.on(\"file\", (_name, stream, info) => {\n stream.on(\"data\", (chunk: Buffer) => chunks.push(chunk));\n stream.on(\"end\", () => {\n file = {\n buffer: Buffer.concat(chunks),\n mimeType: info.mimeType,\n filename: info.filename,\n };\n });\n });\n\n busboy.on(\"finish\", () => resolve({ fields, file }));\n busboy.on(\"error\", reject);\n req.pipe(busboy);\n });\n}\n\nexport async function readJsonBody<T>(req: IncomingMessage): Promise<T> {\n const chunks: Buffer[] = [];\n for await (const chunk of req) {\n chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));\n }\n const raw = Buffer.concat(chunks).toString(\"utf8\");\n return JSON.parse(raw) as T;\n}\n\nexport async function readRequestBuffer(req: Request): Promise<Buffer> {\n const arrayBuffer = await req.arrayBuffer();\n return Buffer.from(arrayBuffer);\n}\n\nexport async function parseMultipartRequest(req: Request): Promise<ParsedMultipart> {\n const formData = await req.formData();\n const fields: Record<string, string> = {};\n let file: ParsedMultipart[\"file\"];\n\n for (const [key, value] of formData.entries()) {\n if (typeof value === \"string\") {\n fields[key] = value;\n continue;\n }\n\n const buffer = Buffer.from(await value.arrayBuffer());\n file = {\n buffer,\n mimeType: value.type || \"application/octet-stream\",\n filename: value.name,\n };\n }\n\n return { fields, file };\n}\n","import type { IncomingMessage } from \"node:http\";\nimport type { CommerceAIServer } from \"./server.js\";\nimport { errorResponse, jsonResponse, type HandlerResponse } from \"./handler-response.js\";\nimport {\n executeSearch,\n executeFacetSchema,\n executeSearchImage,\n executeSearchSuggestions,\n executeSearchVoice,\n executeTts,\n mapRouteError,\n} from \"./route-actions.js\";\nimport {\n executeAddToCart,\n executeAddItemsToCart,\n executeGetCart,\n executeLogin,\n executeLogout,\n executeRemoveFromCart,\n executeUpdateCartQuantity,\n} from \"./cart-actions.js\";\nimport {\n executeCreateOrder,\n executeGetShippingMethods,\n executeSetCartAddresses,\n executeSetShippingMethod,\n} from \"./checkout-actions.js\";\nimport {\n executeAuthorizePayment,\n executeGetPaymentMethods,\n} from \"./payment-actions.js\";\nimport { executeGetOrder } from \"./order-actions.js\";\nimport { readCartSessionHeader } from \"./cart-session.js\";\nimport { parseMultipart, readJsonBody } from \"./utils/multipart.js\";\nimport type {\n AddItemsToCartRequest,\n AddToCartRequest,\n AuthorizePaymentRequest,\n CartLoginRequest,\n CartMutationRequest,\n CreateOrderRequest,\n SetCartAddressesRequest,\n SetShippingMethodRequest,\n UpdateCartQuantityRequest,\n} from \"@commerce-ai-tool/core\";\n\nexport type { HandlerResponse } from \"./handler-response.js\";\n\nexport function createHandlers(server: CommerceAIServer) {\n return {\n async health(): Promise<HandlerResponse> {\n return jsonResponse({ status: \"ok\" });\n },\n\n async search(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<{\n query: string;\n queryLocale?: string;\n catalogLocale?: string;\n locale?: string;\n limit?: number;\n enableMissions?: boolean;\n }>(req);\n\n const result = await executeSearch(server, body);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"search\", \"Search failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async facetSchema(): Promise<HandlerResponse> {\n try {\n return jsonResponse(await executeFacetSchema(server, undefined));\n } catch (error) {\n const mapped = mapRouteError(error, \"facetSchema\", \"Facet schema failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async searchSuggestions(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<{\n query: string;\n queryLocale?: string;\n catalogLocale?: string;\n locale?: string;\n limit?: number;\n }>(req);\n\n const result = await executeSearchSuggestions(server, body);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"searchSuggestions\", \"Suggestions failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async searchVoice(req: IncomingMessage): Promise<HandlerResponse> {\n let fields: Record<string, string> = {};\n let file: Awaited<ReturnType<typeof parseMultipart>>[\"file\"];\n\n try {\n const parsed = await parseMultipart(req);\n fields = parsed.fields;\n file = parsed.file;\n\n const result = await executeSearchVoice(server, fields, file);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"searchVoice\", \"Voice search failed\", {\n queryLocale: fields.queryLocale ?? fields.locale,\n catalogLocale: fields.catalogLocale,\n mimeType: file?.mimeType,\n size: file?.buffer.length,\n });\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async searchImage(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const { fields, file } = await parseMultipart(req);\n const result = await executeSearchImage(server, fields, file);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"searchImage\", \"Image search failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async tts(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<{ text: string }>(req);\n const audio = await executeTts(server, body.text);\n\n return {\n status: 200,\n headers: { \"Content-Type\": \"audio/mpeg\" },\n body: audio,\n };\n } catch (error) {\n const mapped = mapRouteError(error, \"tts\", \"TTS failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async getCart(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const query = parseRequestQuery(req);\n const result = await executeGetCart(server, {\n anonymousId: query.anonymousId ?? \"\",\n catalogLocale: query.catalogLocale,\n sessionToken: readCartSessionHeader(req.headers),\n });\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"getCart\", \"Get cart failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async addToCart(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<AddToCartRequest>(req);\n const result = await executeAddToCart(server, body);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"addToCart\", \"Add to cart failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async addItemsToCart(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<AddItemsToCartRequest>(req);\n const result = await executeAddItemsToCart(server, body);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"addItemsToCart\", \"Add items to cart failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async removeFromCart(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<CartMutationRequest>(req);\n const result = await executeRemoveFromCart(server, body);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"removeFromCart\", \"Remove from cart failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async updateCartQuantity(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<UpdateCartQuantityRequest>(req);\n const result = await executeUpdateCartQuantity(server, body);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"updateCartQuantity\", \"Update cart quantity failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async setCartAddresses(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<SetCartAddressesRequest>(req);\n return jsonResponse(await executeSetCartAddresses(server, body));\n } catch (error) {\n const mapped = mapRouteError(error, \"setCartAddresses\", \"Set cart addresses failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async getShippingMethods(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const query = parseRequestQuery(req);\n return jsonResponse(\n await executeGetShippingMethods(server, {\n anonymousId: query.anonymousId,\n cartId: query.cartId,\n catalogLocale: query.catalogLocale,\n sessionToken: readCartSessionHeader(req.headers),\n }),\n );\n } catch (error) {\n const mapped = mapRouteError(\n error,\n \"getShippingMethods\",\n \"Get shipping methods failed\",\n );\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async setShippingMethod(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<SetShippingMethodRequest>(req);\n return jsonResponse(await executeSetShippingMethod(server, body));\n } catch (error) {\n const mapped = mapRouteError(\n error,\n \"setShippingMethod\",\n \"Set shipping method failed\",\n );\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async createOrder(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<CreateOrderRequest>(req);\n return jsonResponse(await executeCreateOrder(server, body));\n } catch (error) {\n const mapped = mapRouteError(error, \"createOrder\", \"Create order failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async getPaymentMethods(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const query = parseRequestQuery(req);\n return jsonResponse(\n await executeGetPaymentMethods(server, {\n anonymousId: query.anonymousId,\n cartId: query.cartId,\n catalogLocale: query.catalogLocale,\n sessionToken: readCartSessionHeader(req.headers),\n }),\n );\n } catch (error) {\n const mapped = mapRouteError(\n error,\n \"getPaymentMethods\",\n \"Get payment methods failed\",\n );\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async authorizePayment(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<AuthorizePaymentRequest>(req);\n return jsonResponse(await executeAuthorizePayment(server, body));\n } catch (error) {\n const mapped = mapRouteError(error, \"authorizePayment\", \"Payment failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async getOrder(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const query = parseRequestQuery(req);\n return jsonResponse(\n await executeGetOrder(server, {\n orderNumber: query.orderNumber ?? \"\",\n anonymousId: query.anonymousId,\n catalogLocale: query.catalogLocale,\n sessionToken: readCartSessionHeader(req.headers),\n }),\n );\n } catch (error) {\n const mapped = mapRouteError(error, \"getOrder\", \"Get order failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async login(req: IncomingMessage): Promise<HandlerResponse> {\n try {\n const body = await readJsonBody<CartLoginRequest>(req);\n const result = await executeLogin(server, body);\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"login\", \"Login failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n\n async logout(): Promise<HandlerResponse> {\n try {\n const result = await executeLogout();\n return jsonResponse(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"logout\", \"Logout failed\");\n return errorResponse(mapped.message, mapped.status);\n }\n },\n };\n}\n\nexport type CommerceAIHandlers = ReturnType<typeof createHandlers>;\n\nfunction parseRequestQuery(req: IncomingMessage): Record<string, string> {\n const query: Record<string, string> = {};\n const url = new URL(req.url ?? \"\", \"http://localhost\");\n for (const [key, value] of url.searchParams.entries()) {\n query[key] = value;\n }\n return query;\n}\n","import type {\n AddItemsToCartRequest,\n AddToCartRequest,\n AuthorizePaymentRequest,\n CartLoginRequest,\n CartMutationRequest,\n CommerceAIConfig,\n CreateOrderRequest,\n SetCartAddressesRequest,\n SetShippingMethodRequest,\n UpdateCartQuantityRequest,\n} from \"@commerce-ai-tool/core\";\nimport { createHandlers } from \"./handlers.js\";\nimport { toWebErrorResponse, toWebResponse } from \"./handler-response.js\";\nimport { createCommerceAIServer } from \"./server.js\";\nimport {\n executeSearch,\n executeFacetSchema,\n executeSearchImage,\n executeSearchSuggestions,\n executeSearchVoice,\n executeTts,\n mapRouteError,\n} from \"./route-actions.js\";\nimport {\n executeAddToCart,\n executeAddItemsToCart,\n executeGetCart,\n executeLogin,\n executeLogout,\n executeRemoveFromCart,\n executeUpdateCartQuantity,\n} from \"./cart-actions.js\";\nimport {\n executeCreateOrder,\n executeGetShippingMethods,\n executeSetCartAddresses,\n executeSetShippingMethod,\n} from \"./checkout-actions.js\";\nimport {\n executeAuthorizePayment,\n executeGetPaymentMethods,\n} from \"./payment-actions.js\";\nimport { executeGetOrder } from \"./order-actions.js\";\nimport { readCartSessionHeader } from \"./cart-session.js\";\nimport {\n clientKeyFromWebHeaders,\n createLoginAttemptLimiter,\n ORDER_RATE_LIMIT_MAX_ATTEMPTS,\n ORDER_RATE_LIMIT_MESSAGE,\n ORDER_RATE_LIMIT_WINDOW_MS,\n PAYMENT_RATE_LIMIT_MAX_ATTEMPTS,\n PAYMENT_RATE_LIMIT_MESSAGE,\n PAYMENT_RATE_LIMIT_WINDOW_MS,\n TooManyRequestsError,\n} from \"./login-rate-limit.js\";\nimport { parseMultipartRequest } from \"./utils/multipart.js\";\n\nexport interface NextHandlers {\n health: () => Promise<Response>;\n search: (req: Request) => Promise<Response>;\n facetSchema: () => Promise<Response>;\n searchSuggestions: (req: Request) => Promise<Response>;\n searchVoice: (req: Request) => Promise<Response>;\n searchImage: (req: Request) => Promise<Response>;\n tts: (req: Request) => Promise<Response>;\n getCart: (req: Request) => Promise<Response>;\n addToCart: (req: Request) => Promise<Response>;\n addItemsToCart: (req: Request) => Promise<Response>;\n removeFromCart: (req: Request) => Promise<Response>;\n updateCartQuantity: (req: Request) => Promise<Response>;\n setCartAddresses: (req: Request) => Promise<Response>;\n getShippingMethods: (req: Request) => Promise<Response>;\n setShippingMethod: (req: Request) => Promise<Response>;\n createOrder: (req: Request) => Promise<Response>;\n getPaymentMethods: (req: Request) => Promise<Response>;\n authorizePayment: (req: Request) => Promise<Response>;\n getOrder: (req: Request) => Promise<Response>;\n login: (req: Request) => Promise<Response>;\n logout: () => Promise<Response>;\n}\n\nconst loginLimiter = createLoginAttemptLimiter();\nconst orderLimiter = createLoginAttemptLimiter({\n windowMs: ORDER_RATE_LIMIT_WINDOW_MS,\n limit: ORDER_RATE_LIMIT_MAX_ATTEMPTS,\n});\nconst paymentLimiter = createLoginAttemptLimiter({\n windowMs: PAYMENT_RATE_LIMIT_WINDOW_MS,\n limit: PAYMENT_RATE_LIMIT_MAX_ATTEMPTS,\n});\n\nexport function createNextHandlers(config: CommerceAIConfig): NextHandlers {\n const server = createCommerceAIServer({ config });\n const handlers = createHandlers(server);\n\n return {\n health: async () => toWebResponse(await handlers.health()),\n\n facetSchema: async () => {\n try {\n return Response.json(await executeFacetSchema(server, undefined));\n } catch (error) {\n const mapped = mapRouteError(error, \"facetSchema\", \"Facet schema failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n search: async (req: Request) => {\n try {\n const body = (await req.json()) as {\n query: string;\n queryLocale?: string;\n catalogLocale?: string;\n locale?: string;\n limit?: number;\n enableMissions?: boolean;\n };\n\n const result = await executeSearch(server, body);\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"search\", \"Search failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n searchSuggestions: async (req: Request) => {\n try {\n const body = (await req.json()) as {\n query: string;\n queryLocale?: string;\n catalogLocale?: string;\n locale?: string;\n limit?: number;\n };\n\n const result = await executeSearchSuggestions(server, body);\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"searchSuggestions\", \"Suggestions failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n searchVoice: async (req: Request) => {\n let fields: Record<string, string> = {};\n let file: Awaited<ReturnType<typeof parseMultipartRequest>>[\"file\"];\n\n try {\n const parsed = await parseMultipartRequest(req);\n fields = parsed.fields;\n file = parsed.file;\n\n const result = await executeSearchVoice(server, fields, file);\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"searchVoice\", \"Voice search failed\", {\n queryLocale: fields.queryLocale ?? fields.locale,\n catalogLocale: fields.catalogLocale,\n mimeType: file?.mimeType,\n size: file?.buffer.length,\n });\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n searchImage: async (req: Request) => {\n try {\n const { fields, file } = await parseMultipartRequest(req);\n const result = await executeSearchImage(server, fields, file);\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"searchImage\", \"Image search failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n tts: async (req: Request) => {\n try {\n const body = (await req.json()) as { text: string };\n const audio = await executeTts(server, body.text);\n\n return new Response(audio, {\n headers: { \"Content-Type\": \"audio/mpeg\" },\n });\n } catch (error) {\n const mapped = mapRouteError(error, \"tts\", \"TTS failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n getCart: async (req: Request) => {\n try {\n const url = new URL(req.url);\n const result = await executeGetCart(server, {\n anonymousId: url.searchParams.get(\"anonymousId\") ?? \"\",\n catalogLocale: url.searchParams.get(\"catalogLocale\") ?? undefined,\n sessionToken: readCartSessionHeader(req.headers),\n });\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"getCart\", \"Get cart failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n addToCart: async (req: Request) => {\n try {\n const result = await executeAddToCart(server, (await req.json()) as AddToCartRequest);\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"addToCart\", \"Add to cart failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n addItemsToCart: async (req: Request) => {\n try {\n const result = await executeAddItemsToCart(\n server,\n (await req.json()) as AddItemsToCartRequest,\n );\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"addItemsToCart\", \"Add items to cart failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n removeFromCart: async (req: Request) => {\n try {\n const result = await executeRemoveFromCart(server, (await req.json()) as CartMutationRequest);\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"removeFromCart\", \"Remove from cart failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n updateCartQuantity: async (req: Request) => {\n try {\n const result = await executeUpdateCartQuantity(\n server,\n (await req.json()) as UpdateCartQuantityRequest,\n );\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"updateCartQuantity\", \"Update cart quantity failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n setCartAddresses: async (req: Request) => {\n try {\n const result = await executeSetCartAddresses(\n server,\n (await req.json()) as SetCartAddressesRequest,\n );\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"setCartAddresses\", \"Set cart addresses failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n getShippingMethods: async (req: Request) => {\n try {\n const url = new URL(req.url);\n const result = await executeGetShippingMethods(server, {\n anonymousId: url.searchParams.get(\"anonymousId\") ?? undefined,\n cartId: url.searchParams.get(\"cartId\") ?? undefined,\n catalogLocale: url.searchParams.get(\"catalogLocale\") ?? undefined,\n sessionToken: readCartSessionHeader(req.headers),\n });\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(\n error,\n \"getShippingMethods\",\n \"Get shipping methods failed\",\n );\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n setShippingMethod: async (req: Request) => {\n try {\n const result = await executeSetShippingMethod(\n server,\n (await req.json()) as SetShippingMethodRequest,\n );\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(\n error,\n \"setShippingMethod\",\n \"Set shipping method failed\",\n );\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n createOrder: async (req: Request) => {\n try {\n orderLimiter.consume(clientKeyFromWebHeaders(req.headers));\n const result = await executeCreateOrder(\n server,\n (await req.json()) as CreateOrderRequest,\n );\n return Response.json(result);\n } catch (error) {\n if (error instanceof TooManyRequestsError) {\n return Response.json(\n { error: ORDER_RATE_LIMIT_MESSAGE },\n {\n status: 429,\n headers: { \"Retry-After\": String(error.retryAfterSeconds) },\n },\n );\n }\n\n const mapped = mapRouteError(error, \"createOrder\", \"Create order failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n getPaymentMethods: async (req: Request) => {\n try {\n const url = new URL(req.url);\n const result = await executeGetPaymentMethods(server, {\n anonymousId: url.searchParams.get(\"anonymousId\") ?? undefined,\n cartId: url.searchParams.get(\"cartId\") ?? undefined,\n catalogLocale: url.searchParams.get(\"catalogLocale\") ?? undefined,\n sessionToken: readCartSessionHeader(req.headers),\n });\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(\n error,\n \"getPaymentMethods\",\n \"Get payment methods failed\",\n );\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n authorizePayment: async (req: Request) => {\n try {\n paymentLimiter.consume(clientKeyFromWebHeaders(req.headers));\n const result = await executeAuthorizePayment(\n server,\n (await req.json()) as AuthorizePaymentRequest,\n );\n return Response.json(result);\n } catch (error) {\n if (error instanceof TooManyRequestsError) {\n return Response.json(\n { error: PAYMENT_RATE_LIMIT_MESSAGE },\n {\n status: 429,\n headers: { \"Retry-After\": String(error.retryAfterSeconds) },\n },\n );\n }\n\n const mapped = mapRouteError(error, \"authorizePayment\", \"Payment failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n getOrder: async (req: Request) => {\n try {\n const url = new URL(req.url);\n const result = await executeGetOrder(server, {\n orderNumber: url.searchParams.get(\"orderNumber\") ?? \"\",\n anonymousId: url.searchParams.get(\"anonymousId\") ?? undefined,\n catalogLocale: url.searchParams.get(\"catalogLocale\") ?? undefined,\n sessionToken: readCartSessionHeader(req.headers),\n });\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"getOrder\", \"Get order failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n login: async (req: Request) => {\n try {\n loginLimiter.consume(clientKeyFromWebHeaders(req.headers));\n const result = await executeLogin(server, (await req.json()) as CartLoginRequest);\n return Response.json(result);\n } catch (error) {\n if (error instanceof TooManyRequestsError) {\n return Response.json(\n { error: error.message },\n {\n status: 429,\n headers: { \"Retry-After\": String(error.retryAfterSeconds) },\n },\n );\n }\n\n const mapped = mapRouteError(error, \"login\", \"Login failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n\n logout: async () => {\n try {\n const result = await executeLogout();\n return Response.json(result);\n } catch (error) {\n const mapped = mapRouteError(error, \"logout\", \"Logout failed\");\n return toWebErrorResponse(mapped.message, mapped.status);\n }\n },\n };\n}\n"],"mappings":"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","names":["import_core","import_core","value","trimmed","import_core","import_core","import_core","Busboy"]}
@@ -0,0 +1,6 @@
1
+ export { createCommerceAIServer, loadConfigFromEnv, type CommerceAIServer, type CommerceAIServerOptions, } from "./server.js";
2
+ export { createHandlers, type CommerceAIHandlers } from "./handlers.js";
3
+ export { createNextHandlers, type NextHandlers } from "./next.js";
4
+ export { CART_SESSION_HEADER } from "./cart-session.js";
5
+ export { flushLangfuse, registerLangfuseFlush, withRequestSpan, } from "./observability/langfuse.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,6 @@
1
+ export { createCommerceAIServer, loadConfigFromEnv, type CommerceAIServer, type CommerceAIServerOptions, } from "./server.js";
2
+ export { createHandlers, type CommerceAIHandlers } from "./handlers.js";
3
+ export { createNextHandlers, type NextHandlers } from "./next.js";
4
+ export { CART_SESSION_HEADER } from "./cart-session.js";
5
+ export { flushLangfuse, registerLangfuseFlush, withRequestSpan, } from "./observability/langfuse.js";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,KAAK,gBAAgB,EACrB,KAAK,uBAAuB,GAC7B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,eAAe,GAChB,MAAM,6BAA6B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,25 @@
1
+ import {
2
+ createNextHandlers
3
+ } from "./chunk-GMYUJ2J6.js";
4
+ import {
5
+ CART_SESSION_HEADER,
6
+ createCommerceAIServer,
7
+ createHandlers,
8
+ loadConfigFromEnv,
9
+ withRequestSpan
10
+ } from "./chunk-PPWA5L7U.js";
11
+ import {
12
+ flushLangfuse,
13
+ registerLangfuseFlush
14
+ } from "./chunk-UGRFHLDW.js";
15
+ export {
16
+ CART_SESSION_HEADER,
17
+ createCommerceAIServer,
18
+ createHandlers,
19
+ createNextHandlers,
20
+ flushLangfuse,
21
+ loadConfigFromEnv,
22
+ registerLangfuseFlush,
23
+ withRequestSpan
24
+ };
25
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
@@ -0,0 +1,22 @@
1
+ export declare const LOGIN_RATE_LIMIT_WINDOW_MS: number;
2
+ export declare const LOGIN_RATE_LIMIT_MAX_ATTEMPTS = 10;
3
+ export declare const LOGIN_RATE_LIMIT_MESSAGE = "Too many login attempts. Try again later.";
4
+ export declare const ORDER_RATE_LIMIT_WINDOW_MS: number;
5
+ export declare const ORDER_RATE_LIMIT_MAX_ATTEMPTS = 20;
6
+ export declare const ORDER_RATE_LIMIT_MESSAGE = "Too many order attempts. Try again later.";
7
+ export declare const PAYMENT_RATE_LIMIT_WINDOW_MS: number;
8
+ export declare const PAYMENT_RATE_LIMIT_MAX_ATTEMPTS = 20;
9
+ export declare const PAYMENT_RATE_LIMIT_MESSAGE = "Too many payment attempts. Try again later.";
10
+ export declare class TooManyRequestsError extends Error {
11
+ readonly retryAfterSeconds: number;
12
+ constructor(retryAfterSeconds: number, message?: string);
13
+ }
14
+ export interface LoginAttemptLimiter {
15
+ consume(key: string): void;
16
+ }
17
+ export declare function createLoginAttemptLimiter(options?: {
18
+ windowMs?: number;
19
+ limit?: number;
20
+ }): LoginAttemptLimiter;
21
+ export declare function clientKeyFromWebHeaders(headers: Headers): string;
22
+ //# sourceMappingURL=login-rate-limit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"login-rate-limit.d.ts","sourceRoot":"","sources":["../src/login-rate-limit.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,0BAA0B,QAAiB,CAAC;AACzD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,wBAAwB,8CAA8C,CAAC;AAEpF,eAAO,MAAM,0BAA0B,QAAiB,CAAC;AACzD,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,wBAAwB,8CAA8C,CAAC;AAEpF,eAAO,MAAM,4BAA4B,QAAiB,CAAC;AAC3D,eAAO,MAAM,+BAA+B,KAAK,CAAC;AAClD,eAAO,MAAM,0BAA0B,gDAAgD,CAAC;AAExF,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IAEnC,YAAY,iBAAiB,EAAE,MAAM,EAAE,OAAO,SAA2B,EAIxE;CACF;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAgB,yBAAyB,CACvC,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAClD,mBAAmB,CAsBrB;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAWhE"}