@modainteract/moda-interact-shared 2.7.0 → 2.7.2
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.
- package/dist/commerce/index.d.ts +0 -2
- package/dist/commerce/index.js +1 -3
- package/dist/commerce/index.js.map +1 -1
- package/dist/woocommerce/index.d.ts +155 -0
- package/dist/woocommerce/index.js +92 -0
- package/dist/woocommerce/index.js.map +1 -0
- package/package.json +8 -2
- package/src/woocommerce/__fixtures__/woo-restore-v1.json +69 -0
package/dist/commerce/index.d.ts
CHANGED
|
@@ -424,8 +424,6 @@ declare function renderStoreCategoryPromptTemplate(input: {
|
|
|
424
424
|
|
|
425
425
|
declare const CommerceOutreachToolContextSchema: z.ZodObject<{
|
|
426
426
|
purpose: z.ZodLiteral<"INITIAL_RECOVERY_OUTREACH">;
|
|
427
|
-
checkoutRecoveryId: z.ZodString;
|
|
428
|
-
outreachAttemptId: z.ZodString;
|
|
429
427
|
}, z.core.$strict>;
|
|
430
428
|
type CommerceOutreachToolContext = z.infer<typeof CommerceOutreachToolContextSchema>;
|
|
431
429
|
|
package/dist/commerce/index.js
CHANGED
|
@@ -481,9 +481,7 @@ function renderStoreCategoryPromptTemplate(input) {
|
|
|
481
481
|
// src/commerce/outreach-context.ts
|
|
482
482
|
import { z as z2 } from "zod";
|
|
483
483
|
var CommerceOutreachToolContextSchema = z2.strictObject({
|
|
484
|
-
purpose: z2.literal("INITIAL_RECOVERY_OUTREACH")
|
|
485
|
-
checkoutRecoveryId: IdSchema,
|
|
486
|
-
outreachAttemptId: IdSchema
|
|
484
|
+
purpose: z2.literal("INITIAL_RECOVERY_OUTREACH")
|
|
487
485
|
});
|
|
488
486
|
|
|
489
487
|
// src/commerce/fixtures.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commerce/store-category-prompt.ts","../../src/commerce/outreach-context.ts","../../src/commerce/fixtures.ts"],"sourcesContent":["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\";\nimport { IdSchema } from \"./primitives\";\n\nexport const CommerceOutreachToolContextSchema = z.strictObject({\n purpose: z.literal(\"INITIAL_RECOVERY_OUTREACH\"),\n checkoutRecoveryId: IdSchema,\n outreachAttemptId: IdSchema,\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 { ToolDescriptor, CommerceToolDefinition } from \"./definitions\";\nexport const exampleTool: ToolDescriptor = {\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 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","z"]}
|
|
1
|
+
{"version":3,"sources":["../../src/commerce/store-category-prompt.ts","../../src/commerce/outreach-context.ts","../../src/commerce/fixtures.ts"],"sourcesContent":["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 { ToolDescriptor, CommerceToolDefinition } from \"./definitions\";\nexport const exampleTool: ToolDescriptor = {\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 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"]}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const WOO_CART_RESTORE_SNAPSHOT_VERSION: "woo.cart-restore.v1";
|
|
4
|
+
declare const WOO_RESTORE_RESOLVE_VERSION: "woo.restore.resolve.v1";
|
|
5
|
+
declare const WooCartRestoreLineV1Schema: z.ZodObject<{
|
|
6
|
+
productId: z.ZodString;
|
|
7
|
+
variationId: z.ZodOptional<z.ZodString>;
|
|
8
|
+
quantity: z.ZodNumber;
|
|
9
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
10
|
+
}, z.core.$strict>;
|
|
11
|
+
type WooCartRestoreLineV1 = z.infer<typeof WooCartRestoreLineV1Schema>;
|
|
12
|
+
declare const WooCartRestoreUnsupportedReasonV1Schema: z.ZodEnum<{
|
|
13
|
+
ITEMS_UNAVAILABLE: "ITEMS_UNAVAILABLE";
|
|
14
|
+
UNSUPPORTED_PRODUCT_TYPE: "UNSUPPORTED_PRODUCT_TYPE";
|
|
15
|
+
CUSTOM_CART_ITEM_DATA: "CUSTOM_CART_ITEM_DATA";
|
|
16
|
+
INVALID_VARIATION: "INVALID_VARIATION";
|
|
17
|
+
COUPONS_UNAVAILABLE: "COUPONS_UNAVAILABLE";
|
|
18
|
+
LIMIT_EXCEEDED: "LIMIT_EXCEEDED";
|
|
19
|
+
}>;
|
|
20
|
+
type WooCartRestoreUnsupportedReasonV1 = z.infer<typeof WooCartRestoreUnsupportedReasonV1Schema>;
|
|
21
|
+
declare const WooCartRestoreSupportedSnapshotV1Schema: z.ZodObject<{
|
|
22
|
+
schemaVersion: z.ZodLiteral<"woo.cart-restore.v1">;
|
|
23
|
+
kind: z.ZodLiteral<"supported">;
|
|
24
|
+
appliedCouponCodes: z.ZodArray<z.ZodString>;
|
|
25
|
+
lines: z.ZodArray<z.ZodObject<{
|
|
26
|
+
productId: z.ZodString;
|
|
27
|
+
variationId: z.ZodOptional<z.ZodString>;
|
|
28
|
+
quantity: z.ZodNumber;
|
|
29
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
30
|
+
}, z.core.$strict>>;
|
|
31
|
+
}, z.core.$strict>;
|
|
32
|
+
type WooCartRestoreSupportedSnapshotV1 = z.infer<typeof WooCartRestoreSupportedSnapshotV1Schema>;
|
|
33
|
+
declare const WooCartRestoreUnsupportedSnapshotV1Schema: z.ZodObject<{
|
|
34
|
+
schemaVersion: z.ZodLiteral<"woo.cart-restore.v1">;
|
|
35
|
+
kind: z.ZodLiteral<"unsupported">;
|
|
36
|
+
reason: z.ZodEnum<{
|
|
37
|
+
ITEMS_UNAVAILABLE: "ITEMS_UNAVAILABLE";
|
|
38
|
+
UNSUPPORTED_PRODUCT_TYPE: "UNSUPPORTED_PRODUCT_TYPE";
|
|
39
|
+
CUSTOM_CART_ITEM_DATA: "CUSTOM_CART_ITEM_DATA";
|
|
40
|
+
INVALID_VARIATION: "INVALID_VARIATION";
|
|
41
|
+
COUPONS_UNAVAILABLE: "COUPONS_UNAVAILABLE";
|
|
42
|
+
LIMIT_EXCEEDED: "LIMIT_EXCEEDED";
|
|
43
|
+
}>;
|
|
44
|
+
appliedCouponCodes: z.ZodArray<z.ZodString>;
|
|
45
|
+
}, z.core.$strict>;
|
|
46
|
+
type WooCartRestoreUnsupportedSnapshotV1 = z.infer<typeof WooCartRestoreUnsupportedSnapshotV1Schema>;
|
|
47
|
+
declare const WooCartRestoreSnapshotV1Schema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
48
|
+
schemaVersion: z.ZodLiteral<"woo.cart-restore.v1">;
|
|
49
|
+
kind: z.ZodLiteral<"supported">;
|
|
50
|
+
appliedCouponCodes: z.ZodArray<z.ZodString>;
|
|
51
|
+
lines: z.ZodArray<z.ZodObject<{
|
|
52
|
+
productId: z.ZodString;
|
|
53
|
+
variationId: z.ZodOptional<z.ZodString>;
|
|
54
|
+
quantity: z.ZodNumber;
|
|
55
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
56
|
+
}, z.core.$strict>>;
|
|
57
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
58
|
+
schemaVersion: z.ZodLiteral<"woo.cart-restore.v1">;
|
|
59
|
+
kind: z.ZodLiteral<"unsupported">;
|
|
60
|
+
reason: z.ZodEnum<{
|
|
61
|
+
ITEMS_UNAVAILABLE: "ITEMS_UNAVAILABLE";
|
|
62
|
+
UNSUPPORTED_PRODUCT_TYPE: "UNSUPPORTED_PRODUCT_TYPE";
|
|
63
|
+
CUSTOM_CART_ITEM_DATA: "CUSTOM_CART_ITEM_DATA";
|
|
64
|
+
INVALID_VARIATION: "INVALID_VARIATION";
|
|
65
|
+
COUPONS_UNAVAILABLE: "COUPONS_UNAVAILABLE";
|
|
66
|
+
LIMIT_EXCEEDED: "LIMIT_EXCEEDED";
|
|
67
|
+
}>;
|
|
68
|
+
appliedCouponCodes: z.ZodArray<z.ZodString>;
|
|
69
|
+
}, z.core.$strict>], "kind">;
|
|
70
|
+
type WooCartRestoreSnapshotV1 = z.infer<typeof WooCartRestoreSnapshotV1Schema>;
|
|
71
|
+
declare const WooCheckoutRestoreExtensionV1Schema: z.ZodObject<{
|
|
72
|
+
restoration: z.ZodOptional<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
73
|
+
schemaVersion: z.ZodLiteral<"woo.cart-restore.v1">;
|
|
74
|
+
kind: z.ZodLiteral<"supported">;
|
|
75
|
+
appliedCouponCodes: z.ZodArray<z.ZodString>;
|
|
76
|
+
lines: z.ZodArray<z.ZodObject<{
|
|
77
|
+
productId: z.ZodString;
|
|
78
|
+
variationId: z.ZodOptional<z.ZodString>;
|
|
79
|
+
quantity: z.ZodNumber;
|
|
80
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
81
|
+
}, z.core.$strict>>;
|
|
82
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
83
|
+
schemaVersion: z.ZodLiteral<"woo.cart-restore.v1">;
|
|
84
|
+
kind: z.ZodLiteral<"unsupported">;
|
|
85
|
+
reason: z.ZodEnum<{
|
|
86
|
+
ITEMS_UNAVAILABLE: "ITEMS_UNAVAILABLE";
|
|
87
|
+
UNSUPPORTED_PRODUCT_TYPE: "UNSUPPORTED_PRODUCT_TYPE";
|
|
88
|
+
CUSTOM_CART_ITEM_DATA: "CUSTOM_CART_ITEM_DATA";
|
|
89
|
+
INVALID_VARIATION: "INVALID_VARIATION";
|
|
90
|
+
COUPONS_UNAVAILABLE: "COUPONS_UNAVAILABLE";
|
|
91
|
+
LIMIT_EXCEEDED: "LIMIT_EXCEEDED";
|
|
92
|
+
}>;
|
|
93
|
+
appliedCouponCodes: z.ZodArray<z.ZodString>;
|
|
94
|
+
}, z.core.$strict>], "kind">>;
|
|
95
|
+
}, z.core.$strict>;
|
|
96
|
+
type WooCheckoutRestoreExtensionV1 = z.infer<typeof WooCheckoutRestoreExtensionV1Schema>;
|
|
97
|
+
declare const WooRestoreResolveRequestV1Schema: z.ZodObject<{
|
|
98
|
+
schemaVersion: z.ZodLiteral<"woo.restore.resolve.v1">;
|
|
99
|
+
recoveryId: z.ZodString;
|
|
100
|
+
token: z.ZodString;
|
|
101
|
+
}, z.core.$strict>;
|
|
102
|
+
type WooRestoreResolveRequestV1 = z.infer<typeof WooRestoreResolveRequestV1Schema>;
|
|
103
|
+
declare const WooRestoreOutreachOfferV1Schema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
104
|
+
kind: z.ZodLiteral<"NONE">;
|
|
105
|
+
reason: z.ZodEnum<{
|
|
106
|
+
NO_CONFIRMED_OFFER: "NO_CONFIRMED_OFFER";
|
|
107
|
+
UNVERIFIABLE: "UNVERIFIABLE";
|
|
108
|
+
}>;
|
|
109
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
110
|
+
kind: z.ZodLiteral<"CHECKOUT_CODE">;
|
|
111
|
+
code: z.ZodString;
|
|
112
|
+
providerDiscountId: z.ZodString;
|
|
113
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
114
|
+
kind: z.ZodLiteral<"CHECKOUT_AUTOMATIC">;
|
|
115
|
+
providerDiscountId: z.ZodString;
|
|
116
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
117
|
+
kind: z.ZodLiteral<"ALTERNATIVE_PRODUCT">;
|
|
118
|
+
}, z.core.$strict>], "kind">;
|
|
119
|
+
type WooRestoreOutreachOfferV1 = z.infer<typeof WooRestoreOutreachOfferV1Schema>;
|
|
120
|
+
declare const WooRestoreResolveResponseV1Schema: z.ZodObject<{
|
|
121
|
+
schemaVersion: z.ZodLiteral<"woo.restore.resolve.v1">;
|
|
122
|
+
status: z.ZodLiteral<"eligible">;
|
|
123
|
+
recoveryId: z.ZodString;
|
|
124
|
+
checkoutKey: z.ZodString;
|
|
125
|
+
snapshot: z.ZodObject<{
|
|
126
|
+
schemaVersion: z.ZodLiteral<"woo.cart-restore.v1">;
|
|
127
|
+
kind: z.ZodLiteral<"supported">;
|
|
128
|
+
appliedCouponCodes: z.ZodArray<z.ZodString>;
|
|
129
|
+
lines: z.ZodArray<z.ZodObject<{
|
|
130
|
+
productId: z.ZodString;
|
|
131
|
+
variationId: z.ZodOptional<z.ZodString>;
|
|
132
|
+
quantity: z.ZodNumber;
|
|
133
|
+
attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
134
|
+
}, z.core.$strict>>;
|
|
135
|
+
}, z.core.$strict>;
|
|
136
|
+
outreachOffer: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
137
|
+
kind: z.ZodLiteral<"NONE">;
|
|
138
|
+
reason: z.ZodEnum<{
|
|
139
|
+
NO_CONFIRMED_OFFER: "NO_CONFIRMED_OFFER";
|
|
140
|
+
UNVERIFIABLE: "UNVERIFIABLE";
|
|
141
|
+
}>;
|
|
142
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
143
|
+
kind: z.ZodLiteral<"CHECKOUT_CODE">;
|
|
144
|
+
code: z.ZodString;
|
|
145
|
+
providerDiscountId: z.ZodString;
|
|
146
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
147
|
+
kind: z.ZodLiteral<"CHECKOUT_AUTOMATIC">;
|
|
148
|
+
providerDiscountId: z.ZodString;
|
|
149
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
150
|
+
kind: z.ZodLiteral<"ALTERNATIVE_PRODUCT">;
|
|
151
|
+
}, z.core.$strict>], "kind">;
|
|
152
|
+
}, z.core.$strict>;
|
|
153
|
+
type WooRestoreResolveResponseV1 = z.infer<typeof WooRestoreResolveResponseV1Schema>;
|
|
154
|
+
|
|
155
|
+
export { WOO_CART_RESTORE_SNAPSHOT_VERSION, WOO_RESTORE_RESOLVE_VERSION, type WooCartRestoreLineV1, WooCartRestoreLineV1Schema, type WooCartRestoreSnapshotV1, WooCartRestoreSnapshotV1Schema, type WooCartRestoreSupportedSnapshotV1, WooCartRestoreSupportedSnapshotV1Schema, type WooCartRestoreUnsupportedReasonV1, WooCartRestoreUnsupportedReasonV1Schema, type WooCartRestoreUnsupportedSnapshotV1, WooCartRestoreUnsupportedSnapshotV1Schema, type WooCheckoutRestoreExtensionV1, WooCheckoutRestoreExtensionV1Schema, type WooRestoreOutreachOfferV1, WooRestoreOutreachOfferV1Schema, type WooRestoreResolveRequestV1, WooRestoreResolveRequestV1Schema, type WooRestoreResolveResponseV1, WooRestoreResolveResponseV1Schema };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// src/woocommerce/contracts.ts
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
var WOO_CART_RESTORE_SNAPSHOT_VERSION = "woo.cart-restore.v1";
|
|
4
|
+
var WOO_RESTORE_RESOLVE_VERSION = "woo.restore.resolve.v1";
|
|
5
|
+
var WooPositiveDecimalIdSchema = z.string().min(1).max(20).regex(/^[1-9][0-9]*$/);
|
|
6
|
+
var WooOpaqueRecoveryIdSchema = z.string().min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._:~-]{0,127}$/);
|
|
7
|
+
var WooNoControlTextSchema = (max) => z.string().min(1).max(max).regex(/^[^\p{Cc}]+$/u);
|
|
8
|
+
var WooRestoreAttributesV1Schema = z.record(
|
|
9
|
+
WooNoControlTextSchema(80),
|
|
10
|
+
WooNoControlTextSchema(200)
|
|
11
|
+
).superRefine((value, ctx) => {
|
|
12
|
+
if (Object.keys(value).length > 10) {
|
|
13
|
+
ctx.addIssue({ code: "custom", message: "Too many attributes" });
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
var WooAppliedCouponCodesV1Schema = z.array(WooNoControlTextSchema(128)).max(10);
|
|
17
|
+
var WooCartRestoreLineV1Schema = z.strictObject({
|
|
18
|
+
productId: WooPositiveDecimalIdSchema,
|
|
19
|
+
variationId: WooPositiveDecimalIdSchema.optional(),
|
|
20
|
+
quantity: z.number().int().min(1).max(1e5),
|
|
21
|
+
attributes: WooRestoreAttributesV1Schema.optional()
|
|
22
|
+
});
|
|
23
|
+
var WooCartRestoreUnsupportedReasonV1Schema = z.enum([
|
|
24
|
+
"ITEMS_UNAVAILABLE",
|
|
25
|
+
"UNSUPPORTED_PRODUCT_TYPE",
|
|
26
|
+
"CUSTOM_CART_ITEM_DATA",
|
|
27
|
+
"INVALID_VARIATION",
|
|
28
|
+
"COUPONS_UNAVAILABLE",
|
|
29
|
+
"LIMIT_EXCEEDED"
|
|
30
|
+
]);
|
|
31
|
+
var WooCartRestoreSupportedSnapshotV1Schema = z.strictObject({
|
|
32
|
+
schemaVersion: z.literal(WOO_CART_RESTORE_SNAPSHOT_VERSION),
|
|
33
|
+
kind: z.literal("supported"),
|
|
34
|
+
appliedCouponCodes: WooAppliedCouponCodesV1Schema,
|
|
35
|
+
lines: z.array(WooCartRestoreLineV1Schema).min(1).max(50)
|
|
36
|
+
});
|
|
37
|
+
var WooCartRestoreUnsupportedSnapshotV1Schema = z.strictObject({
|
|
38
|
+
schemaVersion: z.literal(WOO_CART_RESTORE_SNAPSHOT_VERSION),
|
|
39
|
+
kind: z.literal("unsupported"),
|
|
40
|
+
reason: WooCartRestoreUnsupportedReasonV1Schema,
|
|
41
|
+
appliedCouponCodes: WooAppliedCouponCodesV1Schema
|
|
42
|
+
});
|
|
43
|
+
var WooCartRestoreSnapshotV1Schema = z.discriminatedUnion("kind", [
|
|
44
|
+
WooCartRestoreSupportedSnapshotV1Schema,
|
|
45
|
+
WooCartRestoreUnsupportedSnapshotV1Schema
|
|
46
|
+
]);
|
|
47
|
+
var WooCheckoutRestoreExtensionV1Schema = z.strictObject({
|
|
48
|
+
restoration: WooCartRestoreSnapshotV1Schema.optional()
|
|
49
|
+
});
|
|
50
|
+
var WooRestoreResolveRequestV1Schema = z.strictObject({
|
|
51
|
+
schemaVersion: z.literal(WOO_RESTORE_RESOLVE_VERSION),
|
|
52
|
+
recoveryId: WooOpaqueRecoveryIdSchema,
|
|
53
|
+
token: z.string().length(43).regex(/^[A-Za-z0-9_-]{43}$/)
|
|
54
|
+
});
|
|
55
|
+
var WooRestoreOutreachOfferV1Schema = z.discriminatedUnion("kind", [
|
|
56
|
+
z.strictObject({
|
|
57
|
+
kind: z.literal("NONE"),
|
|
58
|
+
reason: z.enum(["NO_CONFIRMED_OFFER", "UNVERIFIABLE"])
|
|
59
|
+
}),
|
|
60
|
+
z.strictObject({
|
|
61
|
+
kind: z.literal("CHECKOUT_CODE"),
|
|
62
|
+
code: WooNoControlTextSchema(128),
|
|
63
|
+
providerDiscountId: WooNoControlTextSchema(191)
|
|
64
|
+
}),
|
|
65
|
+
z.strictObject({
|
|
66
|
+
kind: z.literal("CHECKOUT_AUTOMATIC"),
|
|
67
|
+
providerDiscountId: WooNoControlTextSchema(191)
|
|
68
|
+
}),
|
|
69
|
+
z.strictObject({ kind: z.literal("ALTERNATIVE_PRODUCT") })
|
|
70
|
+
]);
|
|
71
|
+
var WooRestoreResolveResponseV1Schema = z.strictObject({
|
|
72
|
+
schemaVersion: z.literal(WOO_RESTORE_RESOLVE_VERSION),
|
|
73
|
+
status: z.literal("eligible"),
|
|
74
|
+
recoveryId: WooOpaqueRecoveryIdSchema,
|
|
75
|
+
checkoutKey: WooOpaqueRecoveryIdSchema,
|
|
76
|
+
snapshot: WooCartRestoreSupportedSnapshotV1Schema,
|
|
77
|
+
outreachOffer: WooRestoreOutreachOfferV1Schema
|
|
78
|
+
});
|
|
79
|
+
export {
|
|
80
|
+
WOO_CART_RESTORE_SNAPSHOT_VERSION,
|
|
81
|
+
WOO_RESTORE_RESOLVE_VERSION,
|
|
82
|
+
WooCartRestoreLineV1Schema,
|
|
83
|
+
WooCartRestoreSnapshotV1Schema,
|
|
84
|
+
WooCartRestoreSupportedSnapshotV1Schema,
|
|
85
|
+
WooCartRestoreUnsupportedReasonV1Schema,
|
|
86
|
+
WooCartRestoreUnsupportedSnapshotV1Schema,
|
|
87
|
+
WooCheckoutRestoreExtensionV1Schema,
|
|
88
|
+
WooRestoreOutreachOfferV1Schema,
|
|
89
|
+
WooRestoreResolveRequestV1Schema,
|
|
90
|
+
WooRestoreResolveResponseV1Schema
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/woocommerce/contracts.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const WOO_CART_RESTORE_SNAPSHOT_VERSION = \"woo.cart-restore.v1\" as const;\nexport const WOO_RESTORE_RESOLVE_VERSION = \"woo.restore.resolve.v1\" as const;\n\n// Wire IDs remain strings because WordPress/PHP may emit IDs beyond JavaScript's\n// safe-integer range. WooCommerce validates their meaning.\nconst WooPositiveDecimalIdSchema = z.string()\n .min(1).max(20).regex(/^[1-9][0-9]*$/);\nconst WooOpaqueRecoveryIdSchema = z.string()\n .min(1).max(128).regex(/^[A-Za-z0-9][A-Za-z0-9._:~-]{0,127}$/);\nconst WooNoControlTextSchema = (max: number) => z.string()\n .min(1).max(max).regex(/^[^\\p{Cc}]+$/u);\n\n// This refinement enforces only the structural ten-property limit.\nconst WooRestoreAttributesV1Schema = z.record(\n WooNoControlTextSchema(80), WooNoControlTextSchema(200),\n).superRefine((value, ctx) => {\n if (Object.keys(value).length > 10) {\n ctx.addIssue({ code: \"custom\", message: \"Too many attributes\" });\n }\n});\n\nconst WooAppliedCouponCodesV1Schema = z.array(WooNoControlTextSchema(128)).max(10);\n\nexport const WooCartRestoreLineV1Schema = z.strictObject({\n productId: WooPositiveDecimalIdSchema,\n variationId: WooPositiveDecimalIdSchema.optional(),\n quantity: z.number().int().min(1).max(100_000),\n attributes: WooRestoreAttributesV1Schema.optional(),\n});\nexport type WooCartRestoreLineV1 = z.infer<typeof WooCartRestoreLineV1Schema>;\n\nexport const WooCartRestoreUnsupportedReasonV1Schema = z.enum([\n \"ITEMS_UNAVAILABLE\",\n \"UNSUPPORTED_PRODUCT_TYPE\",\n \"CUSTOM_CART_ITEM_DATA\",\n \"INVALID_VARIATION\",\n \"COUPONS_UNAVAILABLE\",\n \"LIMIT_EXCEEDED\",\n]);\nexport type WooCartRestoreUnsupportedReasonV1 =\n z.infer<typeof WooCartRestoreUnsupportedReasonV1Schema>;\n\nexport const WooCartRestoreSupportedSnapshotV1Schema = z.strictObject({\n schemaVersion: z.literal(WOO_CART_RESTORE_SNAPSHOT_VERSION),\n kind: z.literal(\"supported\"),\n appliedCouponCodes: WooAppliedCouponCodesV1Schema,\n lines: z.array(WooCartRestoreLineV1Schema).min(1).max(50),\n});\nexport type WooCartRestoreSupportedSnapshotV1 =\n z.infer<typeof WooCartRestoreSupportedSnapshotV1Schema>;\n\nexport const WooCartRestoreUnsupportedSnapshotV1Schema = z.strictObject({\n schemaVersion: z.literal(WOO_CART_RESTORE_SNAPSHOT_VERSION),\n kind: z.literal(\"unsupported\"),\n reason: WooCartRestoreUnsupportedReasonV1Schema,\n appliedCouponCodes: WooAppliedCouponCodesV1Schema,\n});\nexport type WooCartRestoreUnsupportedSnapshotV1 =\n z.infer<typeof WooCartRestoreUnsupportedSnapshotV1Schema>;\n\nexport const WooCartRestoreSnapshotV1Schema = z.discriminatedUnion(\"kind\", [\n WooCartRestoreSupportedSnapshotV1Schema,\n WooCartRestoreUnsupportedSnapshotV1Schema,\n]);\nexport type WooCartRestoreSnapshotV1 = z.infer<typeof WooCartRestoreSnapshotV1Schema>;\n\n// Extension for API-001's canonical v1 checkout object; not a checkout event\n// identity, contact or phone-proof schema.\nexport const WooCheckoutRestoreExtensionV1Schema = z.strictObject({\n restoration: WooCartRestoreSnapshotV1Schema.optional(),\n});\nexport type WooCheckoutRestoreExtensionV1 =\n z.infer<typeof WooCheckoutRestoreExtensionV1Schema>;\n\nexport const WooRestoreResolveRequestV1Schema = z.strictObject({\n schemaVersion: z.literal(WOO_RESTORE_RESOLVE_VERSION),\n recoveryId: WooOpaqueRecoveryIdSchema,\n token: z.string().length(43).regex(/^[A-Za-z0-9_-]{43}$/),\n});\nexport type WooRestoreResolveRequestV1 = z.infer<typeof WooRestoreResolveRequestV1Schema>;\n\n// This describes a previously confirmed offer. Eligibility and provenance are\n// enforced by API-003, not by this wire-shape schema.\nexport const WooRestoreOutreachOfferV1Schema = z.discriminatedUnion(\"kind\", [\n z.strictObject({\n kind: z.literal(\"NONE\"),\n reason: z.enum([\"NO_CONFIRMED_OFFER\", \"UNVERIFIABLE\"]),\n }),\n z.strictObject({\n kind: z.literal(\"CHECKOUT_CODE\"),\n code: WooNoControlTextSchema(128),\n providerDiscountId: WooNoControlTextSchema(191),\n }),\n z.strictObject({\n kind: z.literal(\"CHECKOUT_AUTOMATIC\"),\n providerDiscountId: WooNoControlTextSchema(191),\n }),\n z.strictObject({ kind: z.literal(\"ALTERNATIVE_PRODUCT\") }),\n]);\nexport type WooRestoreOutreachOfferV1 = z.infer<typeof WooRestoreOutreachOfferV1Schema>;\n\nexport const WooRestoreResolveResponseV1Schema = z.strictObject({\n schemaVersion: z.literal(WOO_RESTORE_RESOLVE_VERSION),\n status: z.literal(\"eligible\"),\n recoveryId: WooOpaqueRecoveryIdSchema,\n checkoutKey: WooOpaqueRecoveryIdSchema,\n snapshot: WooCartRestoreSupportedSnapshotV1Schema,\n outreachOffer: WooRestoreOutreachOfferV1Schema,\n});\nexport type WooRestoreResolveResponseV1 =\n z.infer<typeof WooRestoreResolveResponseV1Schema>;\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modainteract/moda-interact-shared",
|
|
3
|
-
"version": "2.7.
|
|
3
|
+
"version": "2.7.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -54,6 +54,11 @@
|
|
|
54
54
|
"import": "./dist/identity/index.js"
|
|
55
55
|
},
|
|
56
56
|
"./identity/fixtures": "./fixtures/identity-v1.json",
|
|
57
|
+
"./woocommerce": {
|
|
58
|
+
"types": "./dist/woocommerce/index.d.ts",
|
|
59
|
+
"import": "./dist/woocommerce/index.js"
|
|
60
|
+
},
|
|
61
|
+
"./woocommerce/fixtures": "./src/woocommerce/__fixtures__/woo-restore-v1.json",
|
|
57
62
|
"./shopify": {
|
|
58
63
|
"types": "./dist/shopify/index.d.ts",
|
|
59
64
|
"import": "./dist/shopify/index.js"
|
|
@@ -126,7 +131,8 @@
|
|
|
126
131
|
"files": [
|
|
127
132
|
"dist",
|
|
128
133
|
"fixtures/identity-v1.json",
|
|
129
|
-
"fixtures/meta-template-status-v2.json"
|
|
134
|
+
"fixtures/meta-template-status-v2.json",
|
|
135
|
+
"src/woocommerce/__fixtures__/woo-restore-v1.json"
|
|
130
136
|
],
|
|
131
137
|
"scripts": {
|
|
132
138
|
"build": "tsup",
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"supportedSnapshot": {
|
|
3
|
+
"schemaVersion": "woo.cart-restore.v1",
|
|
4
|
+
"kind": "supported",
|
|
5
|
+
"appliedCouponCodes": ["save10", "freeship"],
|
|
6
|
+
"lines": [
|
|
7
|
+
{"productId": "101", "quantity": 2},
|
|
8
|
+
{
|
|
9
|
+
"productId": "202",
|
|
10
|
+
"variationId": "207",
|
|
11
|
+
"quantity": 1,
|
|
12
|
+
"attributes": {
|
|
13
|
+
"attribute_pa_color": "navy",
|
|
14
|
+
"attribute_pa_size": "m"
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
"unsupportedSnapshot": {
|
|
20
|
+
"schemaVersion": "woo.cart-restore.v1",
|
|
21
|
+
"kind": "unsupported",
|
|
22
|
+
"reason": "CUSTOM_CART_ITEM_DATA",
|
|
23
|
+
"appliedCouponCodes": ["save10"]
|
|
24
|
+
},
|
|
25
|
+
"resolveRequest": {
|
|
26
|
+
"schemaVersion": "woo.restore.resolve.v1",
|
|
27
|
+
"recoveryId": "recovery_456",
|
|
28
|
+
"token": "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
|
29
|
+
},
|
|
30
|
+
"eligibleResolveResponse": {
|
|
31
|
+
"schemaVersion": "woo.restore.resolve.v1",
|
|
32
|
+
"status": "eligible",
|
|
33
|
+
"recoveryId": "recovery_456",
|
|
34
|
+
"checkoutKey": "woo-example-checkout",
|
|
35
|
+
"snapshot": {
|
|
36
|
+
"schemaVersion": "woo.cart-restore.v1",
|
|
37
|
+
"kind": "supported",
|
|
38
|
+
"appliedCouponCodes": ["save10", "freeship"],
|
|
39
|
+
"lines": [
|
|
40
|
+
{"productId": "101", "quantity": 2},
|
|
41
|
+
{
|
|
42
|
+
"productId": "202",
|
|
43
|
+
"variationId": "207",
|
|
44
|
+
"quantity": 1,
|
|
45
|
+
"attributes": {"attribute_pa_color": "navy", "attribute_pa_size": "m"}
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
},
|
|
49
|
+
"outreachOffer": {
|
|
50
|
+
"kind": "CHECKOUT_CODE",
|
|
51
|
+
"code": "EXTRA15",
|
|
52
|
+
"providerDiscountId": "woo-discount-915"
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
"outreachOfferExamples": {
|
|
56
|
+
"none": {"kind": "NONE", "reason": "NO_CONFIRMED_OFFER"},
|
|
57
|
+
"unverifiable": {"kind": "NONE", "reason": "UNVERIFIABLE"},
|
|
58
|
+
"checkoutCode": {
|
|
59
|
+
"kind": "CHECKOUT_CODE",
|
|
60
|
+
"code": "EXTRA15",
|
|
61
|
+
"providerDiscountId": "woo-discount-915"
|
|
62
|
+
},
|
|
63
|
+
"checkoutAutomatic": {
|
|
64
|
+
"kind": "CHECKOUT_AUTOMATIC",
|
|
65
|
+
"providerDiscountId": "woo-discount-916"
|
|
66
|
+
},
|
|
67
|
+
"alternativeProduct": {"kind": "ALTERNATIVE_PRODUCT"}
|
|
68
|
+
}
|
|
69
|
+
}
|