@modainteract/moda-interact-shared 5.10.0 → 5.11.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commerce/discount-capability-contracts.ts","../../src/commerce/store-category-prompt.ts","../../src/commerce/outreach-context.ts","../../src/commerce/fixtures.ts"],"sourcesContent":["import { CommerceToolInputs, CommerceToolOutputs } from \"./schemas.js\";\n\n/**\n * Canonical Shared mapping for the two published discount capabilities.\n * Consumers reuse these validators instead of maintaining local copies.\n * `operationVersion` is independent of immutable published tool definition\n * versions selected by Commerce during publication.\n */\nexport const DISCOUNT_POLICY_OPERATION_DESCRIPTORS = Object.freeze([\n Object.freeze({\n toolName: \"commerce_get_discount_options\",\n displayName: \"Get Discount Options\",\n operation: \"discounts.getOptions\",\n operationVersion: \"1.0.0\",\n description: \"Read the configured discount mode and available offers.\",\n inputValidator: CommerceToolInputs.commerce_get_discount_options,\n outputValidator: CommerceToolOutputs.commerce_get_discount_options,\n }),\n Object.freeze({\n toolName: \"commerce_get_discount_details\",\n displayName: \"Get Discount Details\",\n operation: \"discounts.getDetails\",\n operationVersion: \"1.0.0\",\n description: \"Read details and condition facts for a permitted discount.\",\n inputValidator: CommerceToolInputs.commerce_get_discount_details,\n outputValidator: CommerceToolOutputs.commerce_get_discount_details,\n }),\n] as const);\n\nexport type DiscountPolicyOperationDescriptor =\n (typeof DISCOUNT_POLICY_OPERATION_DESCRIPTORS)[number];\n","import { z } from \"zod\";\n\nexport const STORE_CATEGORY_PROMPT_RUNTIME_VERSION = \"store-category-prompt.v1\" as const;\nexport const MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS = 100_000;\nexport const MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS = 100_000;\nexport const MAX_STORE_CATEGORY_PROMPT_CONDITIONS = 256;\nconst MAX_CONTROL_TAGS = 512;\nconst MAX_CONTROL_DEPTH = 8;\nconst MAX_EXPRESSION_CHARS = 1_024;\n\nconst forbiddenConditionKeys = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst conditionKeyPattern = /^[a-z][a-z0-9_]{0,127}$/;\n\nexport const StoreCategoryPromptConditionKeySchema = z\n .string()\n .regex(conditionKeyPattern)\n .refine((value) => !forbiddenConditionKeys.has(value));\n\nexport type StoreCategoryPromptConditionKey = z.infer<typeof StoreCategoryPromptConditionKeySchema>;\n\nexport const StoreCategoryPromptContextSchema = z.strictObject({\n mappings: z\n .record(StoreCategoryPromptConditionKeySchema, z.boolean())\n .refine((value) => Object.keys(value).length <= MAX_STORE_CATEGORY_PROMPT_CONDITIONS),\n});\n\nexport type StoreCategoryPromptContext = z.infer<typeof StoreCategoryPromptContextSchema>;\n\nexport type StoreCategoryPromptTemplateIssue = {\n path: \"/promptText\";\n code:\n | \"invalid_prompt_source\"\n | \"unsupported_template_construct\"\n | \"invalid_template_structure\"\n | \"invalid_template_expression\"\n | \"invalid_mapping_condition\"\n | \"unknown_mapping_condition\"\n | \"template_too_complex\"\n | \"rendered_prompt_too_large\";\n message: string;\n};\n\nexport type StoreCategoryPromptTemplateValidation = {\n valid: boolean;\n issues: StoreCategoryPromptTemplateIssue[];\n referencedConditionKeys: string[];\n};\n\nexport type StoreCategoryPromptRenderResult =\n | { ok: true; promptText: string; referencedConditionKeys: string[] }\n | { ok: false; issues: StoreCategoryPromptTemplateIssue[] };\n\ntype ExpressionNode =\n | { kind: \"condition\"; key: string }\n | { kind: \"not\"; operand: ExpressionNode }\n | { kind: \"and\"; left: ExpressionNode; right: ExpressionNode }\n | { kind: \"or\"; left: ExpressionNode; right: ExpressionNode };\n\ntype TemplateNode =\n | { kind: \"text\"; text: string }\n | {\n kind: \"if\";\n branches: Array<{ expression: ExpressionNode; body: TemplateNode[] }>;\n elseBody: TemplateNode[] | null;\n };\n\ntype TemplateToken =\n | { kind: \"text\"; text: string }\n | { kind: \"control\"; source: string }\n | { kind: \"unsupported\"; source: string; marker: \"interpolation\" | \"comment\" };\n\ntype CompileResult = {\n issues: StoreCategoryPromptTemplateIssue[];\n nodes: TemplateNode[];\n referencedConditionKeys: string[];\n};\n\nfunction issue(code: StoreCategoryPromptTemplateIssue[\"code\"], message: string): StoreCategoryPromptTemplateIssue {\n return { path: \"/promptText\", code, message };\n}\n\nfunction boundedIssues(issues: StoreCategoryPromptTemplateIssue[]): StoreCategoryPromptTemplateIssue[] {\n return issues.slice(0, 32).map((entry) => ({\n path: entry.path,\n code: entry.code,\n message: entry.message.slice(0, 512),\n }));\n}\n\nfunction sourceLength(value: string): number {\n return Array.from(value).length;\n}\n\nfunction findNextMarker(source: string, start: number): { index: number; marker: \"{%\" | \"{{\" | \"{#\" } | null {\n let best: { index: number; marker: \"{%\" | \"{{\" | \"{#\" } | null = null;\n for (const marker of [\"{%\", \"{{\", \"{#\"] as const) {\n const index = source.indexOf(marker, start);\n if (index >= 0 && (!best || index < best.index)) best = { index, marker };\n }\n return best;\n}\n\nfunction tokenizeTemplate(source: string, issues: StoreCategoryPromptTemplateIssue[]): TemplateToken[] {\n const tokens: TemplateToken[] = [];\n let cursor = 0;\n while (cursor < source.length) {\n const next = findNextMarker(source, cursor);\n if (!next) {\n tokens.push({ kind: \"text\", text: source.slice(cursor) });\n break;\n }\n if (next.index > cursor) tokens.push({ kind: \"text\", text: source.slice(cursor, next.index) });\n const closeMarker = next.marker === \"{%\" ? \"%}\" : next.marker === \"{{\" ? \"}}\" : \"#}\";\n const close = source.indexOf(closeMarker, next.index + 2);\n if (close < 0) {\n issues.push(issue(\"invalid_template_structure\", `Unclosed ${next.marker} template construct.`));\n tokens.push({ kind: \"text\", text: source.slice(next.index) });\n break;\n }\n const raw = source.slice(next.index + 2, close).trim();\n if (next.marker === \"{%\") tokens.push({ kind: \"control\", source: raw });\n else tokens.push({ kind: \"unsupported\", source: raw, marker: next.marker === \"{{\" ? \"interpolation\" : \"comment\" });\n cursor = close + 2;\n }\n if (source.length === 0) tokens.push({ kind: \"text\", text: \"\" });\n return tokens;\n}\n\ntype ExprToken = { kind: \"word\"; value: string } | { kind: \"dot\" } | { kind: \"lparen\" } | { kind: \"rparen\" };\n\nfunction lexExpression(source: string, issues: StoreCategoryPromptTemplateIssue[]): ExprToken[] | null {\n if (sourceLength(source) > MAX_EXPRESSION_CHARS) {\n issues.push(issue(\"template_too_complex\", `Conditional expressions must not exceed ${MAX_EXPRESSION_CHARS} characters.`));\n return null;\n }\n const tokens: ExprToken[] = [];\n let cursor = 0;\n while (cursor < source.length) {\n const char = source[cursor];\n if (/\\s/.test(char)) {\n cursor += 1;\n continue;\n }\n if (char === \".\") {\n tokens.push({ kind: \"dot\" });\n cursor += 1;\n continue;\n }\n if (char === \"(\") {\n tokens.push({ kind: \"lparen\" });\n cursor += 1;\n continue;\n }\n if (char === \")\") {\n tokens.push({ kind: \"rparen\" });\n cursor += 1;\n continue;\n }\n const match = /^[A-Za-z_][A-Za-z0-9_]*/.exec(source.slice(cursor));\n if (!match) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expressions may only use mappings.<conditionKey>, not, and, or, and parentheses.\"));\n return null;\n }\n tokens.push({ kind: \"word\", value: match[0] });\n cursor += match[0].length;\n }\n return tokens;\n}\n\nfunction parseExpression(source: string, issues: StoreCategoryPromptTemplateIssue[], referenced: string[]): ExpressionNode | null {\n const tokens = lexExpression(source, issues);\n if (!tokens || tokens.length === 0) {\n if (tokens?.length === 0) issues.push(issue(\"invalid_template_expression\", \"A conditional expression is required.\"));\n return null;\n }\n let index = 0;\n const peekWord = (word: string) => {\n const token = tokens[index];\n return token?.kind === \"word\" && token.value === word;\n };\n\n const parsePrimary = (): ExpressionNode | null => {\n const token = tokens[index];\n if (token?.kind === \"lparen\") {\n index += 1;\n const inner = parseOr();\n if (tokens[index]?.kind !== \"rparen\") {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expression parentheses are unbalanced.\"));\n return null;\n }\n index += 1;\n return inner;\n }\n if (!peekWord(\"mappings\")) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expressions must reference mappings.<conditionKey>.\"));\n return null;\n }\n index += 1;\n if (tokens[index]?.kind !== \"dot\") {\n issues.push(issue(\"invalid_template_expression\", \"Mapping conditions must use mappings.<conditionKey>.\"));\n return null;\n }\n index += 1;\n const keyToken = tokens[index];\n if (keyToken?.kind !== \"word\") {\n issues.push(issue(\"invalid_mapping_condition\", \"A valid mapping condition key is required after mappings.\"));\n return null;\n }\n index += 1;\n if (!StoreCategoryPromptConditionKeySchema.safeParse(keyToken.value).success) {\n issues.push(issue(\"invalid_mapping_condition\", `Invalid mapping condition key: ${keyToken.value}.`));\n return null;\n }\n if (!referenced.includes(keyToken.value)) referenced.push(keyToken.value);\n return { kind: \"condition\", key: keyToken.value };\n };\n\n const parseNot = (): ExpressionNode | null => {\n if (peekWord(\"not\")) {\n index += 1;\n const operand = parseNot();\n return operand ? { kind: \"not\", operand } : null;\n }\n return parsePrimary();\n };\n\n const parseAnd = (): ExpressionNode | null => {\n let left = parseNot();\n while (left && peekWord(\"and\")) {\n index += 1;\n const right = parseNot();\n if (!right) return null;\n left = { kind: \"and\", left, right };\n }\n return left;\n };\n\n const parseOr = (): ExpressionNode | null => {\n let left = parseAnd();\n while (left && peekWord(\"or\")) {\n index += 1;\n const right = parseAnd();\n if (!right) return null;\n left = { kind: \"or\", left, right };\n }\n return left;\n };\n\n const expression = parseOr();\n if (expression && index !== tokens.length) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expression contains unsupported syntax.\"));\n return null;\n }\n return expression;\n}\n\nfunction compileStoreCategoryPromptTemplate(source: string): CompileResult {\n const issues: StoreCategoryPromptTemplateIssue[] = [];\n const referencedConditionKeys: string[] = [];\n const nodes: TemplateNode[] = [];\n\n if (source.trim().length === 0) issues.push(issue(\"invalid_prompt_source\", \"Prompt template must not be blank.\"));\n if (sourceLength(source) > MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS) {\n issues.push(issue(\"invalid_prompt_source\", `Prompt template must not exceed ${MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS.toLocaleString()} characters.`));\n }\n\n const tokens = tokenizeTemplate(source, issues);\n type Frame = {\n node: Extract<TemplateNode, { kind: \"if\" }>;\n parentBody: TemplateNode[];\n currentBody: TemplateNode[];\n sawElse: boolean;\n };\n const stack: Frame[] = [];\n let currentBody = nodes;\n let controlCount = 0;\n\n for (const token of tokens) {\n if (token.kind === \"text\") {\n if (token.text) currentBody.push({ kind: \"text\", text: token.text });\n continue;\n }\n if (token.kind === \"unsupported\") {\n issues.push(issue(\n \"unsupported_template_construct\",\n token.marker === \"interpolation\"\n ? \"Variable interpolation is not supported in Store Category prompt templates.\"\n : \"Template comments are not supported in Store Category prompt templates.\",\n ));\n continue;\n }\n\n controlCount += 1;\n if (controlCount > MAX_CONTROL_TAGS) {\n issues.push(issue(\"template_too_complex\", `Prompt template must not contain more than ${MAX_CONTROL_TAGS} control tags.`));\n break;\n }\n\n const ifMatch = /^if\\s+([\\s\\S]+)$/.exec(token.source);\n if (ifMatch) {\n if (stack.length >= MAX_CONTROL_DEPTH) {\n issues.push(issue(\"template_too_complex\", `Conditional nesting must not exceed ${MAX_CONTROL_DEPTH} levels.`));\n continue;\n }\n const expression = parseExpression(ifMatch[1].trim(), issues, referencedConditionKeys);\n if (!expression) continue;\n const branchBody: TemplateNode[] = [];\n const node: Extract<TemplateNode, { kind: \"if\" }> = {\n kind: \"if\",\n branches: [{ expression, body: branchBody }],\n elseBody: null,\n };\n currentBody.push(node);\n const frame: Frame = { node, parentBody: currentBody, currentBody: branchBody, sawElse: false };\n stack.push(frame);\n currentBody = branchBody;\n continue;\n }\n\n const elifMatch = /^elif\\s+([\\s\\S]+)$/.exec(token.source);\n if (elifMatch) {\n const frame = stack.at(-1);\n if (!frame || frame.sawElse) {\n issues.push(issue(\"invalid_template_structure\", \"elif must appear inside an if block and before else.\"));\n continue;\n }\n const expression = parseExpression(elifMatch[1].trim(), issues, referencedConditionKeys);\n if (!expression) continue;\n const branchBody: TemplateNode[] = [];\n frame.node.branches.push({ expression, body: branchBody });\n frame.currentBody = branchBody;\n currentBody = branchBody;\n continue;\n }\n\n if (token.source === \"else\") {\n const frame = stack.at(-1);\n if (!frame || frame.sawElse) {\n issues.push(issue(\"invalid_template_structure\", \"else must appear once inside an if block.\"));\n continue;\n }\n const elseBody: TemplateNode[] = [];\n frame.node.elseBody = elseBody;\n frame.currentBody = elseBody;\n frame.sawElse = true;\n currentBody = elseBody;\n continue;\n }\n\n if (token.source === \"endif\") {\n const frame = stack.pop();\n if (!frame) {\n issues.push(issue(\"invalid_template_structure\", \"endif does not have a matching if block.\"));\n continue;\n }\n currentBody = frame.parentBody;\n continue;\n }\n\n issues.push(issue(\n \"unsupported_template_construct\",\n \"Only if, elif, else, and endif control tags are supported in Store Category prompt templates.\",\n ));\n }\n\n if (stack.length) issues.push(issue(\"invalid_template_structure\", \"Every if block must end with endif.\"));\n return { issues: boundedIssues(issues), nodes, referencedConditionKeys };\n}\n\nfunction validateAvailableConditionKeys(values: readonly string[], issues: StoreCategoryPromptTemplateIssue[]): Set<string> {\n if (values.length > MAX_STORE_CATEGORY_PROMPT_CONDITIONS) {\n issues.push(issue(\"template_too_complex\", `At most ${MAX_STORE_CATEGORY_PROMPT_CONDITIONS} mapping conditions are supported.`));\n }\n const keys = new Set<string>();\n for (const value of values.slice(0, MAX_STORE_CATEGORY_PROMPT_CONDITIONS + 1)) {\n if (!StoreCategoryPromptConditionKeySchema.safeParse(value).success) {\n issues.push(issue(\"invalid_mapping_condition\", `Invalid mapping condition key: ${value}.`));\n continue;\n }\n if (keys.has(value)) {\n issues.push(issue(\"invalid_mapping_condition\", `Duplicate mapping condition key: ${value}.`));\n continue;\n }\n keys.add(value);\n }\n return keys;\n}\n\nexport function validateStoreCategoryPromptTemplate(input: {\n source: string;\n availableConditionKeys: readonly string[];\n}): StoreCategoryPromptTemplateValidation {\n const compiled = compileStoreCategoryPromptTemplate(input.source);\n const issues = [...compiled.issues];\n const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);\n for (const key of compiled.referencedConditionKeys) {\n if (!available.has(key)) issues.push(issue(\"unknown_mapping_condition\", `Prompt template references unavailable mapping condition: mappings.${key}.`));\n }\n const bounded = boundedIssues(issues);\n return { valid: bounded.length === 0, issues: bounded, referencedConditionKeys: compiled.referencedConditionKeys };\n}\n\n\nexport function createStoreCategoryPromptConditionBlock(conditionKey: string): string {\n const parsed = StoreCategoryPromptConditionKeySchema.safeParse(conditionKey);\n if (!parsed.success) throw new TypeError(`Invalid mapping condition key: ${conditionKey}.`);\n return `{% if mappings.${conditionKey} %}\\n\\n{% endif %}`;\n}\n\nexport function createStoreCategoryPromptContext(input: {\n availableConditionKeys: readonly string[];\n selectedConditionKeys: readonly string[];\n}): StoreCategoryPromptContext {\n const issues: StoreCategoryPromptTemplateIssue[] = [];\n const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);\n const selected = validateAvailableConditionKeys(input.selectedConditionKeys, issues);\n for (const key of selected) {\n if (!available.has(key)) issues.push(issue(\"unknown_mapping_condition\", `Selected mapping condition is unavailable: ${key}.`));\n }\n if (issues.length) throw new TypeError(issues[0].message);\n const mappings = Object.create(null) as Record<string, boolean>;\n for (const key of available) mappings[key] = selected.has(key);\n return { mappings };\n}\n\nfunction evaluateExpression(expression: ExpressionNode, mappings: Record<string, boolean>): boolean {\n switch (expression.kind) {\n case \"condition\":\n return mappings[expression.key] === true;\n case \"not\":\n return !evaluateExpression(expression.operand, mappings);\n case \"and\":\n return evaluateExpression(expression.left, mappings) && evaluateExpression(expression.right, mappings);\n case \"or\":\n return evaluateExpression(expression.left, mappings) || evaluateExpression(expression.right, mappings);\n }\n}\n\nfunction renderNodes(nodes: TemplateNode[], mappings: Record<string, boolean>, append: (text: string) => boolean): boolean {\n for (const node of nodes) {\n if (node.kind === \"text\") {\n if (!append(node.text)) return false;\n continue;\n }\n let renderedBranch = false;\n for (const branch of node.branches) {\n if (evaluateExpression(branch.expression, mappings)) {\n if (!renderNodes(branch.body, mappings, append)) return false;\n renderedBranch = true;\n break;\n }\n }\n if (!renderedBranch && node.elseBody && !renderNodes(node.elseBody, mappings, append)) return false;\n }\n return true;\n}\n\nexport function renderStoreCategoryPromptTemplate(input: {\n source: string;\n context: StoreCategoryPromptContext;\n}): StoreCategoryPromptRenderResult {\n const contextResult = StoreCategoryPromptContextSchema.safeParse(input.context);\n if (!contextResult.success) {\n return { ok: false, issues: [issue(\"invalid_mapping_condition\", \"Store Category prompt context contains invalid mapping conditions.\")] };\n }\n const availableConditionKeys = Object.keys(contextResult.data.mappings);\n const validation = validateStoreCategoryPromptTemplate({ source: input.source, availableConditionKeys });\n if (!validation.valid) return { ok: false, issues: validation.issues };\n\n const compiled = compileStoreCategoryPromptTemplate(input.source);\n let output = \"\";\n let outputChars = 0;\n const append = (text: string) => {\n outputChars += sourceLength(text);\n if (outputChars > MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS) return false;\n output += text;\n return true;\n };\n const rendered = renderNodes(compiled.nodes, contextResult.data.mappings, append);\n if (!rendered) {\n return {\n ok: false,\n issues: [issue(\"rendered_prompt_too_large\", `Rendered prompt must not exceed ${MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS.toLocaleString()} characters.`)],\n };\n }\n return { ok: true, promptText: output, referencedConditionKeys: validation.referencedConditionKeys };\n}\n","import { z } from \"zod\";\n\nexport const CommerceOutreachToolContextSchema = z.strictObject({\n purpose: z.literal(\"INITIAL_RECOVERY_OUTREACH\"),\n});\n\nexport type CommerceOutreachToolContext =\n z.infer<typeof CommerceOutreachToolContextSchema>;\n","/** Synthetic examples; no provider identity, schema artifact or publication claim. */\nimport type {\n CommerceManifest,\n CommerceConversationGrant,\n CommerceTurnIdentity,\n} from \"./schemas\";\nimport {\n EMPTY_RESPONSE_CONTRACT,\n type CommerceFinalResponse,\n} from \"./response\";\nimport type { Digest } from \"./canonical-json\";\nimport { responseContractCanonicalJson } from \"./canonical-json\";\nimport type { PublishedToolDescriptor, CommerceToolDefinition } from \"./definitions\";\nexport const exampleTool: PublishedToolDescriptor = {\n toolId: \"tool-fixture\",\n toolRevisionId: \"revision-fixture\",\n name: \"never_seeded_catalogue_facts\",\n definitionVersion: \"1.0.0\",\n description: \"Read synthetic catalogue facts.\",\n inputSchema: {\n type: \"object\",\n properties: { handle: { type: \"string\", minLength: 1, maxLength: 255 } },\n required: [\"handle\"],\n additionalProperties: false,\n },\n};\nexport const exampleDefinition: CommerceToolDefinition = {\n name: exampleTool.name,\n definitionVersion: \"1.0.0\",\n description: exampleTool.description,\n inputSchema: exampleTool.inputSchema,\n execution: {\n kind: \"SHOPIFY_STOREFRONT_QUERY\",\n executorVersion: \"1.0.0\",\n apiVersion: \"2026-07\",\n schemaHash: \"a\".repeat(64),\n document:\n \"query ProductDetails($handle: String!) { product(handle: $handle) { title description } }\",\n operationName: \"ProductDetails\",\n variables: { handle: { input: \"handle\" } },\n resultPath: \"product\",\n },\n responseTemplate: {\n kind: \"text\",\n text: \"{{result.values.title}}: {{result.values.description}}\",\n unavailable: \"Product details could not be verified.\",\n },\n};\nexport const exampleTurn: CommerceTurnIdentity = {\n contractVersion: \"commerce.v1\",\n shopId: \"shop-fixture\",\n checkoutRecoveryId: \"recovery-fixture\",\n conversationId: \"conversation-fixture\",\n inboundVersion: 1,\n};\nexport function exampleManifest(\n digest: Digest,\n withTool = false,\n): CommerceManifest {\n const capabilities = withTool\n ? [{\n capabilityId: \"capability-fixture\",\n key: \"feature_product_read\",\n featureId: \"feature-fixture\",\n position: 0,\n toolDescriptor: structuredClone(exampleTool),\n }]\n : [];\n return {\n contractVersion: \"commerce.v1\",\n releaseId: \"release-fixture\",\n runnerCompatibility: \"^1.0.0\",\n capabilities,\n featureBehaviours: withTool\n ? [{ featureId: \"feature-fixture\", behaviourPrompt: \"Synthetic Feature behavior.\" }]\n : [],\n selectedCapabilityKeys: capabilities.map((capability) => capability.key),\n builtInTools: [],\n grantedTools: withTool\n ? [\n {\n toolId: exampleTool.toolId,\n toolRevisionId: exampleTool.toolRevisionId,\n toolName: exampleTool.name,\n definitionVersion: \"1.0.0\",\n capabilityKeys: [\"feature_product_read\"],\n },\n ]\n : [],\n responseContract: structuredClone(EMPTY_RESPONSE_CONTRACT),\n responseContractHash: digest(\n responseContractCanonicalJson(EMPTY_RESPONSE_CONTRACT),\n ),\n };\n}\nexport function exampleGrant(\n manifest: CommerceManifest,\n): CommerceConversationGrant {\n return {\n id: \"grant-fixture\",\n shopId: exampleTurn.shopId,\n conversationId: exampleTurn.conversationId,\n initialInboundVersion: 1,\n releaseId: manifest.releaseId,\n selectedCapabilityKeys: [...manifest.selectedCapabilityKeys],\n grantedTools: structuredClone(manifest.grantedTools),\n runnerVersion: \"1.0.0\",\n createdAt: \"2026-09-20T00:00:00.000Z\",\n expiresAt: null,\n };\n}\nexport const exampleFinal: CommerceFinalResponse = {\n answerKind: \"REFER_TO_STORE\",\n replyText:\n \"I cannot verify that information. Please contact the store directly.\",\n referralReason: \"INSUFFICIENT_TOOLS\",\n detectedLanguageTag: null,\n detectedLanguageConfidence: null,\n evidenceIds: [],\n details: {},\n};\n"],"mappings":"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","names":["z"]}
1
+ {"version":3,"sources":["../../src/commerce/discount-capability-contracts.ts","../../src/commerce/store-category-prompt.ts","../../src/commerce/outreach-context.ts","../../src/commerce/fixtures.ts"],"sourcesContent":["import { CommerceToolInputs, CommerceToolOutputs } from \"./schemas.js\";\n\n/**\n * Canonical Shared mapping for the two published discount capabilities.\n * Consumers reuse these validators instead of maintaining local copies.\n * `operationVersion` is independent of immutable published tool definition\n * versions selected by Commerce during publication.\n */\nexport const DISCOUNT_POLICY_OPERATION_DESCRIPTORS = Object.freeze([\n Object.freeze({\n toolName: \"commerce_get_discount_options\",\n displayName: \"Get Discount Options\",\n operation: \"discounts.getOptions\",\n operationVersion: \"1.0.0\",\n description: \"Read the configured discount mode and available offers.\",\n inputValidator: CommerceToolInputs.commerce_get_discount_options,\n outputValidator: CommerceToolOutputs.commerce_get_discount_options,\n }),\n Object.freeze({\n toolName: \"commerce_get_discount_details\",\n displayName: \"Get Discount Details\",\n operation: \"discounts.getDetails\",\n operationVersion: \"1.0.0\",\n description: \"Read details and condition facts for a permitted discount.\",\n inputValidator: CommerceToolInputs.commerce_get_discount_details,\n outputValidator: CommerceToolOutputs.commerce_get_discount_details,\n }),\n] as const);\n\nexport type DiscountPolicyOperationDescriptor =\n (typeof DISCOUNT_POLICY_OPERATION_DESCRIPTORS)[number];\n","import { z } from \"zod\";\n\nexport const STORE_CATEGORY_PROMPT_RUNTIME_VERSION = \"store-category-prompt.v1\" as const;\nexport const MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS = 100_000;\nexport const MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS = 100_000;\nexport const MAX_STORE_CATEGORY_PROMPT_CONDITIONS = 256;\nconst MAX_CONTROL_TAGS = 512;\nconst MAX_CONTROL_DEPTH = 8;\nconst MAX_EXPRESSION_CHARS = 1_024;\n\nconst forbiddenConditionKeys = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst conditionKeyPattern = /^[a-z][a-z0-9_]{0,127}$/;\n\nexport const StoreCategoryPromptConditionKeySchema = z\n .string()\n .regex(conditionKeyPattern)\n .refine((value) => !forbiddenConditionKeys.has(value));\n\nexport type StoreCategoryPromptConditionKey = z.infer<typeof StoreCategoryPromptConditionKeySchema>;\n\nexport const StoreCategoryPromptContextSchema = z.strictObject({\n mappings: z\n .record(StoreCategoryPromptConditionKeySchema, z.boolean())\n .refine((value) => Object.keys(value).length <= MAX_STORE_CATEGORY_PROMPT_CONDITIONS),\n});\n\nexport type StoreCategoryPromptContext = z.infer<typeof StoreCategoryPromptContextSchema>;\n\nexport type StoreCategoryPromptTemplateIssue = {\n path: \"/promptText\";\n code:\n | \"invalid_prompt_source\"\n | \"unsupported_template_construct\"\n | \"invalid_template_structure\"\n | \"invalid_template_expression\"\n | \"invalid_mapping_condition\"\n | \"unknown_mapping_condition\"\n | \"template_too_complex\"\n | \"rendered_prompt_too_large\";\n message: string;\n};\n\nexport type StoreCategoryPromptTemplateValidation = {\n valid: boolean;\n issues: StoreCategoryPromptTemplateIssue[];\n referencedConditionKeys: string[];\n};\n\nexport type StoreCategoryPromptRenderResult =\n | { ok: true; promptText: string; referencedConditionKeys: string[] }\n | { ok: false; issues: StoreCategoryPromptTemplateIssue[] };\n\ntype ExpressionNode =\n | { kind: \"condition\"; key: string }\n | { kind: \"not\"; operand: ExpressionNode }\n | { kind: \"and\"; left: ExpressionNode; right: ExpressionNode }\n | { kind: \"or\"; left: ExpressionNode; right: ExpressionNode };\n\ntype TemplateNode =\n | { kind: \"text\"; text: string }\n | {\n kind: \"if\";\n branches: Array<{ expression: ExpressionNode; body: TemplateNode[] }>;\n elseBody: TemplateNode[] | null;\n };\n\ntype TemplateToken =\n | { kind: \"text\"; text: string }\n | { kind: \"control\"; source: string }\n | { kind: \"unsupported\"; source: string; marker: \"interpolation\" | \"comment\" };\n\ntype CompileResult = {\n issues: StoreCategoryPromptTemplateIssue[];\n nodes: TemplateNode[];\n referencedConditionKeys: string[];\n};\n\nfunction issue(code: StoreCategoryPromptTemplateIssue[\"code\"], message: string): StoreCategoryPromptTemplateIssue {\n return { path: \"/promptText\", code, message };\n}\n\nfunction boundedIssues(issues: StoreCategoryPromptTemplateIssue[]): StoreCategoryPromptTemplateIssue[] {\n return issues.slice(0, 32).map((entry) => ({\n path: entry.path,\n code: entry.code,\n message: entry.message.slice(0, 512),\n }));\n}\n\nfunction sourceLength(value: string): number {\n return Array.from(value).length;\n}\n\nfunction findNextMarker(source: string, start: number): { index: number; marker: \"{%\" | \"{{\" | \"{#\" } | null {\n let best: { index: number; marker: \"{%\" | \"{{\" | \"{#\" } | null = null;\n for (const marker of [\"{%\", \"{{\", \"{#\"] as const) {\n const index = source.indexOf(marker, start);\n if (index >= 0 && (!best || index < best.index)) best = { index, marker };\n }\n return best;\n}\n\nfunction tokenizeTemplate(source: string, issues: StoreCategoryPromptTemplateIssue[]): TemplateToken[] {\n const tokens: TemplateToken[] = [];\n let cursor = 0;\n while (cursor < source.length) {\n const next = findNextMarker(source, cursor);\n if (!next) {\n tokens.push({ kind: \"text\", text: source.slice(cursor) });\n break;\n }\n if (next.index > cursor) tokens.push({ kind: \"text\", text: source.slice(cursor, next.index) });\n const closeMarker = next.marker === \"{%\" ? \"%}\" : next.marker === \"{{\" ? \"}}\" : \"#}\";\n const close = source.indexOf(closeMarker, next.index + 2);\n if (close < 0) {\n issues.push(issue(\"invalid_template_structure\", `Unclosed ${next.marker} template construct.`));\n tokens.push({ kind: \"text\", text: source.slice(next.index) });\n break;\n }\n const raw = source.slice(next.index + 2, close).trim();\n if (next.marker === \"{%\") tokens.push({ kind: \"control\", source: raw });\n else tokens.push({ kind: \"unsupported\", source: raw, marker: next.marker === \"{{\" ? \"interpolation\" : \"comment\" });\n cursor = close + 2;\n }\n if (source.length === 0) tokens.push({ kind: \"text\", text: \"\" });\n return tokens;\n}\n\ntype ExprToken = { kind: \"word\"; value: string } | { kind: \"dot\" } | { kind: \"lparen\" } | { kind: \"rparen\" };\n\nfunction lexExpression(source: string, issues: StoreCategoryPromptTemplateIssue[]): ExprToken[] | null {\n if (sourceLength(source) > MAX_EXPRESSION_CHARS) {\n issues.push(issue(\"template_too_complex\", `Conditional expressions must not exceed ${MAX_EXPRESSION_CHARS} characters.`));\n return null;\n }\n const tokens: ExprToken[] = [];\n let cursor = 0;\n while (cursor < source.length) {\n const char = source[cursor];\n if (/\\s/.test(char)) {\n cursor += 1;\n continue;\n }\n if (char === \".\") {\n tokens.push({ kind: \"dot\" });\n cursor += 1;\n continue;\n }\n if (char === \"(\") {\n tokens.push({ kind: \"lparen\" });\n cursor += 1;\n continue;\n }\n if (char === \")\") {\n tokens.push({ kind: \"rparen\" });\n cursor += 1;\n continue;\n }\n const match = /^[A-Za-z_][A-Za-z0-9_]*/.exec(source.slice(cursor));\n if (!match) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expressions may only use mappings.<conditionKey>, not, and, or, and parentheses.\"));\n return null;\n }\n tokens.push({ kind: \"word\", value: match[0] });\n cursor += match[0].length;\n }\n return tokens;\n}\n\nfunction parseExpression(source: string, issues: StoreCategoryPromptTemplateIssue[], referenced: string[]): ExpressionNode | null {\n const tokens = lexExpression(source, issues);\n if (!tokens || tokens.length === 0) {\n if (tokens?.length === 0) issues.push(issue(\"invalid_template_expression\", \"A conditional expression is required.\"));\n return null;\n }\n let index = 0;\n const peekWord = (word: string) => {\n const token = tokens[index];\n return token?.kind === \"word\" && token.value === word;\n };\n\n const parsePrimary = (): ExpressionNode | null => {\n const token = tokens[index];\n if (token?.kind === \"lparen\") {\n index += 1;\n const inner = parseOr();\n if (tokens[index]?.kind !== \"rparen\") {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expression parentheses are unbalanced.\"));\n return null;\n }\n index += 1;\n return inner;\n }\n if (!peekWord(\"mappings\")) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expressions must reference mappings.<conditionKey>.\"));\n return null;\n }\n index += 1;\n if (tokens[index]?.kind !== \"dot\") {\n issues.push(issue(\"invalid_template_expression\", \"Mapping conditions must use mappings.<conditionKey>.\"));\n return null;\n }\n index += 1;\n const keyToken = tokens[index];\n if (keyToken?.kind !== \"word\") {\n issues.push(issue(\"invalid_mapping_condition\", \"A valid mapping condition key is required after mappings.\"));\n return null;\n }\n index += 1;\n if (!StoreCategoryPromptConditionKeySchema.safeParse(keyToken.value).success) {\n issues.push(issue(\"invalid_mapping_condition\", `Invalid mapping condition key: ${keyToken.value}.`));\n return null;\n }\n if (!referenced.includes(keyToken.value)) referenced.push(keyToken.value);\n return { kind: \"condition\", key: keyToken.value };\n };\n\n const parseNot = (): ExpressionNode | null => {\n if (peekWord(\"not\")) {\n index += 1;\n const operand = parseNot();\n return operand ? { kind: \"not\", operand } : null;\n }\n return parsePrimary();\n };\n\n const parseAnd = (): ExpressionNode | null => {\n let left = parseNot();\n while (left && peekWord(\"and\")) {\n index += 1;\n const right = parseNot();\n if (!right) return null;\n left = { kind: \"and\", left, right };\n }\n return left;\n };\n\n const parseOr = (): ExpressionNode | null => {\n let left = parseAnd();\n while (left && peekWord(\"or\")) {\n index += 1;\n const right = parseAnd();\n if (!right) return null;\n left = { kind: \"or\", left, right };\n }\n return left;\n };\n\n const expression = parseOr();\n if (expression && index !== tokens.length) {\n issues.push(issue(\"invalid_template_expression\", \"Conditional expression contains unsupported syntax.\"));\n return null;\n }\n return expression;\n}\n\nfunction compileStoreCategoryPromptTemplate(source: string): CompileResult {\n const issues: StoreCategoryPromptTemplateIssue[] = [];\n const referencedConditionKeys: string[] = [];\n const nodes: TemplateNode[] = [];\n\n if (source.trim().length === 0) issues.push(issue(\"invalid_prompt_source\", \"Prompt template must not be blank.\"));\n if (sourceLength(source) > MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS) {\n issues.push(issue(\"invalid_prompt_source\", `Prompt template must not exceed ${MAX_STORE_CATEGORY_PROMPT_SOURCE_CHARS.toLocaleString()} characters.`));\n }\n\n const tokens = tokenizeTemplate(source, issues);\n type Frame = {\n node: Extract<TemplateNode, { kind: \"if\" }>;\n parentBody: TemplateNode[];\n currentBody: TemplateNode[];\n sawElse: boolean;\n };\n const stack: Frame[] = [];\n let currentBody = nodes;\n let controlCount = 0;\n\n for (const token of tokens) {\n if (token.kind === \"text\") {\n if (token.text) currentBody.push({ kind: \"text\", text: token.text });\n continue;\n }\n if (token.kind === \"unsupported\") {\n issues.push(issue(\n \"unsupported_template_construct\",\n token.marker === \"interpolation\"\n ? \"Variable interpolation is not supported in Store Category prompt templates.\"\n : \"Template comments are not supported in Store Category prompt templates.\",\n ));\n continue;\n }\n\n controlCount += 1;\n if (controlCount > MAX_CONTROL_TAGS) {\n issues.push(issue(\"template_too_complex\", `Prompt template must not contain more than ${MAX_CONTROL_TAGS} control tags.`));\n break;\n }\n\n const ifMatch = /^if\\s+([\\s\\S]+)$/.exec(token.source);\n if (ifMatch) {\n if (stack.length >= MAX_CONTROL_DEPTH) {\n issues.push(issue(\"template_too_complex\", `Conditional nesting must not exceed ${MAX_CONTROL_DEPTH} levels.`));\n continue;\n }\n const expression = parseExpression(ifMatch[1].trim(), issues, referencedConditionKeys);\n if (!expression) continue;\n const branchBody: TemplateNode[] = [];\n const node: Extract<TemplateNode, { kind: \"if\" }> = {\n kind: \"if\",\n branches: [{ expression, body: branchBody }],\n elseBody: null,\n };\n currentBody.push(node);\n const frame: Frame = { node, parentBody: currentBody, currentBody: branchBody, sawElse: false };\n stack.push(frame);\n currentBody = branchBody;\n continue;\n }\n\n const elifMatch = /^elif\\s+([\\s\\S]+)$/.exec(token.source);\n if (elifMatch) {\n const frame = stack.at(-1);\n if (!frame || frame.sawElse) {\n issues.push(issue(\"invalid_template_structure\", \"elif must appear inside an if block and before else.\"));\n continue;\n }\n const expression = parseExpression(elifMatch[1].trim(), issues, referencedConditionKeys);\n if (!expression) continue;\n const branchBody: TemplateNode[] = [];\n frame.node.branches.push({ expression, body: branchBody });\n frame.currentBody = branchBody;\n currentBody = branchBody;\n continue;\n }\n\n if (token.source === \"else\") {\n const frame = stack.at(-1);\n if (!frame || frame.sawElse) {\n issues.push(issue(\"invalid_template_structure\", \"else must appear once inside an if block.\"));\n continue;\n }\n const elseBody: TemplateNode[] = [];\n frame.node.elseBody = elseBody;\n frame.currentBody = elseBody;\n frame.sawElse = true;\n currentBody = elseBody;\n continue;\n }\n\n if (token.source === \"endif\") {\n const frame = stack.pop();\n if (!frame) {\n issues.push(issue(\"invalid_template_structure\", \"endif does not have a matching if block.\"));\n continue;\n }\n currentBody = frame.parentBody;\n continue;\n }\n\n issues.push(issue(\n \"unsupported_template_construct\",\n \"Only if, elif, else, and endif control tags are supported in Store Category prompt templates.\",\n ));\n }\n\n if (stack.length) issues.push(issue(\"invalid_template_structure\", \"Every if block must end with endif.\"));\n return { issues: boundedIssues(issues), nodes, referencedConditionKeys };\n}\n\nfunction validateAvailableConditionKeys(values: readonly string[], issues: StoreCategoryPromptTemplateIssue[]): Set<string> {\n if (values.length > MAX_STORE_CATEGORY_PROMPT_CONDITIONS) {\n issues.push(issue(\"template_too_complex\", `At most ${MAX_STORE_CATEGORY_PROMPT_CONDITIONS} mapping conditions are supported.`));\n }\n const keys = new Set<string>();\n for (const value of values.slice(0, MAX_STORE_CATEGORY_PROMPT_CONDITIONS + 1)) {\n if (!StoreCategoryPromptConditionKeySchema.safeParse(value).success) {\n issues.push(issue(\"invalid_mapping_condition\", `Invalid mapping condition key: ${value}.`));\n continue;\n }\n if (keys.has(value)) {\n issues.push(issue(\"invalid_mapping_condition\", `Duplicate mapping condition key: ${value}.`));\n continue;\n }\n keys.add(value);\n }\n return keys;\n}\n\nexport function validateStoreCategoryPromptTemplate(input: {\n source: string;\n availableConditionKeys: readonly string[];\n}): StoreCategoryPromptTemplateValidation {\n const compiled = compileStoreCategoryPromptTemplate(input.source);\n const issues = [...compiled.issues];\n const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);\n for (const key of compiled.referencedConditionKeys) {\n if (!available.has(key)) issues.push(issue(\"unknown_mapping_condition\", `Prompt template references unavailable mapping condition: mappings.${key}.`));\n }\n const bounded = boundedIssues(issues);\n return { valid: bounded.length === 0, issues: bounded, referencedConditionKeys: compiled.referencedConditionKeys };\n}\n\n\nexport function createStoreCategoryPromptConditionBlock(conditionKey: string): string {\n const parsed = StoreCategoryPromptConditionKeySchema.safeParse(conditionKey);\n if (!parsed.success) throw new TypeError(`Invalid mapping condition key: ${conditionKey}.`);\n return `{% if mappings.${conditionKey} %}\\n\\n{% endif %}`;\n}\n\nexport function createStoreCategoryPromptContext(input: {\n availableConditionKeys: readonly string[];\n selectedConditionKeys: readonly string[];\n}): StoreCategoryPromptContext {\n const issues: StoreCategoryPromptTemplateIssue[] = [];\n const available = validateAvailableConditionKeys(input.availableConditionKeys, issues);\n const selected = validateAvailableConditionKeys(input.selectedConditionKeys, issues);\n for (const key of selected) {\n if (!available.has(key)) issues.push(issue(\"unknown_mapping_condition\", `Selected mapping condition is unavailable: ${key}.`));\n }\n if (issues.length) throw new TypeError(issues[0].message);\n const mappings = Object.create(null) as Record<string, boolean>;\n for (const key of available) mappings[key] = selected.has(key);\n return { mappings };\n}\n\nfunction evaluateExpression(expression: ExpressionNode, mappings: Record<string, boolean>): boolean {\n switch (expression.kind) {\n case \"condition\":\n return mappings[expression.key] === true;\n case \"not\":\n return !evaluateExpression(expression.operand, mappings);\n case \"and\":\n return evaluateExpression(expression.left, mappings) && evaluateExpression(expression.right, mappings);\n case \"or\":\n return evaluateExpression(expression.left, mappings) || evaluateExpression(expression.right, mappings);\n }\n}\n\nfunction renderNodes(nodes: TemplateNode[], mappings: Record<string, boolean>, append: (text: string) => boolean): boolean {\n for (const node of nodes) {\n if (node.kind === \"text\") {\n if (!append(node.text)) return false;\n continue;\n }\n let renderedBranch = false;\n for (const branch of node.branches) {\n if (evaluateExpression(branch.expression, mappings)) {\n if (!renderNodes(branch.body, mappings, append)) return false;\n renderedBranch = true;\n break;\n }\n }\n if (!renderedBranch && node.elseBody && !renderNodes(node.elseBody, mappings, append)) return false;\n }\n return true;\n}\n\nexport function renderStoreCategoryPromptTemplate(input: {\n source: string;\n context: StoreCategoryPromptContext;\n}): StoreCategoryPromptRenderResult {\n const contextResult = StoreCategoryPromptContextSchema.safeParse(input.context);\n if (!contextResult.success) {\n return { ok: false, issues: [issue(\"invalid_mapping_condition\", \"Store Category prompt context contains invalid mapping conditions.\")] };\n }\n const availableConditionKeys = Object.keys(contextResult.data.mappings);\n const validation = validateStoreCategoryPromptTemplate({ source: input.source, availableConditionKeys });\n if (!validation.valid) return { ok: false, issues: validation.issues };\n\n const compiled = compileStoreCategoryPromptTemplate(input.source);\n let output = \"\";\n let outputChars = 0;\n const append = (text: string) => {\n outputChars += sourceLength(text);\n if (outputChars > MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS) return false;\n output += text;\n return true;\n };\n const rendered = renderNodes(compiled.nodes, contextResult.data.mappings, append);\n if (!rendered) {\n return {\n ok: false,\n issues: [issue(\"rendered_prompt_too_large\", `Rendered prompt must not exceed ${MAX_STORE_CATEGORY_PROMPT_RENDERED_CHARS.toLocaleString()} characters.`)],\n };\n }\n return { ok: true, promptText: output, referencedConditionKeys: validation.referencedConditionKeys };\n}\n","import { z } from \"zod\";\n\nexport const CommerceOutreachToolContextSchema = z.strictObject({\n purpose: z.literal(\"INITIAL_RECOVERY_OUTREACH\"),\n});\n\nexport type CommerceOutreachToolContext =\n z.infer<typeof CommerceOutreachToolContextSchema>;\n","/** Synthetic examples; no provider identity, schema artifact or publication claim. */\nimport type {\n CommerceManifest,\n CommerceConversationGrant,\n CommerceTurnIdentity,\n} from \"./schemas\";\nimport {\n EMPTY_RESPONSE_CONTRACT,\n type CommerceFinalResponse,\n} from \"./response\";\nimport type { Digest } from \"./canonical-json\";\nimport { responseContractCanonicalJson } from \"./canonical-json\";\nimport type { PublishedToolDescriptor, CommerceToolDefinition } from \"./definitions\";\nexport const exampleTool: PublishedToolDescriptor = {\n toolId: \"tool-fixture\",\n toolRevisionId: \"revision-fixture\",\n name: \"never_seeded_catalogue_facts\",\n definitionVersion: \"1.0.0\",\n description: \"Read synthetic catalogue facts.\",\n inputSchema: {\n type: \"object\",\n properties: { handle: { type: \"string\", minLength: 1, maxLength: 255 } },\n required: [\"handle\"],\n additionalProperties: false,\n },\n};\nexport const exampleDefinition: CommerceToolDefinition = {\n name: exampleTool.name,\n definitionVersion: \"1.0.0\",\n description: exampleTool.description,\n inputSchema: exampleTool.inputSchema,\n execution: {\n kind: \"SHOPIFY_STOREFRONT_QUERY\",\n executorVersion: \"1.0.0\",\n apiVersion: \"2026-07\",\n schemaHash: \"a\".repeat(64),\n document:\n \"query ProductDetails($handle: String!) { product(handle: $handle) { title description } }\",\n operationName: \"ProductDetails\",\n variables: { handle: { input: \"handle\" } },\n resultPath: \"product\",\n },\n responseTemplate: {\n kind: \"text\",\n text: \"{{result.values.title}}: {{result.values.description}}\",\n unavailable: \"Product details could not be verified.\",\n },\n};\nexport const exampleTurn: CommerceTurnIdentity = {\n contractVersion: \"commerce.v1\",\n shopId: \"shop-fixture\",\n checkoutRecoveryId: \"recovery-fixture\",\n conversationId: \"conversation-fixture\",\n inboundVersion: 1,\n};\nexport function exampleManifest(\n digest: Digest,\n withTool = false,\n): CommerceManifest {\n const capabilities = withTool\n ? [{\n capabilityId: \"capability-fixture\",\n key: \"feature_product_read\",\n featureId: \"feature-fixture\",\n position: 0,\n toolDescriptor: structuredClone(exampleTool),\n }]\n : [];\n return {\n contractVersion: \"commerce.v1\",\n releaseId: \"release-fixture\",\n runnerCompatibility: \"^1.0.0\",\n capabilities,\n featureBehaviours: withTool\n ? [{ featureId: \"feature-fixture\", behaviourPrompt: \"Synthetic Feature behavior.\" }]\n : [],\n selectedCapabilityKeys: capabilities.map((capability) => capability.key),\n builtInTools: [],\n grantedTools: withTool\n ? [\n {\n toolId: exampleTool.toolId,\n toolRevisionId: exampleTool.toolRevisionId,\n toolName: exampleTool.name,\n definitionVersion: \"1.0.0\",\n capabilityKeys: [\"feature_product_read\"],\n },\n ]\n : [],\n responseContract: structuredClone(EMPTY_RESPONSE_CONTRACT),\n responseContractHash: digest(\n responseContractCanonicalJson(EMPTY_RESPONSE_CONTRACT),\n ),\n };\n}\nexport function exampleGrant(\n manifest: CommerceManifest,\n): CommerceConversationGrant {\n return {\n id: \"grant-fixture\",\n shopId: exampleTurn.shopId,\n conversationId: exampleTurn.conversationId,\n initialInboundVersion: 1,\n releaseId: manifest.releaseId,\n selectedCapabilityKeys: [...manifest.selectedCapabilityKeys],\n grantedTools: structuredClone(manifest.grantedTools),\n runnerVersion: \"1.0.0\",\n createdAt: \"2026-09-20T00:00:00.000Z\",\n expiresAt: null,\n };\n}\nexport const exampleFinal: CommerceFinalResponse = {\n answerKind: \"REFER_TO_STORE\",\n replyText:\n \"I cannot verify that information. Please contact the store directly.\",\n referralReason: \"INSUFFICIENT_TOOLS\",\n detectedLanguageTag: null,\n detectedLanguageConfidence: null,\n evidenceIds: [],\n details: {},\n};\n"],"mappings":"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","names":["z"]}
@@ -1,7 +1,7 @@
1
- import { R as RunnerTransportCode, C as CommerceModelInvoker, M as ModelStep } from '../../types-BXeYmpeg.js';
1
+ import { R as RunnerTransportCode, C as CommerceModelInvoker, M as ModelStep } from '../../types-CxiCD8Pw.js';
2
2
  import { CommerceModelProvider, CommerceProviderModelId } from './index.js';
3
- import '../../product-context-qfk6k9uk.js';
4
- import '../../response-DD6HXT8s.js';
3
+ import '../../product-context-D1Xfe1FX.js';
4
+ import '../../response-gHpvLkzy.js';
5
5
  import 'zod';
6
6
  import '../../types-B32wDMLO.js';
7
7
 
@@ -4,7 +4,7 @@ import {
4
4
  } from "../../chunk-WONND3OK.js";
5
5
  import {
6
6
  CommerceToolResultSchema
7
- } from "../../chunk-SW2AFMT7.js";
7
+ } from "../../chunk-W5Y5ZLGN.js";
8
8
  import "../../chunk-GCCT2BDE.js";
9
9
  import "../../chunk-4KSODB2R.js";
10
10
  import {
@@ -1,8 +1,8 @@
1
1
  import { z } from 'zod';
2
- import { g as CommerceToolInputs } from '../../response-DD6HXT8s.js';
3
- import { C as CommerceModelInvoker } from '../../types-BXeYmpeg.js';
2
+ import { g as CommerceToolInputs } from '../../response-gHpvLkzy.js';
3
+ import { C as CommerceModelInvoker } from '../../types-CxiCD8Pw.js';
4
4
  import { S as StructuredLogger } from '../../types-B32wDMLO.js';
5
- import '../../product-context-qfk6k9uk.js';
5
+ import '../../product-context-D1Xfe1FX.js';
6
6
 
7
7
  declare const StageSchema: z.ZodEnum<{
8
8
  COMPLETE: "COMPLETE";
@@ -126,6 +126,18 @@ declare const InitialOutreachEvaluationResultSchema: z.ZodDiscriminatedUnion<[z.
126
126
  quantity: z.ZodNumber;
127
127
  checkoutUnitPrice: z.ZodNullable<z.ZodString>;
128
128
  currentProduct: z.ZodObject<{
129
+ stock: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
130
+ status: z.ZodLiteral<"KNOWN">;
131
+ quantity: z.ZodNumber;
132
+ scope: z.ZodEnum<{
133
+ PRODUCT: "PRODUCT";
134
+ VARIANT: "VARIANT";
135
+ }>;
136
+ }, z.core.$strict>, z.ZodObject<{
137
+ status: z.ZodLiteral<"NOT_TRACKED">;
138
+ }, z.core.$strict>, z.ZodObject<{
139
+ status: z.ZodLiteral<"UNAVAILABLE">;
140
+ }, z.core.$strict>], "status">>;
129
141
  description: z.ZodOptional<z.ZodPreprocess<z.ZodObject<{
130
142
  status: z.ZodEnum<{
131
143
  AVAILABLE: "AVAILABLE";
@@ -691,6 +703,18 @@ declare const InitialOutreachRenderInputSchema: z.ZodObject<{
691
703
  quantity: z.ZodNumber;
692
704
  checkoutUnitPrice: z.ZodNullable<z.ZodString>;
693
705
  currentProduct: z.ZodObject<{
706
+ stock: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
707
+ status: z.ZodLiteral<"KNOWN">;
708
+ quantity: z.ZodNumber;
709
+ scope: z.ZodEnum<{
710
+ PRODUCT: "PRODUCT";
711
+ VARIANT: "VARIANT";
712
+ }>;
713
+ }, z.core.$strict>, z.ZodObject<{
714
+ status: z.ZodLiteral<"NOT_TRACKED">;
715
+ }, z.core.$strict>, z.ZodObject<{
716
+ status: z.ZodLiteral<"UNAVAILABLE">;
717
+ }, z.core.$strict>], "status">>;
694
718
  description: z.ZodOptional<z.ZodPreprocess<z.ZodObject<{
695
719
  status: z.ZodEnum<{
696
720
  AVAILABLE: "AVAILABLE";
@@ -1428,6 +1452,18 @@ declare const StudioInitialOutreachRenderInputSchema: z.ZodObject<{
1428
1452
  quantity: z.ZodNumber;
1429
1453
  checkoutUnitPrice: z.ZodNullable<z.ZodString>;
1430
1454
  currentProduct: z.ZodObject<{
1455
+ stock: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
1456
+ status: z.ZodLiteral<"KNOWN">;
1457
+ quantity: z.ZodNumber;
1458
+ scope: z.ZodEnum<{
1459
+ PRODUCT: "PRODUCT";
1460
+ VARIANT: "VARIANT";
1461
+ }>;
1462
+ }, z.core.$strict>, z.ZodObject<{
1463
+ status: z.ZodLiteral<"NOT_TRACKED">;
1464
+ }, z.core.$strict>, z.ZodObject<{
1465
+ status: z.ZodLiteral<"UNAVAILABLE">;
1466
+ }, z.core.$strict>], "status">>;
1431
1467
  description: z.ZodOptional<z.ZodPreprocess<z.ZodObject<{
1432
1468
  status: z.ZodEnum<{
1433
1469
  AVAILABLE: "AVAILABLE";
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  PLATFORM_INSTRUCTIONS,
6
6
  RUNTIME_DATA_AUTHORITY_INSTRUCTION
7
- } from "../../chunk-WHZAAF2Q.js";
7
+ } from "../../chunk-5TBA3WLV.js";
8
8
  import {
9
9
  CommerceModelInvocationFailure
10
10
  } from "../../chunk-WONND3OK.js";
@@ -12,7 +12,7 @@ import {
12
12
  CommerceProductSchema,
13
13
  CommerceToolInputs,
14
14
  CommerceToolOutputs
15
- } from "../../chunk-SW2AFMT7.js";
15
+ } from "../../chunk-W5Y5ZLGN.js";
16
16
  import {
17
17
  CurrencySchema,
18
18
  DateSchema,
@@ -1,7 +1,7 @@
1
1
  import * as zod from 'zod';
2
2
  import { z } from 'zod';
3
3
  import { ModaSupportedLanguageTag, IcuMessageCatalogue, InternationalizationRuntime } from '../../internationalization.js';
4
- import { Y as CommerceShippingInformation, d as CommerceFinalResponse } from '../../response-DD6HXT8s.js';
4
+ import { _ as CommerceShippingInformation, d as CommerceFinalResponse } from '../../response-gHpvLkzy.js';
5
5
  import 'intl-messageformat';
6
6
 
7
7
  declare const CommerceVerifiedPresentationSchema: z.ZodObject<{
@@ -62,6 +62,19 @@ declare const CommerceVerifiedPresentationSchema: z.ZodObject<{
62
62
  }, z.core.$strict>>>;
63
63
  }, z.core.$strict>>;
64
64
  productFacts: z.ZodDefault<z.ZodArray<z.ZodObject<{
65
+ stock: z.ZodDiscriminatedUnion<[z.ZodObject<{
66
+ status: z.ZodLiteral<"KNOWN">;
67
+ quantity: z.ZodNumber;
68
+ scope: z.ZodEnum<{
69
+ PRODUCT: "PRODUCT";
70
+ VARIANT: "VARIANT";
71
+ }>;
72
+ }, z.core.$strict>, z.ZodObject<{
73
+ status: z.ZodLiteral<"NOT_TRACKED">;
74
+ }, z.core.$strict>, z.ZodObject<{
75
+ status: z.ZodLiteral<"UNAVAILABLE">;
76
+ }, z.core.$strict>], "status">;
77
+ observedAt: z.ZodISODateTime;
65
78
  productId: z.ZodString;
66
79
  variantId: z.ZodNullable<z.ZodString>;
67
80
  title: z.ZodString;
@@ -363,6 +376,19 @@ type CommerceWhatsAppPreviewResult = {
363
376
  declare function composeCommerceWhatsAppPreview(input: CommerceWhatsAppPreviewInput): CommerceWhatsAppPreviewResult;
364
377
 
365
378
  declare const CommerceProductFactSchema: z.ZodObject<{
379
+ stock: z.ZodDiscriminatedUnion<[z.ZodObject<{
380
+ status: z.ZodLiteral<"KNOWN">;
381
+ quantity: z.ZodNumber;
382
+ scope: z.ZodEnum<{
383
+ PRODUCT: "PRODUCT";
384
+ VARIANT: "VARIANT";
385
+ }>;
386
+ }, z.core.$strict>, z.ZodObject<{
387
+ status: z.ZodLiteral<"NOT_TRACKED">;
388
+ }, z.core.$strict>, z.ZodObject<{
389
+ status: z.ZodLiteral<"UNAVAILABLE">;
390
+ }, z.core.$strict>], "status">;
391
+ observedAt: z.ZodISODateTime;
366
392
  productId: z.ZodString;
367
393
  variantId: z.ZodNullable<z.ZodString>;
368
394
  title: z.ZodString;
@@ -416,5 +442,7 @@ declare function verifyCommerceProductFacts(selection: readonly {
416
442
  declare function renderCommerceProductFacts(facts: readonly CommerceProductFact[], locale: ModaSupportedLanguageTag): string;
417
443
 
418
444
  declare const productFactMessages: Readonly<Record<"tr" | "zh-Hans" | "zh-Hant" | "cs" | "da" | "nl" | "en" | "fi" | "fr" | "de" | "it" | "ja" | "ko" | "nb" | "pl" | "pt-BR" | "pt-PT" | "es" | "sv" | "th", readonly [string, string, string]>>;
445
+ /** Aggregate sellable counts for the exact selected identity, never a fulfillment promise. */
446
+ declare const stockFactMessages: Readonly<Record<ModaSupportedLanguageTag, readonly [string, string, string, string]>>;
419
447
 
420
- export { type CommerceOptionFact, CommerceOptionFactSchema, type CommerceProductFact, CommerceProductFactSchema, type CommerceVerifiedPresentation, CommerceVerifiedPresentationSchema, type CommerceWhatsAppPreviewInput, type CommerceWhatsAppPreviewResult, MAX_WHATSAPP_TEXT_LENGTH, type PreparedToken, type PreparedWrapper, type PresentationDigest, type RenderRecommendationProduct, type ShippingPresentation, type VerifiedWrapperContext, type WrapperAudience, type WrapperDefinition, type WrapperRefusal, type WrapperSlot, type WrapperSource, type WrapperVariable, buildReplyCandidates, canonicalTag, chooseSlot, composeCommerceWhatsAppPreview, currencyExponent, decimalToMinorUnits, digest, formatObservedMoney, isValidDecimal, languageChoices, minorUnitsToDecimal, normalizeCommerceReplyText, productFactMessages, productOptionMessages, readPreparedWrapper, recommendationMessage, recommendationMessageKeys, recommendationMessages, renderCommerceProductFacts, renderPreparedWrapper, renderProductOptionFacts, renderRecommendationReply, selectShippingPresentation, stableJson, sumPurchaseSubtotal, validDefinition, verifyCommerceOptionFacts, verifyCommerceProductFacts };
448
+ export { type CommerceOptionFact, CommerceOptionFactSchema, type CommerceProductFact, CommerceProductFactSchema, type CommerceVerifiedPresentation, CommerceVerifiedPresentationSchema, type CommerceWhatsAppPreviewInput, type CommerceWhatsAppPreviewResult, MAX_WHATSAPP_TEXT_LENGTH, type PreparedToken, type PreparedWrapper, type PresentationDigest, type RenderRecommendationProduct, type ShippingPresentation, type VerifiedWrapperContext, type WrapperAudience, type WrapperDefinition, type WrapperRefusal, type WrapperSlot, type WrapperSource, type WrapperVariable, buildReplyCandidates, canonicalTag, chooseSlot, composeCommerceWhatsAppPreview, currencyExponent, decimalToMinorUnits, digest, formatObservedMoney, isValidDecimal, languageChoices, minorUnitsToDecimal, normalizeCommerceReplyText, productFactMessages, productOptionMessages, readPreparedWrapper, recommendationMessage, recommendationMessageKeys, recommendationMessages, renderCommerceProductFacts, renderPreparedWrapper, renderProductOptionFacts, renderRecommendationReply, selectShippingPresentation, stableJson, stockFactMessages, sumPurchaseSubtotal, validDefinition, verifyCommerceOptionFacts, verifyCommerceProductFacts };
@@ -4,9 +4,12 @@ import {
4
4
  CommerceProductDescriptionSchema,
5
5
  CommerceProductOptionsSchema,
6
6
  CommerceProductSchema,
7
- CommerceProductSelectedOptionsSchema
8
- } from "../../chunk-SW2AFMT7.js";
9
- import "../../chunk-GCCT2BDE.js";
7
+ CommerceProductSelectedOptionsSchema,
8
+ CommerceProductStockSchema
9
+ } from "../../chunk-W5Y5ZLGN.js";
10
+ import {
11
+ DateSchema
12
+ } from "../../chunk-GCCT2BDE.js";
10
13
  import {
11
14
  MODA_SUPPORTED_LANGUAGE_TAGS,
12
15
  ModaSupportedLanguageTagSchema,
@@ -44,9 +47,31 @@ var labels = {
44
47
  tr: ["\xDCr\xFCn ayr\u0131nt\u0131lar\u0131 mevcut de\u011Fil.", "\xDCr\xFCn bilgileri eksik.", "Se\xE7ilen se\xE7enekler"]
45
48
  };
46
49
  var productFactMessages = Object.freeze(labels);
50
+ var stockFactMessages = Object.freeze({
51
+ en: ["Stock (product)", "Stock (selected variant)", "Stock is not tracked.", "Stock is unavailable."],
52
+ "zh-Hans": ["\u5E93\u5B58\uFF08\u5546\u54C1\uFF09", "\u5E93\u5B58\uFF08\u6240\u9009\u6B3E\u5F0F\uFF09", "\u672A\u8DDF\u8E2A\u5E93\u5B58\u3002", "\u5E93\u5B58\u4FE1\u606F\u4E0D\u53EF\u7528\u3002"],
53
+ "zh-Hant": ["\u5EAB\u5B58\uFF08\u5546\u54C1\uFF09", "\u5EAB\u5B58\uFF08\u6240\u9078\u6B3E\u5F0F\uFF09", "\u672A\u8FFD\u8E64\u5EAB\u5B58\u3002", "\u5EAB\u5B58\u8CC7\u8A0A\u7121\u6CD5\u53D6\u5F97\u3002"],
54
+ cs: ["Z\xE1soby (produkt)", "Z\xE1soby (vybran\xE1 varianta)", "Z\xE1soby nejsou sledov\xE1ny.", "Z\xE1soby nejsou dostupn\xE9."],
55
+ da: ["Lager (produkt)", "Lager (valgt variant)", "Lager spores ikke.", "Lageroplysninger er ikke tilg\xE6ngelige."],
56
+ nl: ["Voorraad (product)", "Voorraad (geselecteerde variant)", "Voorraad wordt niet bijgehouden.", "Voorraad is niet beschikbaar."],
57
+ fi: ["Varasto (tuote)", "Varasto (valittu vaihtoehto)", "Varastoa ei seurata.", "Varastotietoja ei ole saatavilla."],
58
+ fr: ["Stock (produit)", "Stock (variante s\xE9lectionn\xE9e)", "Le stock n\u2019est pas suivi.", "Le stock est indisponible."],
59
+ de: ["Bestand (Produkt)", "Bestand (ausgew\xE4hlte Variante)", "Der Bestand wird nicht verfolgt.", "Der Bestand ist nicht verf\xFCgbar."],
60
+ it: ["Scorte (prodotto)", "Scorte (variante selezionata)", "Le scorte non sono monitorate.", "Le scorte non sono disponibili."],
61
+ ja: ["\u5728\u5EAB\uFF08\u5546\u54C1\uFF09", "\u5728\u5EAB\uFF08\u9078\u629E\u3057\u305F\u30D0\u30EA\u30A8\u30FC\u30B7\u30E7\u30F3\uFF09", "\u5728\u5EAB\u306F\u8FFD\u8DE1\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002", "\u5728\u5EAB\u60C5\u5831\u3092\u78BA\u8A8D\u3067\u304D\u307E\u305B\u3093\u3002"],
62
+ ko: ["\uC7AC\uACE0 (\uC81C\uD488)", "\uC7AC\uACE0 (\uC120\uD0DD\uD55C \uC635\uC158)", "\uC7AC\uACE0\uB97C \uCD94\uC801\uD558\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4.", "\uC7AC\uACE0 \uC815\uBCF4\uB97C \uD655\uC778\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4."],
63
+ nb: ["Lager (produkt)", "Lager (valgt variant)", "Lager spores ikke.", "Lagerinformasjon er ikke tilgjengelig."],
64
+ pl: ["Stan magazynowy (produkt)", "Stan magazynowy (wybrany wariant)", "Stan magazynowy nie jest \u015Bledzony.", "Stan magazynowy jest niedost\u0119pny."],
65
+ "pt-BR": ["Estoque (produto)", "Estoque (variante selecionada)", "O estoque n\xE3o \xE9 acompanhado.", "O estoque est\xE1 indispon\xEDvel."],
66
+ "pt-PT": ["Stock (produto)", "Stock (variante selecionada)", "O stock n\xE3o \xE9 acompanhado.", "O stock est\xE1 indispon\xEDvel."],
67
+ es: ["Existencias (producto)", "Existencias (variante seleccionada)", "No se realiza seguimiento de existencias.", "Las existencias no est\xE1n disponibles."],
68
+ sv: ["Lager (produkt)", "Lager (vald variant)", "Lager sp\xE5ras inte.", "Lagerinformation \xE4r inte tillg\xE4nglig."],
69
+ th: ["\u0E2A\u0E15\u0E47\u0E2D\u0E01 (\u0E2A\u0E34\u0E19\u0E04\u0E49\u0E32)", "\u0E2A\u0E15\u0E47\u0E2D\u0E01 (\u0E15\u0E31\u0E27\u0E40\u0E25\u0E37\u0E2D\u0E01\u0E17\u0E35\u0E48\u0E40\u0E25\u0E37\u0E2D\u0E01)", "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E01\u0E32\u0E23\u0E15\u0E34\u0E14\u0E15\u0E32\u0E21\u0E2A\u0E15\u0E47\u0E2D\u0E01", "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E02\u0E49\u0E2D\u0E21\u0E39\u0E25\u0E2A\u0E15\u0E47\u0E2D\u0E01"],
70
+ tr: ["Stok (\xFCr\xFCn)", "Stok (se\xE7ilen varyant)", "Stok takip edilmiyor.", "Stok bilgisi mevcut de\u011Fil."]
71
+ });
47
72
 
48
73
  // src/commerce/presentation/facts.ts
49
- var CommerceProductFactSchema = z.strictObject({ productId: z.string().min(1).max(128), variantId: z.string().min(1).max(128).nullable(), title: z.string().min(1).max(512), description: CommerceProductDescriptionSchema, attributes: CommerceProductAttributesSchema, options: CommerceProductOptionsSchema, selectedOptions: CommerceProductSelectedOptionsSchema });
74
+ var CommerceProductFactSchema = z.strictObject({ stock: CommerceProductStockSchema, observedAt: DateSchema, productId: z.string().min(1).max(128), variantId: z.string().min(1).max(128).nullable(), title: z.string().min(1).max(512), description: CommerceProductDescriptionSchema, attributes: CommerceProductAttributesSchema, options: CommerceProductOptionsSchema, selectedOptions: CommerceProductSelectedOptionsSchema });
50
75
  function verifyCommerceProductFacts(selection, currentProducts) {
51
76
  const parsed = z.array(z.strictObject({ productId: z.string().min(1).max(128), variantId: z.string().min(1).max(128).nullable() })).max(3).safeParse(selection);
52
77
  if (!parsed.success || new Set(selection.map((s) => JSON.stringify([s.productId, s.variantId]))).size !== selection.length) return { kind: "limitation", reason: "INVALID_SELECTION" };
@@ -56,7 +81,7 @@ function verifyCommerceProductFacts(selection, currentProducts) {
56
81
  if (matches.length !== 1) return { kind: "limitation", reason: "PRODUCT_NOT_FOUND" };
57
82
  const product2 = CommerceProductSchema.safeParse(matches[0]);
58
83
  if (!product2.success) return { kind: "limitation", reason: "PRODUCT_INVALID" };
59
- facts.push({ productId: product2.data.productId, variantId: product2.data.variantId, title: product2.data.title, description: product2.data.description ?? { status: "PARTIAL", text: "" }, attributes: product2.data.attributes ?? { status: "PARTIAL", items: [] }, options: product2.data.options ?? { status: "PARTIAL", items: [] }, selectedOptions: product2.data.selectedOptions ?? [] });
84
+ facts.push({ stock: product2.data.stock ?? { status: "UNAVAILABLE" }, observedAt: product2.data.observedAt, productId: product2.data.productId, variantId: product2.data.variantId, title: product2.data.title, description: product2.data.description ?? { status: "PARTIAL", text: "" }, attributes: product2.data.attributes ?? { status: "PARTIAL", items: [] }, options: product2.data.options ?? { status: "PARTIAL", items: [] }, selectedOptions: product2.data.selectedOptions ?? [] });
60
85
  }
61
86
  return { kind: "verified", productFacts: facts };
62
87
  }
@@ -64,7 +89,8 @@ function renderCommerceProductFacts(facts, locale) {
64
89
  const [unavailable, incomplete, selected] = productFactMessages[locale];
65
90
  if (!facts.length) return unavailable;
66
91
  return facts.map((f) => {
67
- const lines = [];
92
+ const labels3 = stockFactMessages[locale];
93
+ const lines = [f.stock.status === "KNOWN" ? `${f.stock.scope === "VARIANT" ? labels3[1] : labels3[0]}: ${new Intl.NumberFormat(locale).format(f.stock.quantity)}` : f.stock.status === "NOT_TRACKED" ? labels3[2] : labels3[3]];
68
94
  if (f.description.text) lines.push(f.description.text);
69
95
  const selectedLines = [...new Set(f.selectedOptions.map((o) => `${o.name}: ${o.value}`))];
70
96
  const factLines = [...f.attributes.items.map((a) => `${a.name}: ${a.values.length ? a.values.join(", ") : unavailable}`), ...f.options.items.filter((o) => !f.attributes.items.some((a) => a.name === o.name && JSON.stringify(a.values) === JSON.stringify(o.values))).map((o) => `${o.name}: ${o.values.length ? o.values.join(", ") : unavailable}`)];
@@ -653,6 +679,7 @@ export {
653
679
  renderRecommendationReply,
654
680
  selectShippingPresentation,
655
681
  stableJson,
682
+ stockFactMessages,
656
683
  sumPurchaseSubtotal,
657
684
  validDefinition,
658
685
  verifyCommerceOptionFacts,