@adatechnology/meta-whatsapp-contracts 0.2.0-rc.3 → 0.2.0-rc.5
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/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -7
- package/dist/index.d.ts +7 -7
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -175,7 +175,7 @@ var flowNodeDataSchema = import_zod2.z.object({
|
|
|
175
175
|
import_zod2.z.string()
|
|
176
176
|
])).optional(),
|
|
177
177
|
actionKind: import_zod2.z.string().optional(),
|
|
178
|
-
|
|
178
|
+
actionParams: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()).optional(),
|
|
179
179
|
directMessage: import_zod2.z.string().optional(),
|
|
180
180
|
fallbackMessage: import_zod2.z.string().optional(),
|
|
181
181
|
conditionContextKey: import_zod2.z.string().optional(),
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/webhook.types.ts","../src/flow.types.ts","../src/errors.ts"],"sourcesContent":["export {\n whatsAppMediaSchema,\n whatsAppInteractiveSchema,\n whatsAppOrderSchema,\n whatsAppMessageSchema,\n whatsAppMessageEchoSchema,\n whatsAppMessageStatusSchema,\n whatsAppStatusSchema,\n whatsAppWebhookPayloadSchema,\n} from './webhook.types'\nexport type {\n WhatsAppMedia,\n WhatsAppInteractive,\n WhatsAppOrder,\n WhatsAppMessage,\n WhatsAppMessageEcho,\n WhatsAppMessageStatusValue,\n WhatsAppStatus,\n WhatsAppWebhookPayload,\n} from './webhook.types'\n\nexport type {\n SessionState,\n SessionMode,\n MessageDirection,\n MessageSender,\n MessageStatus,\n ConversationSession,\n ConversationMessage,\n ConversationSummary,\n ListConversationsParams,\n ListMessagesParams,\n} from './conversation.types'\n\nexport {\n CROSS_FLOW_PREFIX,\n isCrossFlowTarget,\n crossFlowKey,\n flowNodeNextSchema,\n flowNodeDataSchema,\n flowGraphNodesSchema,\n} from './flow.types'\nexport type {\n FlowNodeType,\n FlowQuestionType,\n FlowActionKind,\n FlowConditionOperator,\n FlowNodeNext,\n FlowNodeData,\n FlowGraphData,\n FlowGraphSummary,\n LiveFlowPosition,\n} from './flow.types'\n\nexport type {\n WhatsAppSettings,\n TemplateVariablesMap,\n TemplateConfig,\n WhatsAppTemplateSummary,\n CreateTemplateResult,\n} from './settings.types'\n\nexport type { MetaWhatsAppHooks, MessageHookOutcome } from './events'\n\nexport type {\n ChannelAdapterInterface,\n SubjectResolverInterface,\n CatalogProduct,\n CatalogPort,\n ObjectStorageInterface,\n RealtimeNotifierInterface,\n FlowActionHandler,\n FlowActionResult,\n FlowActionRegistry,\n} from './providers'\n\nexport {\n MetaWhatsAppError,\n META_WHATSAPP_ERROR_CODES,\n WindowExpiredError,\n InvalidWebhookSignatureError,\n DuplicateWebhookDeliveryError,\n ConfigMissingError,\n TemplateNotConfiguredError,\n SessionNotFoundError,\n} from './errors'\n","import { z } from 'zod'\n\n// Extraído de financiamento-imobiliario-bot/apps/api/src/modules/webhook/application/use-cases/\n// ReceiveWhatsAppWebhook.use-case.ts:39-113 — shape real do payload da Cloud API da Meta.\n\nexport const whatsAppMediaSchema = z.object({\n id: z.string(),\n mime_type: z.string(),\n sha256: z.string().optional(),\n caption: z.string().optional(),\n filename: z.string().optional(),\n})\nexport type WhatsAppMedia = z.infer<typeof whatsAppMediaSchema>\n\nexport const whatsAppInteractiveSchema = z.object({\n type: z.string(),\n button_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n list_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n})\nexport type WhatsAppInteractive = z.infer<typeof whatsAppInteractiveSchema>\n\nexport const whatsAppOrderSchema = z.object({\n catalog_id: z.string(),\n text: z.string().optional(),\n product_items: z.array(\n z.object({\n product_retailer_id: z.string(),\n quantity: z.number(),\n item_price: z.number(),\n currency: z.string(),\n }),\n ),\n})\nexport type WhatsAppOrder = z.infer<typeof whatsAppOrderSchema>\n\nexport const whatsAppMessageSchema = z.object({\n id: z.string(),\n from: z.string(),\n type: z.string(),\n text: z.object({ body: z.string() }).optional(),\n image: whatsAppMediaSchema.optional(),\n audio: whatsAppMediaSchema.optional(),\n video: whatsAppMediaSchema.optional(),\n document: whatsAppMediaSchema.optional(),\n sticker: whatsAppMediaSchema.optional(),\n interactive: whatsAppInteractiveSchema.optional(),\n // Pedido enviado pelo carrinho do catálogo (WhatsApp Commerce)\n order: whatsAppOrderSchema.optional(),\n // Presente quando o cliente abre um item do catálogo e manda mensagem pela página do produto\n context: z\n .object({\n from: z.string().optional(),\n id: z.string().optional(),\n referred_product: z.object({ catalog_id: z.string(), product_retailer_id: z.string() }).optional(),\n })\n .optional(),\n timestamp: z.string(),\n})\nexport type WhatsAppMessage = z.infer<typeof whatsAppMessageSchema>\n\nexport const whatsAppMessageEchoSchema = z.object({\n id: z.string(),\n from: z.string(),\n timestamp: z.string(),\n type: z.string(),\n})\nexport type WhatsAppMessageEcho = z.infer<typeof whatsAppMessageEchoSchema>\n\nexport const whatsAppMessageStatusSchema = z.enum(['sent', 'delivered', 'read', 'failed'])\nexport type WhatsAppMessageStatusValue = z.infer<typeof whatsAppMessageStatusSchema>\n\nexport const whatsAppStatusSchema = z.object({\n id: z.string(),\n status: whatsAppMessageStatusSchema,\n timestamp: z.string(),\n recipient_id: z.string().optional(),\n})\nexport type WhatsAppStatus = z.infer<typeof whatsAppStatusSchema>\n\nexport const whatsAppWebhookPayloadSchema = z.object({\n object: z.string(),\n entry: z.array(\n z.object({\n id: z.string(),\n changes: z.array(\n z.object({\n value: z.object({\n messaging_product: z.string(),\n messages: z.array(whatsAppMessageSchema).optional(),\n message_echoes: z.array(whatsAppMessageEchoSchema).optional(),\n statuses: z.array(whatsAppStatusSchema).optional(),\n metadata: z.object({ display_phone_number: z.string(), phone_number_id: z.string() }).optional(),\n }),\n }),\n ),\n }),\n ),\n})\nexport type WhatsAppWebhookPayload = z.infer<typeof whatsAppWebhookPayloadSchema>\n","// Mesmo shape de dados do editor visual (@adatechnology/conversations-ui/flows) — o backend\n// interpreta/persiste o grafo, o frontend edita; os dois lados precisam concordar no formato.\n// `FlowActionKind` é string aberta (não union fechada): o host registra os próprios actions\n// (ex.: 'trigger_simulation' no bot) via registerFlowAction() no módulo (T4.3) — o pacote nunca\n// assume nenhum caso de negócio específico.\nimport { z } from 'zod'\n\nexport type FlowNodeType = 'question' | 'entrada_choice' | 'action' | 'menu' | 'condition'\nexport type FlowQuestionType = 'text' | 'money' | 'date' | 'int' | 'cpf' | 'choice'\nexport type FlowActionKind = string\nexport type FlowConditionOperator = '>' | '>=' | '<' | '<=' | '==' | '!=' | 'contains'\nexport type FlowNodeNext = string | { byAnswer: Record<string, string>; default: string }\n\n// Destinos \"flow:<key>\" são saltos para outro fluxo — mesma convenção usada pelo editor visual\n// (conversations-ui/flows/flowGraph.ts); backend e frontend precisam concordar no formato.\nexport const CROSS_FLOW_PREFIX = 'flow:'\nexport const isCrossFlowTarget = (target: string): boolean => target.startsWith(CROSS_FLOW_PREFIX)\nexport const crossFlowKey = (target: string): string => target.slice(CROSS_FLOW_PREFIX.length)\n\nexport type FlowNodeData = {\n id: string\n type: FlowNodeType\n contextKey?: string\n questionType?: FlowQuestionType\n question?: string\n options?: [string, string][]\n actionKind?: FlowActionKind\n simulationTemplate?: Record<string, string>\n directMessage?: string\n fallbackMessage?: string\n conditionContextKey?: string\n conditionOperator?: FlowConditionOperator\n conditionValue?: string\n position?: { x: number; y: number }\n next?: FlowNodeNext\n}\n\nexport interface FlowGraphData {\n key: string\n label: string\n startNodeId: string\n version: number\n nodes: Record<string, FlowNodeData>\n}\n\nexport interface FlowGraphSummary {\n key: string\n label: string\n nodeCount: number\n showInMenu: boolean\n menuOptionLabel?: string\n updatedAt: string\n}\n\n// Retorno de GetLiveFlowPositions (T4.2) — quantas sessões ativas estão em cada nó agora,\n// usado pelo editor para desenhar o \"liveCount\" nos cards (FlowNodeCardData.liveCount).\nexport interface LiveFlowPosition {\n flowKey: string\n nodeId: string\n count: number\n}\n\n// Validação de runtime do grafo. O `nodes` é um jsonb que entrou pelo editor (dado de origem\n// cliente) e sai do banco como `unknown` — sem parse, um grafo malformado só se manifestaria\n// como comportamento estranho lá dentro do interpretador, longe da causa.\n//\n// Permissivo de propósito em dois pontos: `actionKind` é string aberta (o host registra os\n// seus) e `.passthrough()` deixa passar campos extras — um grafo salvo por uma versão mais nova\n// do editor não pode ficar irrecuperável numa versão mais antiga do módulo.\nexport const flowNodeNextSchema = z.union([\n z.string(),\n z.object({ byAnswer: z.record(z.string(), z.string()), default: z.string() }),\n])\n\nexport const flowNodeDataSchema = z\n .object({\n id: z.string(),\n type: z.enum(['question', 'entrada_choice', 'action', 'menu', 'condition']),\n contextKey: z.string().optional(),\n questionType: z.enum(['text', 'money', 'date', 'int', 'cpf', 'choice']).optional(),\n question: z.string().optional(),\n options: z.array(z.tuple([z.string(), z.string()])).optional(),\n actionKind: z.string().optional(),\n simulationTemplate: z.record(z.string(), z.string()).optional(),\n directMessage: z.string().optional(),\n fallbackMessage: z.string().optional(),\n conditionContextKey: z.string().optional(),\n conditionOperator: z.enum(['>', '>=', '<', '<=', '==', '!=', 'contains']).optional(),\n conditionValue: z.string().optional(),\n position: z.object({ x: z.number(), y: z.number() }).optional(),\n next: flowNodeNextSchema.optional(),\n })\n .passthrough()\n\nexport const flowGraphNodesSchema = z.record(z.string(), flowNodeDataSchema)\n","// Hierarquia de erros do módulo — não depende do framework de erros do host (nenhum DomainError\n// importado); o host mapeia estes para o seu próprio formato de resposta no exception filter.\nexport class MetaWhatsAppError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly code: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'MetaWhatsAppError'\n }\n}\n\nexport const META_WHATSAPP_ERROR_CODES = {\n WINDOW_EXPIRED: 'META_WHATSAPP_WINDOW_EXPIRED',\n INVALID_SIGNATURE: 'META_WHATSAPP_INVALID_SIGNATURE',\n DUPLICATE_DELIVERY: 'META_WHATSAPP_DUPLICATE_DELIVERY',\n CONFIG_MISSING: 'META_WHATSAPP_CONFIG_MISSING',\n TEMPLATE_NOT_CONFIGURED: 'META_WHATSAPP_TEMPLATE_NOT_CONFIGURED',\n SESSION_NOT_FOUND: 'META_WHATSAPP_SESSION_NOT_FOUND',\n} as const\n\nexport class WindowExpiredError extends MetaWhatsAppError {\n constructor(public readonly hoursSinceLastMessage?: number) {\n super(\n 'Janela de 24h expirada — não é possível enviar mensagem para este contato fora de template.',\n 400,\n META_WHATSAPP_ERROR_CODES.WINDOW_EXPIRED,\n { hoursSinceLastMessage },\n )\n }\n}\n\n// Assinatura HMAC do webhook não confere — Meta ou um terceiro tentando forjar uma entrega.\nexport class InvalidWebhookSignatureError extends MetaWhatsAppError {\n constructor() {\n super('Assinatura do webhook inválida.', 401, META_WHATSAPP_ERROR_CODES.INVALID_SIGNATURE)\n }\n}\n\n// Meta reenviou uma entrega dentro da janela de replay (nonce já visto) — não é erro do\n// cliente, é comportamento esperado da Cloud API; o host deve responder 200 e ignorar.\nexport class DuplicateWebhookDeliveryError extends MetaWhatsAppError {\n constructor(nonce: string) {\n super('Entrega de webhook duplicada.', 409, META_WHATSAPP_ERROR_CODES.DUPLICATE_DELIVERY, { nonce })\n }\n}\n\nexport class ConfigMissingError extends MetaWhatsAppError {\n constructor(missingField: string) {\n super(`Configuração do WhatsApp ausente: ${missingField}.`, 503, META_WHATSAPP_ERROR_CODES.CONFIG_MISSING, {\n missingField,\n })\n }\n}\n\nexport class TemplateNotConfiguredError extends MetaWhatsAppError {\n constructor() {\n super(\n 'Nenhum template de WhatsApp configurado para reabertura de janela.',\n 503,\n META_WHATSAPP_ERROR_CODES.TEMPLATE_NOT_CONFIGURED,\n )\n }\n}\n\nexport class SessionNotFoundError extends MetaWhatsAppError {\n constructor(whatsappNumber: string) {\n super(\n `Sessão de conversa não encontrada para ${whatsappNumber}.`,\n 404,\n META_WHATSAPP_ERROR_CODES.SESSION_NOT_FOUND,\n { whatsappNumber },\n )\n }\n}\n"],"mappings":"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","names":["whatsAppMediaSchema","z","object","id","string","mime_type","sha256","optional","caption","filename","whatsAppInteractiveSchema","type","button_reply","title","list_reply","whatsAppOrderSchema","catalog_id","text","product_items","array","product_retailer_id","quantity","number","item_price","currency","whatsAppMessageSchema","from","body","image","audio","video","document","sticker","interactive","order","context","referred_product","timestamp","whatsAppMessageEchoSchema","whatsAppMessageStatusSchema","enum","whatsAppStatusSchema","status","recipient_id","whatsAppWebhookPayloadSchema","entry","changes","value","messaging_product","messages","message_echoes","statuses","metadata","display_phone_number","phone_number_id","import_zod","CROSS_FLOW_PREFIX","isCrossFlowTarget","target","startsWith","crossFlowKey","slice","length","flowNodeNextSchema","z","union","string","object","byAnswer","record","default","flowNodeDataSchema","id","type","enum","contextKey","optional","questionType","question","options","array","tuple","actionKind","simulationTemplate","directMessage","fallbackMessage","conditionContextKey","conditionOperator","conditionValue","position","x","number","y","next","passthrough","flowGraphNodesSchema","MetaWhatsAppError","Error","message","statusCode","code","details","name","META_WHATSAPP_ERROR_CODES","WINDOW_EXPIRED","INVALID_SIGNATURE","DUPLICATE_DELIVERY","CONFIG_MISSING","TEMPLATE_NOT_CONFIGURED","SESSION_NOT_FOUND","WindowExpiredError","hoursSinceLastMessage","InvalidWebhookSignatureError","DuplicateWebhookDeliveryError","nonce","ConfigMissingError","missingField","TemplateNotConfiguredError","SessionNotFoundError","whatsappNumber"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/webhook.types.ts","../src/flow.types.ts","../src/errors.ts"],"sourcesContent":["export {\n whatsAppMediaSchema,\n whatsAppInteractiveSchema,\n whatsAppOrderSchema,\n whatsAppMessageSchema,\n whatsAppMessageEchoSchema,\n whatsAppMessageStatusSchema,\n whatsAppStatusSchema,\n whatsAppWebhookPayloadSchema,\n} from './webhook.types'\nexport type {\n WhatsAppMedia,\n WhatsAppInteractive,\n WhatsAppOrder,\n WhatsAppMessage,\n WhatsAppMessageEcho,\n WhatsAppMessageStatusValue,\n WhatsAppStatus,\n WhatsAppWebhookPayload,\n} from './webhook.types'\n\nexport type {\n SessionState,\n SessionMode,\n MessageDirection,\n MessageSender,\n MessageStatus,\n ConversationSession,\n ConversationMessage,\n ConversationSummary,\n ListConversationsParams,\n ListMessagesParams,\n} from './conversation.types'\n\nexport {\n CROSS_FLOW_PREFIX,\n isCrossFlowTarget,\n crossFlowKey,\n flowNodeNextSchema,\n flowNodeDataSchema,\n flowGraphNodesSchema,\n} from './flow.types'\nexport type {\n FlowNodeType,\n FlowQuestionType,\n FlowActionKind,\n FlowConditionOperator,\n FlowNodeNext,\n FlowNodeData,\n FlowGraphData,\n FlowGraphSummary,\n LiveFlowPosition,\n} from './flow.types'\n\nexport type {\n WhatsAppSettings,\n TemplateVariablesMap,\n TemplateConfig,\n WhatsAppTemplateSummary,\n CreateTemplateResult,\n} from './settings.types'\n\nexport type { MetaWhatsAppHooks, MessageHookOutcome } from './events'\n\nexport type {\n ChannelAdapterInterface,\n SubjectResolverInterface,\n CatalogProduct,\n CatalogPort,\n ObjectStorageInterface,\n RealtimeNotifierInterface,\n FlowActionHandler,\n FlowActionResult,\n FlowActionRegistry,\n} from './providers'\n\nexport {\n MetaWhatsAppError,\n META_WHATSAPP_ERROR_CODES,\n WindowExpiredError,\n InvalidWebhookSignatureError,\n DuplicateWebhookDeliveryError,\n ConfigMissingError,\n TemplateNotConfiguredError,\n SessionNotFoundError,\n} from './errors'\n","import { z } from 'zod'\n\n// Extraído de financiamento-imobiliario-bot/apps/api/src/modules/webhook/application/use-cases/\n// ReceiveWhatsAppWebhook.use-case.ts:39-113 — shape real do payload da Cloud API da Meta.\n\nexport const whatsAppMediaSchema = z.object({\n id: z.string(),\n mime_type: z.string(),\n sha256: z.string().optional(),\n caption: z.string().optional(),\n filename: z.string().optional(),\n})\nexport type WhatsAppMedia = z.infer<typeof whatsAppMediaSchema>\n\nexport const whatsAppInteractiveSchema = z.object({\n type: z.string(),\n button_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n list_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n})\nexport type WhatsAppInteractive = z.infer<typeof whatsAppInteractiveSchema>\n\nexport const whatsAppOrderSchema = z.object({\n catalog_id: z.string(),\n text: z.string().optional(),\n product_items: z.array(\n z.object({\n product_retailer_id: z.string(),\n quantity: z.number(),\n item_price: z.number(),\n currency: z.string(),\n }),\n ),\n})\nexport type WhatsAppOrder = z.infer<typeof whatsAppOrderSchema>\n\nexport const whatsAppMessageSchema = z.object({\n id: z.string(),\n from: z.string(),\n type: z.string(),\n text: z.object({ body: z.string() }).optional(),\n image: whatsAppMediaSchema.optional(),\n audio: whatsAppMediaSchema.optional(),\n video: whatsAppMediaSchema.optional(),\n document: whatsAppMediaSchema.optional(),\n sticker: whatsAppMediaSchema.optional(),\n interactive: whatsAppInteractiveSchema.optional(),\n // Pedido enviado pelo carrinho do catálogo (WhatsApp Commerce)\n order: whatsAppOrderSchema.optional(),\n // Presente quando o cliente abre um item do catálogo e manda mensagem pela página do produto\n context: z\n .object({\n from: z.string().optional(),\n id: z.string().optional(),\n referred_product: z.object({ catalog_id: z.string(), product_retailer_id: z.string() }).optional(),\n })\n .optional(),\n timestamp: z.string(),\n})\nexport type WhatsAppMessage = z.infer<typeof whatsAppMessageSchema>\n\nexport const whatsAppMessageEchoSchema = z.object({\n id: z.string(),\n from: z.string(),\n timestamp: z.string(),\n type: z.string(),\n})\nexport type WhatsAppMessageEcho = z.infer<typeof whatsAppMessageEchoSchema>\n\nexport const whatsAppMessageStatusSchema = z.enum(['sent', 'delivered', 'read', 'failed'])\nexport type WhatsAppMessageStatusValue = z.infer<typeof whatsAppMessageStatusSchema>\n\nexport const whatsAppStatusSchema = z.object({\n id: z.string(),\n status: whatsAppMessageStatusSchema,\n timestamp: z.string(),\n recipient_id: z.string().optional(),\n})\nexport type WhatsAppStatus = z.infer<typeof whatsAppStatusSchema>\n\nexport const whatsAppWebhookPayloadSchema = z.object({\n object: z.string(),\n entry: z.array(\n z.object({\n id: z.string(),\n changes: z.array(\n z.object({\n value: z.object({\n messaging_product: z.string(),\n messages: z.array(whatsAppMessageSchema).optional(),\n message_echoes: z.array(whatsAppMessageEchoSchema).optional(),\n statuses: z.array(whatsAppStatusSchema).optional(),\n metadata: z.object({ display_phone_number: z.string(), phone_number_id: z.string() }).optional(),\n }),\n }),\n ),\n }),\n ),\n})\nexport type WhatsAppWebhookPayload = z.infer<typeof whatsAppWebhookPayloadSchema>\n","// Mesmo shape de dados do editor visual (@adatechnology/conversations-ui/flows) — o backend\n// interpreta/persiste o grafo, o frontend edita; os dois lados precisam concordar no formato.\n// `FlowActionKind` é string aberta (não union fechada): o host registra os próprios actions\n// (ex.: 'trigger_simulation' no bot) via registerFlowAction() no módulo (T4.3) — o pacote nunca\n// assume nenhum caso de negócio específico.\nimport { z } from 'zod'\n\nexport type FlowNodeType = 'question' | 'entrada_choice' | 'action' | 'menu' | 'condition'\nexport type FlowQuestionType = 'text' | 'money' | 'date' | 'int' | 'cpf' | 'choice'\nexport type FlowActionKind = string\nexport type FlowConditionOperator = '>' | '>=' | '<' | '<=' | '==' | '!=' | 'contains'\nexport type FlowNodeNext = string | { byAnswer: Record<string, string>; default: string }\n\n// Destinos \"flow:<key>\" são saltos para outro fluxo — mesma convenção usada pelo editor visual\n// (conversations-ui/flows/flowGraph.ts); backend e frontend precisam concordar no formato.\nexport const CROSS_FLOW_PREFIX = 'flow:'\nexport const isCrossFlowTarget = (target: string): boolean => target.startsWith(CROSS_FLOW_PREFIX)\nexport const crossFlowKey = (target: string): string => target.slice(CROSS_FLOW_PREFIX.length)\n\nexport type FlowNodeData = {\n id: string\n type: FlowNodeType\n contextKey?: string\n questionType?: FlowQuestionType\n question?: string\n options?: [string, string][]\n actionKind?: FlowActionKind\n // Parâmetros arbitrários que o nó carrega para o handler registrado em `actionKind`. O pacote\n // nunca os interpreta — é o que permite um nó de ação ser configurado pelo editor sem que o\n // vocabulário do produto (o antigo `simulationTemplate`) vaze para dentro do contrato.\n actionParams?: Record<string, unknown>\n directMessage?: string\n fallbackMessage?: string\n conditionContextKey?: string\n conditionOperator?: FlowConditionOperator\n conditionValue?: string\n position?: { x: number; y: number }\n next?: FlowNodeNext\n}\n\nexport interface FlowGraphData {\n key: string\n label: string\n startNodeId: string\n version: number\n nodes: Record<string, FlowNodeData>\n}\n\nexport interface FlowGraphSummary {\n key: string\n label: string\n nodeCount: number\n showInMenu: boolean\n menuOptionLabel?: string\n updatedAt: string\n}\n\n// Retorno de GetLiveFlowPositions (T4.2) — quantas sessões ativas estão em cada nó agora,\n// usado pelo editor para desenhar o \"liveCount\" nos cards (FlowNodeCardData.liveCount).\nexport interface LiveFlowPosition {\n flowKey: string\n nodeId: string\n count: number\n}\n\n// Validação de runtime do grafo. O `nodes` é um jsonb que entrou pelo editor (dado de origem\n// cliente) e sai do banco como `unknown` — sem parse, um grafo malformado só se manifestaria\n// como comportamento estranho lá dentro do interpretador, longe da causa.\n//\n// Permissivo de propósito em dois pontos: `actionKind` é string aberta (o host registra os\n// seus) e `.passthrough()` deixa passar campos extras — um grafo salvo por uma versão mais nova\n// do editor não pode ficar irrecuperável numa versão mais antiga do módulo.\nexport const flowNodeNextSchema = z.union([\n z.string(),\n z.object({ byAnswer: z.record(z.string(), z.string()), default: z.string() }),\n])\n\nexport const flowNodeDataSchema = z\n .object({\n id: z.string(),\n type: z.enum(['question', 'entrada_choice', 'action', 'menu', 'condition']),\n contextKey: z.string().optional(),\n questionType: z.enum(['text', 'money', 'date', 'int', 'cpf', 'choice']).optional(),\n question: z.string().optional(),\n options: z.array(z.tuple([z.string(), z.string()])).optional(),\n actionKind: z.string().optional(),\n actionParams: z.record(z.string(), z.unknown()).optional(),\n directMessage: z.string().optional(),\n fallbackMessage: z.string().optional(),\n conditionContextKey: z.string().optional(),\n conditionOperator: z.enum(['>', '>=', '<', '<=', '==', '!=', 'contains']).optional(),\n conditionValue: z.string().optional(),\n position: z.object({ x: z.number(), y: z.number() }).optional(),\n next: flowNodeNextSchema.optional(),\n })\n .passthrough()\n\nexport const flowGraphNodesSchema = z.record(z.string(), flowNodeDataSchema)\n","// Hierarquia de erros do módulo — não depende do framework de erros do host (nenhum DomainError\n// importado); o host mapeia estes para o seu próprio formato de resposta no exception filter.\nexport class MetaWhatsAppError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly code: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'MetaWhatsAppError'\n }\n}\n\nexport const META_WHATSAPP_ERROR_CODES = {\n WINDOW_EXPIRED: 'META_WHATSAPP_WINDOW_EXPIRED',\n INVALID_SIGNATURE: 'META_WHATSAPP_INVALID_SIGNATURE',\n DUPLICATE_DELIVERY: 'META_WHATSAPP_DUPLICATE_DELIVERY',\n CONFIG_MISSING: 'META_WHATSAPP_CONFIG_MISSING',\n TEMPLATE_NOT_CONFIGURED: 'META_WHATSAPP_TEMPLATE_NOT_CONFIGURED',\n SESSION_NOT_FOUND: 'META_WHATSAPP_SESSION_NOT_FOUND',\n} as const\n\nexport class WindowExpiredError extends MetaWhatsAppError {\n constructor(public readonly hoursSinceLastMessage?: number) {\n super(\n 'Janela de 24h expirada — não é possível enviar mensagem para este contato fora de template.',\n 400,\n META_WHATSAPP_ERROR_CODES.WINDOW_EXPIRED,\n { hoursSinceLastMessage },\n )\n }\n}\n\n// Assinatura HMAC do webhook não confere — Meta ou um terceiro tentando forjar uma entrega.\nexport class InvalidWebhookSignatureError extends MetaWhatsAppError {\n constructor() {\n super('Assinatura do webhook inválida.', 401, META_WHATSAPP_ERROR_CODES.INVALID_SIGNATURE)\n }\n}\n\n// Meta reenviou uma entrega dentro da janela de replay (nonce já visto) — não é erro do\n// cliente, é comportamento esperado da Cloud API; o host deve responder 200 e ignorar.\nexport class DuplicateWebhookDeliveryError extends MetaWhatsAppError {\n constructor(nonce: string) {\n super('Entrega de webhook duplicada.', 409, META_WHATSAPP_ERROR_CODES.DUPLICATE_DELIVERY, { nonce })\n }\n}\n\nexport class ConfigMissingError extends MetaWhatsAppError {\n constructor(missingField: string) {\n super(`Configuração do WhatsApp ausente: ${missingField}.`, 503, META_WHATSAPP_ERROR_CODES.CONFIG_MISSING, {\n missingField,\n })\n }\n}\n\nexport class TemplateNotConfiguredError extends MetaWhatsAppError {\n constructor() {\n super(\n 'Nenhum template de WhatsApp configurado para reabertura de janela.',\n 503,\n META_WHATSAPP_ERROR_CODES.TEMPLATE_NOT_CONFIGURED,\n )\n }\n}\n\nexport class SessionNotFoundError extends MetaWhatsAppError {\n constructor(whatsappNumber: string) {\n super(\n `Sessão de conversa não encontrada para ${whatsappNumber}.`,\n 404,\n META_WHATSAPP_ERROR_CODES.SESSION_NOT_FOUND,\n { whatsappNumber },\n )\n }\n}\n"],"mappings":"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","names":["whatsAppMediaSchema","z","object","id","string","mime_type","sha256","optional","caption","filename","whatsAppInteractiveSchema","type","button_reply","title","list_reply","whatsAppOrderSchema","catalog_id","text","product_items","array","product_retailer_id","quantity","number","item_price","currency","whatsAppMessageSchema","from","body","image","audio","video","document","sticker","interactive","order","context","referred_product","timestamp","whatsAppMessageEchoSchema","whatsAppMessageStatusSchema","enum","whatsAppStatusSchema","status","recipient_id","whatsAppWebhookPayloadSchema","entry","changes","value","messaging_product","messages","message_echoes","statuses","metadata","display_phone_number","phone_number_id","import_zod","CROSS_FLOW_PREFIX","isCrossFlowTarget","target","startsWith","crossFlowKey","slice","length","flowNodeNextSchema","z","union","string","object","byAnswer","record","default","flowNodeDataSchema","id","type","enum","contextKey","optional","questionType","question","options","array","tuple","actionKind","actionParams","unknown","directMessage","fallbackMessage","conditionContextKey","conditionOperator","conditionValue","position","x","number","y","next","passthrough","flowGraphNodesSchema","MetaWhatsAppError","Error","message","statusCode","code","details","name","META_WHATSAPP_ERROR_CODES","WINDOW_EXPIRED","INVALID_SIGNATURE","DUPLICATE_DELIVERY","CONFIG_MISSING","TEMPLATE_NOT_CONFIGURED","SESSION_NOT_FOUND","WindowExpiredError","hoursSinceLastMessage","InvalidWebhookSignatureError","DuplicateWebhookDeliveryError","nonce","ConfigMissingError","missingField","TemplateNotConfiguredError","SessionNotFoundError","whatsappNumber"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -83,7 +83,7 @@ type FlowNodeData = {
|
|
|
83
83
|
question?: string;
|
|
84
84
|
options?: [string, string][];
|
|
85
85
|
actionKind?: FlowActionKind;
|
|
86
|
-
|
|
86
|
+
actionParams?: Record<string, unknown>;
|
|
87
87
|
directMessage?: string;
|
|
88
88
|
fallbackMessage?: string;
|
|
89
89
|
conditionContextKey?: string;
|
|
@@ -133,7 +133,7 @@ declare const flowNodeDataSchema: z.ZodObject<{
|
|
|
133
133
|
question: z.ZodOptional<z.ZodString>;
|
|
134
134
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
135
135
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
136
|
-
|
|
136
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
137
137
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
138
138
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
139
139
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -167,7 +167,7 @@ declare const flowNodeDataSchema: z.ZodObject<{
|
|
|
167
167
|
question: z.ZodOptional<z.ZodString>;
|
|
168
168
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
169
169
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
170
|
-
|
|
170
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
171
171
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
172
172
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
173
173
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -201,7 +201,7 @@ declare const flowNodeDataSchema: z.ZodObject<{
|
|
|
201
201
|
question: z.ZodOptional<z.ZodString>;
|
|
202
202
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
203
203
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
204
|
-
|
|
204
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
205
205
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
206
206
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
207
207
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -236,7 +236,7 @@ declare const flowGraphNodesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
236
236
|
question: z.ZodOptional<z.ZodString>;
|
|
237
237
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
238
238
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
239
|
-
|
|
239
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
240
240
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
241
241
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
242
242
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -270,7 +270,7 @@ declare const flowGraphNodesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
270
270
|
question: z.ZodOptional<z.ZodString>;
|
|
271
271
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
272
272
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
273
|
-
|
|
273
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
274
274
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
275
275
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
276
276
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -304,7 +304,7 @@ declare const flowGraphNodesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
304
304
|
question: z.ZodOptional<z.ZodString>;
|
|
305
305
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
306
306
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
307
|
-
|
|
307
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
308
308
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
309
309
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
310
310
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
package/dist/index.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ type FlowNodeData = {
|
|
|
83
83
|
question?: string;
|
|
84
84
|
options?: [string, string][];
|
|
85
85
|
actionKind?: FlowActionKind;
|
|
86
|
-
|
|
86
|
+
actionParams?: Record<string, unknown>;
|
|
87
87
|
directMessage?: string;
|
|
88
88
|
fallbackMessage?: string;
|
|
89
89
|
conditionContextKey?: string;
|
|
@@ -133,7 +133,7 @@ declare const flowNodeDataSchema: z.ZodObject<{
|
|
|
133
133
|
question: z.ZodOptional<z.ZodString>;
|
|
134
134
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
135
135
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
136
|
-
|
|
136
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
137
137
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
138
138
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
139
139
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -167,7 +167,7 @@ declare const flowNodeDataSchema: z.ZodObject<{
|
|
|
167
167
|
question: z.ZodOptional<z.ZodString>;
|
|
168
168
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
169
169
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
170
|
-
|
|
170
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
171
171
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
172
172
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
173
173
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -201,7 +201,7 @@ declare const flowNodeDataSchema: z.ZodObject<{
|
|
|
201
201
|
question: z.ZodOptional<z.ZodString>;
|
|
202
202
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
203
203
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
204
|
-
|
|
204
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
205
205
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
206
206
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
207
207
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -236,7 +236,7 @@ declare const flowGraphNodesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
236
236
|
question: z.ZodOptional<z.ZodString>;
|
|
237
237
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
238
238
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
239
|
-
|
|
239
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
240
240
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
241
241
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
242
242
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -270,7 +270,7 @@ declare const flowGraphNodesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
270
270
|
question: z.ZodOptional<z.ZodString>;
|
|
271
271
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
272
272
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
273
|
-
|
|
273
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
274
274
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
275
275
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
276
276
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
|
@@ -304,7 +304,7 @@ declare const flowGraphNodesSchema: z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
|
304
304
|
question: z.ZodOptional<z.ZodString>;
|
|
305
305
|
options: z.ZodOptional<z.ZodArray<z.ZodTuple<[z.ZodString, z.ZodString], null>, "many">>;
|
|
306
306
|
actionKind: z.ZodOptional<z.ZodString>;
|
|
307
|
-
|
|
307
|
+
actionParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
308
308
|
directMessage: z.ZodOptional<z.ZodString>;
|
|
309
309
|
fallbackMessage: z.ZodOptional<z.ZodString>;
|
|
310
310
|
conditionContextKey: z.ZodOptional<z.ZodString>;
|
package/dist/index.js
CHANGED
|
@@ -130,7 +130,7 @@ var flowNodeDataSchema = z2.object({
|
|
|
130
130
|
z2.string()
|
|
131
131
|
])).optional(),
|
|
132
132
|
actionKind: z2.string().optional(),
|
|
133
|
-
|
|
133
|
+
actionParams: z2.record(z2.string(), z2.unknown()).optional(),
|
|
134
134
|
directMessage: z2.string().optional(),
|
|
135
135
|
fallbackMessage: z2.string().optional(),
|
|
136
136
|
conditionContextKey: z2.string().optional(),
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/webhook.types.ts","../src/flow.types.ts","../src/errors.ts"],"sourcesContent":["import { z } from 'zod'\n\n// Extraído de financiamento-imobiliario-bot/apps/api/src/modules/webhook/application/use-cases/\n// ReceiveWhatsAppWebhook.use-case.ts:39-113 — shape real do payload da Cloud API da Meta.\n\nexport const whatsAppMediaSchema = z.object({\n id: z.string(),\n mime_type: z.string(),\n sha256: z.string().optional(),\n caption: z.string().optional(),\n filename: z.string().optional(),\n})\nexport type WhatsAppMedia = z.infer<typeof whatsAppMediaSchema>\n\nexport const whatsAppInteractiveSchema = z.object({\n type: z.string(),\n button_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n list_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n})\nexport type WhatsAppInteractive = z.infer<typeof whatsAppInteractiveSchema>\n\nexport const whatsAppOrderSchema = z.object({\n catalog_id: z.string(),\n text: z.string().optional(),\n product_items: z.array(\n z.object({\n product_retailer_id: z.string(),\n quantity: z.number(),\n item_price: z.number(),\n currency: z.string(),\n }),\n ),\n})\nexport type WhatsAppOrder = z.infer<typeof whatsAppOrderSchema>\n\nexport const whatsAppMessageSchema = z.object({\n id: z.string(),\n from: z.string(),\n type: z.string(),\n text: z.object({ body: z.string() }).optional(),\n image: whatsAppMediaSchema.optional(),\n audio: whatsAppMediaSchema.optional(),\n video: whatsAppMediaSchema.optional(),\n document: whatsAppMediaSchema.optional(),\n sticker: whatsAppMediaSchema.optional(),\n interactive: whatsAppInteractiveSchema.optional(),\n // Pedido enviado pelo carrinho do catálogo (WhatsApp Commerce)\n order: whatsAppOrderSchema.optional(),\n // Presente quando o cliente abre um item do catálogo e manda mensagem pela página do produto\n context: z\n .object({\n from: z.string().optional(),\n id: z.string().optional(),\n referred_product: z.object({ catalog_id: z.string(), product_retailer_id: z.string() }).optional(),\n })\n .optional(),\n timestamp: z.string(),\n})\nexport type WhatsAppMessage = z.infer<typeof whatsAppMessageSchema>\n\nexport const whatsAppMessageEchoSchema = z.object({\n id: z.string(),\n from: z.string(),\n timestamp: z.string(),\n type: z.string(),\n})\nexport type WhatsAppMessageEcho = z.infer<typeof whatsAppMessageEchoSchema>\n\nexport const whatsAppMessageStatusSchema = z.enum(['sent', 'delivered', 'read', 'failed'])\nexport type WhatsAppMessageStatusValue = z.infer<typeof whatsAppMessageStatusSchema>\n\nexport const whatsAppStatusSchema = z.object({\n id: z.string(),\n status: whatsAppMessageStatusSchema,\n timestamp: z.string(),\n recipient_id: z.string().optional(),\n})\nexport type WhatsAppStatus = z.infer<typeof whatsAppStatusSchema>\n\nexport const whatsAppWebhookPayloadSchema = z.object({\n object: z.string(),\n entry: z.array(\n z.object({\n id: z.string(),\n changes: z.array(\n z.object({\n value: z.object({\n messaging_product: z.string(),\n messages: z.array(whatsAppMessageSchema).optional(),\n message_echoes: z.array(whatsAppMessageEchoSchema).optional(),\n statuses: z.array(whatsAppStatusSchema).optional(),\n metadata: z.object({ display_phone_number: z.string(), phone_number_id: z.string() }).optional(),\n }),\n }),\n ),\n }),\n ),\n})\nexport type WhatsAppWebhookPayload = z.infer<typeof whatsAppWebhookPayloadSchema>\n","// Mesmo shape de dados do editor visual (@adatechnology/conversations-ui/flows) — o backend\n// interpreta/persiste o grafo, o frontend edita; os dois lados precisam concordar no formato.\n// `FlowActionKind` é string aberta (não union fechada): o host registra os próprios actions\n// (ex.: 'trigger_simulation' no bot) via registerFlowAction() no módulo (T4.3) — o pacote nunca\n// assume nenhum caso de negócio específico.\nimport { z } from 'zod'\n\nexport type FlowNodeType = 'question' | 'entrada_choice' | 'action' | 'menu' | 'condition'\nexport type FlowQuestionType = 'text' | 'money' | 'date' | 'int' | 'cpf' | 'choice'\nexport type FlowActionKind = string\nexport type FlowConditionOperator = '>' | '>=' | '<' | '<=' | '==' | '!=' | 'contains'\nexport type FlowNodeNext = string | { byAnswer: Record<string, string>; default: string }\n\n// Destinos \"flow:<key>\" são saltos para outro fluxo — mesma convenção usada pelo editor visual\n// (conversations-ui/flows/flowGraph.ts); backend e frontend precisam concordar no formato.\nexport const CROSS_FLOW_PREFIX = 'flow:'\nexport const isCrossFlowTarget = (target: string): boolean => target.startsWith(CROSS_FLOW_PREFIX)\nexport const crossFlowKey = (target: string): string => target.slice(CROSS_FLOW_PREFIX.length)\n\nexport type FlowNodeData = {\n id: string\n type: FlowNodeType\n contextKey?: string\n questionType?: FlowQuestionType\n question?: string\n options?: [string, string][]\n actionKind?: FlowActionKind\n simulationTemplate?: Record<string, string>\n directMessage?: string\n fallbackMessage?: string\n conditionContextKey?: string\n conditionOperator?: FlowConditionOperator\n conditionValue?: string\n position?: { x: number; y: number }\n next?: FlowNodeNext\n}\n\nexport interface FlowGraphData {\n key: string\n label: string\n startNodeId: string\n version: number\n nodes: Record<string, FlowNodeData>\n}\n\nexport interface FlowGraphSummary {\n key: string\n label: string\n nodeCount: number\n showInMenu: boolean\n menuOptionLabel?: string\n updatedAt: string\n}\n\n// Retorno de GetLiveFlowPositions (T4.2) — quantas sessões ativas estão em cada nó agora,\n// usado pelo editor para desenhar o \"liveCount\" nos cards (FlowNodeCardData.liveCount).\nexport interface LiveFlowPosition {\n flowKey: string\n nodeId: string\n count: number\n}\n\n// Validação de runtime do grafo. O `nodes` é um jsonb que entrou pelo editor (dado de origem\n// cliente) e sai do banco como `unknown` — sem parse, um grafo malformado só se manifestaria\n// como comportamento estranho lá dentro do interpretador, longe da causa.\n//\n// Permissivo de propósito em dois pontos: `actionKind` é string aberta (o host registra os\n// seus) e `.passthrough()` deixa passar campos extras — um grafo salvo por uma versão mais nova\n// do editor não pode ficar irrecuperável numa versão mais antiga do módulo.\nexport const flowNodeNextSchema = z.union([\n z.string(),\n z.object({ byAnswer: z.record(z.string(), z.string()), default: z.string() }),\n])\n\nexport const flowNodeDataSchema = z\n .object({\n id: z.string(),\n type: z.enum(['question', 'entrada_choice', 'action', 'menu', 'condition']),\n contextKey: z.string().optional(),\n questionType: z.enum(['text', 'money', 'date', 'int', 'cpf', 'choice']).optional(),\n question: z.string().optional(),\n options: z.array(z.tuple([z.string(), z.string()])).optional(),\n actionKind: z.string().optional(),\n simulationTemplate: z.record(z.string(), z.string()).optional(),\n directMessage: z.string().optional(),\n fallbackMessage: z.string().optional(),\n conditionContextKey: z.string().optional(),\n conditionOperator: z.enum(['>', '>=', '<', '<=', '==', '!=', 'contains']).optional(),\n conditionValue: z.string().optional(),\n position: z.object({ x: z.number(), y: z.number() }).optional(),\n next: flowNodeNextSchema.optional(),\n })\n .passthrough()\n\nexport const flowGraphNodesSchema = z.record(z.string(), flowNodeDataSchema)\n","// Hierarquia de erros do módulo — não depende do framework de erros do host (nenhum DomainError\n// importado); o host mapeia estes para o seu próprio formato de resposta no exception filter.\nexport class MetaWhatsAppError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly code: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'MetaWhatsAppError'\n }\n}\n\nexport const META_WHATSAPP_ERROR_CODES = {\n WINDOW_EXPIRED: 'META_WHATSAPP_WINDOW_EXPIRED',\n INVALID_SIGNATURE: 'META_WHATSAPP_INVALID_SIGNATURE',\n DUPLICATE_DELIVERY: 'META_WHATSAPP_DUPLICATE_DELIVERY',\n CONFIG_MISSING: 'META_WHATSAPP_CONFIG_MISSING',\n TEMPLATE_NOT_CONFIGURED: 'META_WHATSAPP_TEMPLATE_NOT_CONFIGURED',\n SESSION_NOT_FOUND: 'META_WHATSAPP_SESSION_NOT_FOUND',\n} as const\n\nexport class WindowExpiredError extends MetaWhatsAppError {\n constructor(public readonly hoursSinceLastMessage?: number) {\n super(\n 'Janela de 24h expirada — não é possível enviar mensagem para este contato fora de template.',\n 400,\n META_WHATSAPP_ERROR_CODES.WINDOW_EXPIRED,\n { hoursSinceLastMessage },\n )\n }\n}\n\n// Assinatura HMAC do webhook não confere — Meta ou um terceiro tentando forjar uma entrega.\nexport class InvalidWebhookSignatureError extends MetaWhatsAppError {\n constructor() {\n super('Assinatura do webhook inválida.', 401, META_WHATSAPP_ERROR_CODES.INVALID_SIGNATURE)\n }\n}\n\n// Meta reenviou uma entrega dentro da janela de replay (nonce já visto) — não é erro do\n// cliente, é comportamento esperado da Cloud API; o host deve responder 200 e ignorar.\nexport class DuplicateWebhookDeliveryError extends MetaWhatsAppError {\n constructor(nonce: string) {\n super('Entrega de webhook duplicada.', 409, META_WHATSAPP_ERROR_CODES.DUPLICATE_DELIVERY, { nonce })\n }\n}\n\nexport class ConfigMissingError extends MetaWhatsAppError {\n constructor(missingField: string) {\n super(`Configuração do WhatsApp ausente: ${missingField}.`, 503, META_WHATSAPP_ERROR_CODES.CONFIG_MISSING, {\n missingField,\n })\n }\n}\n\nexport class TemplateNotConfiguredError extends MetaWhatsAppError {\n constructor() {\n super(\n 'Nenhum template de WhatsApp configurado para reabertura de janela.',\n 503,\n META_WHATSAPP_ERROR_CODES.TEMPLATE_NOT_CONFIGURED,\n )\n }\n}\n\nexport class SessionNotFoundError extends MetaWhatsAppError {\n constructor(whatsappNumber: string) {\n super(\n `Sessão de conversa não encontrada para ${whatsappNumber}.`,\n 404,\n META_WHATSAPP_ERROR_CODES.SESSION_NOT_FOUND,\n { whatsappNumber },\n )\n }\n}\n"],"mappings":";;;;AAAA,SAASA,SAAS;AAKX,IAAMC,sBAAsBD,EAAEE,OAAO;EAC1CC,IAAIH,EAAEI,OAAM;EACZC,WAAWL,EAAEI,OAAM;EACnBE,QAAQN,EAAEI,OAAM,EAAGG,SAAQ;EAC3BC,SAASR,EAAEI,OAAM,EAAGG,SAAQ;EAC5BE,UAAUT,EAAEI,OAAM,EAAGG,SAAQ;AAC/B,CAAA;AAGO,IAAMG,4BAA4BV,EAAEE,OAAO;EAChDS,MAAMX,EAAEI,OAAM;EACdQ,cAAcZ,EAAEE,OAAO;IAAEC,IAAIH,EAAEI,OAAM;IAAIS,OAAOb,EAAEI,OAAM;EAAG,CAAA,EAAGG,SAAQ;EACtEO,YAAYd,EAAEE,OAAO;IAAEC,IAAIH,EAAEI,OAAM;IAAIS,OAAOb,EAAEI,OAAM;EAAG,CAAA,EAAGG,SAAQ;AACtE,CAAA;AAGO,IAAMQ,sBAAsBf,EAAEE,OAAO;EAC1Cc,YAAYhB,EAAEI,OAAM;EACpBa,MAAMjB,EAAEI,OAAM,EAAGG,SAAQ;EACzBW,eAAelB,EAAEmB,MACfnB,EAAEE,OAAO;IACPkB,qBAAqBpB,EAAEI,OAAM;IAC7BiB,UAAUrB,EAAEsB,OAAM;IAClBC,YAAYvB,EAAEsB,OAAM;IACpBE,UAAUxB,EAAEI,OAAM;EACpB,CAAA,CAAA;AAEJ,CAAA;AAGO,IAAMqB,wBAAwBzB,EAAEE,OAAO;EAC5CC,IAAIH,EAAEI,OAAM;EACZsB,MAAM1B,EAAEI,OAAM;EACdO,MAAMX,EAAEI,OAAM;EACda,MAAMjB,EAAEE,OAAO;IAAEyB,MAAM3B,EAAEI,OAAM;EAAG,CAAA,EAAGG,SAAQ;EAC7CqB,OAAO3B,oBAAoBM,SAAQ;EACnCsB,OAAO5B,oBAAoBM,SAAQ;EACnCuB,OAAO7B,oBAAoBM,SAAQ;EACnCwB,UAAU9B,oBAAoBM,SAAQ;EACtCyB,SAAS/B,oBAAoBM,SAAQ;EACrC0B,aAAavB,0BAA0BH,SAAQ;;EAE/C2B,OAAOnB,oBAAoBR,SAAQ;;EAEnC4B,SAASnC,EACNE,OAAO;IACNwB,MAAM1B,EAAEI,OAAM,EAAGG,SAAQ;IACzBJ,IAAIH,EAAEI,OAAM,EAAGG,SAAQ;IACvB6B,kBAAkBpC,EAAEE,OAAO;MAAEc,YAAYhB,EAAEI,OAAM;MAAIgB,qBAAqBpB,EAAEI,OAAM;IAAG,CAAA,EAAGG,SAAQ;EAClG,CAAA,EACCA,SAAQ;EACX8B,WAAWrC,EAAEI,OAAM;AACrB,CAAA;AAGO,IAAMkC,4BAA4BtC,EAAEE,OAAO;EAChDC,IAAIH,EAAEI,OAAM;EACZsB,MAAM1B,EAAEI,OAAM;EACdiC,WAAWrC,EAAEI,OAAM;EACnBO,MAAMX,EAAEI,OAAM;AAChB,CAAA;AAGO,IAAMmC,8BAA8BvC,EAAEwC,KAAK;EAAC;EAAQ;EAAa;EAAQ;CAAS;AAGlF,IAAMC,uBAAuBzC,EAAEE,OAAO;EAC3CC,IAAIH,EAAEI,OAAM;EACZsC,QAAQH;EACRF,WAAWrC,EAAEI,OAAM;EACnBuC,cAAc3C,EAAEI,OAAM,EAAGG,SAAQ;AACnC,CAAA;AAGO,IAAMqC,+BAA+B5C,EAAEE,OAAO;EACnDA,QAAQF,EAAEI,OAAM;EAChByC,OAAO7C,EAAEmB,MACPnB,EAAEE,OAAO;IACPC,IAAIH,EAAEI,OAAM;IACZ0C,SAAS9C,EAAEmB,MACTnB,EAAEE,OAAO;MACP6C,OAAO/C,EAAEE,OAAO;QACd8C,mBAAmBhD,EAAEI,OAAM;QAC3B6C,UAAUjD,EAAEmB,MAAMM,qBAAAA,EAAuBlB,SAAQ;QACjD2C,gBAAgBlD,EAAEmB,MAAMmB,yBAAAA,EAA2B/B,SAAQ;QAC3D4C,UAAUnD,EAAEmB,MAAMsB,oBAAAA,EAAsBlC,SAAQ;QAChD6C,UAAUpD,EAAEE,OAAO;UAAEmD,sBAAsBrD,EAAEI,OAAM;UAAIkD,iBAAiBtD,EAAEI,OAAM;QAAG,CAAA,EAAGG,SAAQ;MAChG,CAAA;IACF,CAAA,CAAA;EAEJ,CAAA,CAAA;AAEJ,CAAA;;;AC5FA,SAASgD,KAAAA,UAAS;AAUX,IAAMC,oBAAoB;AAC1B,IAAMC,oBAAoB,wBAACC,WAA4BA,OAAOC,WAAWH,iBAAAA,GAA/C;AAC1B,IAAMI,eAAe,wBAACF,WAA2BA,OAAOG,MAAML,kBAAkBM,MAAM,GAAjE;AAoDrB,IAAMC,qBAAqBC,GAAEC,MAAM;EACxCD,GAAEE,OAAM;EACRF,GAAEG,OAAO;IAAEC,UAAUJ,GAAEK,OAAOL,GAAEE,OAAM,GAAIF,GAAEE,OAAM,CAAA;IAAKI,SAASN,GAAEE,OAAM;EAAG,CAAA;CAC5E;AAEM,IAAMK,qBAAqBP,GAC/BG,OAAO;EACNK,IAAIR,GAAEE,OAAM;EACZO,MAAMT,GAAEU,KAAK;IAAC;IAAY;IAAkB;IAAU;IAAQ;GAAY;EAC1EC,YAAYX,GAAEE,OAAM,EAAGU,SAAQ;EAC/BC,cAAcb,GAAEU,KAAK;IAAC;IAAQ;IAAS;IAAQ;IAAO;IAAO;GAAS,EAAEE,SAAQ;EAChFE,UAAUd,GAAEE,OAAM,EAAGU,SAAQ;EAC7BG,SAASf,GAAEgB,MAAMhB,GAAEiB,MAAM;IAACjB,GAAEE,OAAM;IAAIF,GAAEE,OAAM;GAAG,CAAA,EAAGU,SAAQ;EAC5DM,YAAYlB,GAAEE,OAAM,EAAGU,SAAQ;EAC/BO,oBAAoBnB,GAAEK,OAAOL,GAAEE,OAAM,GAAIF,GAAEE,OAAM,CAAA,EAAIU,SAAQ;EAC7DQ,eAAepB,GAAEE,OAAM,EAAGU,SAAQ;EAClCS,iBAAiBrB,GAAEE,OAAM,EAAGU,SAAQ;EACpCU,qBAAqBtB,GAAEE,OAAM,EAAGU,SAAQ;EACxCW,mBAAmBvB,GAAEU,KAAK;IAAC;IAAK;IAAM;IAAK;IAAM;IAAM;IAAM;GAAW,EAAEE,SAAQ;EAClFY,gBAAgBxB,GAAEE,OAAM,EAAGU,SAAQ;EACnCa,UAAUzB,GAAEG,OAAO;IAAEuB,GAAG1B,GAAE2B,OAAM;IAAIC,GAAG5B,GAAE2B,OAAM;EAAG,CAAA,EAAGf,SAAQ;EAC7DiB,MAAM9B,mBAAmBa,SAAQ;AACnC,CAAA,EACCkB,YAAW;AAEP,IAAMC,uBAAuB/B,GAAEK,OAAOL,GAAEE,OAAM,GAAIK,kBAAAA;;;AC5FlD,IAAMyB,oBAAN,cAAgCC,MAAAA;EAFvC,OAEuCA;;;;;;EACrC,YACEC,SACgBC,YACAC,MACAC,SAChB;AACA,UAAMH,OAAAA,GAAAA,KAJUC,aAAAA,YAAAA,KACAC,OAAAA,MAAAA,KACAC,UAAAA;AAGhB,SAAKC,OAAO;EACd;AACF;AAEO,IAAMC,4BAA4B;EACvCC,gBAAgB;EAChBC,mBAAmB;EACnBC,oBAAoB;EACpBC,gBAAgB;EAChBC,yBAAyB;EACzBC,mBAAmB;AACrB;AAEO,IAAMC,qBAAN,cAAiCd,kBAAAA;EAvBxC,OAuBwCA;;;;EACtC,YAA4Be,uBAAgC;AAC1D,UACE,6GACA,KACAR,0BAA0BC,gBAC1B;MAAEO;IAAsB,CAAA,GAAA,KALAA,wBAAAA;EAO5B;AACF;AAGO,IAAMC,+BAAN,cAA2ChB,kBAAAA;EAnClD,OAmCkDA;;;EAChD,cAAc;AACZ,UAAM,sCAAmC,KAAKO,0BAA0BE,iBAAiB;EAC3F;AACF;AAIO,IAAMQ,gCAAN,cAA4CjB,kBAAAA;EA3CnD,OA2CmDA;;;EACjD,YAAYkB,OAAe;AACzB,UAAM,iCAAiC,KAAKX,0BAA0BG,oBAAoB;MAAEQ;IAAM,CAAA;EACpG;AACF;AAEO,IAAMC,qBAAN,cAAiCnB,kBAAAA;EAjDxC,OAiDwCA;;;EACtC,YAAYoB,cAAsB;AAChC,UAAM,2CAAqCA,YAAAA,KAAiB,KAAKb,0BAA0BI,gBAAgB;MACzGS;IACF,CAAA;EACF;AACF;AAEO,IAAMC,6BAAN,cAAyCrB,kBAAAA;EAzDhD,OAyDgDA;;;EAC9C,cAAc;AACZ,UACE,sEACA,KACAO,0BAA0BK,uBAAuB;EAErD;AACF;AAEO,IAAMU,uBAAN,cAAmCtB,kBAAAA;EAnE1C,OAmE0CA;;;EACxC,YAAYuB,gBAAwB;AAClC,UACE,gDAA0CA,cAAAA,KAC1C,KACAhB,0BAA0BM,mBAC1B;MAAEU;IAAe,CAAA;EAErB;AACF;","names":["z","whatsAppMediaSchema","object","id","string","mime_type","sha256","optional","caption","filename","whatsAppInteractiveSchema","type","button_reply","title","list_reply","whatsAppOrderSchema","catalog_id","text","product_items","array","product_retailer_id","quantity","number","item_price","currency","whatsAppMessageSchema","from","body","image","audio","video","document","sticker","interactive","order","context","referred_product","timestamp","whatsAppMessageEchoSchema","whatsAppMessageStatusSchema","enum","whatsAppStatusSchema","status","recipient_id","whatsAppWebhookPayloadSchema","entry","changes","value","messaging_product","messages","message_echoes","statuses","metadata","display_phone_number","phone_number_id","z","CROSS_FLOW_PREFIX","isCrossFlowTarget","target","startsWith","crossFlowKey","slice","length","flowNodeNextSchema","z","union","string","object","byAnswer","record","default","flowNodeDataSchema","id","type","enum","contextKey","optional","questionType","question","options","array","tuple","actionKind","simulationTemplate","directMessage","fallbackMessage","conditionContextKey","conditionOperator","conditionValue","position","x","number","y","next","passthrough","flowGraphNodesSchema","MetaWhatsAppError","Error","message","statusCode","code","details","name","META_WHATSAPP_ERROR_CODES","WINDOW_EXPIRED","INVALID_SIGNATURE","DUPLICATE_DELIVERY","CONFIG_MISSING","TEMPLATE_NOT_CONFIGURED","SESSION_NOT_FOUND","WindowExpiredError","hoursSinceLastMessage","InvalidWebhookSignatureError","DuplicateWebhookDeliveryError","nonce","ConfigMissingError","missingField","TemplateNotConfiguredError","SessionNotFoundError","whatsappNumber"]}
|
|
1
|
+
{"version":3,"sources":["../src/webhook.types.ts","../src/flow.types.ts","../src/errors.ts"],"sourcesContent":["import { z } from 'zod'\n\n// Extraído de financiamento-imobiliario-bot/apps/api/src/modules/webhook/application/use-cases/\n// ReceiveWhatsAppWebhook.use-case.ts:39-113 — shape real do payload da Cloud API da Meta.\n\nexport const whatsAppMediaSchema = z.object({\n id: z.string(),\n mime_type: z.string(),\n sha256: z.string().optional(),\n caption: z.string().optional(),\n filename: z.string().optional(),\n})\nexport type WhatsAppMedia = z.infer<typeof whatsAppMediaSchema>\n\nexport const whatsAppInteractiveSchema = z.object({\n type: z.string(),\n button_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n list_reply: z.object({ id: z.string(), title: z.string() }).optional(),\n})\nexport type WhatsAppInteractive = z.infer<typeof whatsAppInteractiveSchema>\n\nexport const whatsAppOrderSchema = z.object({\n catalog_id: z.string(),\n text: z.string().optional(),\n product_items: z.array(\n z.object({\n product_retailer_id: z.string(),\n quantity: z.number(),\n item_price: z.number(),\n currency: z.string(),\n }),\n ),\n})\nexport type WhatsAppOrder = z.infer<typeof whatsAppOrderSchema>\n\nexport const whatsAppMessageSchema = z.object({\n id: z.string(),\n from: z.string(),\n type: z.string(),\n text: z.object({ body: z.string() }).optional(),\n image: whatsAppMediaSchema.optional(),\n audio: whatsAppMediaSchema.optional(),\n video: whatsAppMediaSchema.optional(),\n document: whatsAppMediaSchema.optional(),\n sticker: whatsAppMediaSchema.optional(),\n interactive: whatsAppInteractiveSchema.optional(),\n // Pedido enviado pelo carrinho do catálogo (WhatsApp Commerce)\n order: whatsAppOrderSchema.optional(),\n // Presente quando o cliente abre um item do catálogo e manda mensagem pela página do produto\n context: z\n .object({\n from: z.string().optional(),\n id: z.string().optional(),\n referred_product: z.object({ catalog_id: z.string(), product_retailer_id: z.string() }).optional(),\n })\n .optional(),\n timestamp: z.string(),\n})\nexport type WhatsAppMessage = z.infer<typeof whatsAppMessageSchema>\n\nexport const whatsAppMessageEchoSchema = z.object({\n id: z.string(),\n from: z.string(),\n timestamp: z.string(),\n type: z.string(),\n})\nexport type WhatsAppMessageEcho = z.infer<typeof whatsAppMessageEchoSchema>\n\nexport const whatsAppMessageStatusSchema = z.enum(['sent', 'delivered', 'read', 'failed'])\nexport type WhatsAppMessageStatusValue = z.infer<typeof whatsAppMessageStatusSchema>\n\nexport const whatsAppStatusSchema = z.object({\n id: z.string(),\n status: whatsAppMessageStatusSchema,\n timestamp: z.string(),\n recipient_id: z.string().optional(),\n})\nexport type WhatsAppStatus = z.infer<typeof whatsAppStatusSchema>\n\nexport const whatsAppWebhookPayloadSchema = z.object({\n object: z.string(),\n entry: z.array(\n z.object({\n id: z.string(),\n changes: z.array(\n z.object({\n value: z.object({\n messaging_product: z.string(),\n messages: z.array(whatsAppMessageSchema).optional(),\n message_echoes: z.array(whatsAppMessageEchoSchema).optional(),\n statuses: z.array(whatsAppStatusSchema).optional(),\n metadata: z.object({ display_phone_number: z.string(), phone_number_id: z.string() }).optional(),\n }),\n }),\n ),\n }),\n ),\n})\nexport type WhatsAppWebhookPayload = z.infer<typeof whatsAppWebhookPayloadSchema>\n","// Mesmo shape de dados do editor visual (@adatechnology/conversations-ui/flows) — o backend\n// interpreta/persiste o grafo, o frontend edita; os dois lados precisam concordar no formato.\n// `FlowActionKind` é string aberta (não union fechada): o host registra os próprios actions\n// (ex.: 'trigger_simulation' no bot) via registerFlowAction() no módulo (T4.3) — o pacote nunca\n// assume nenhum caso de negócio específico.\nimport { z } from 'zod'\n\nexport type FlowNodeType = 'question' | 'entrada_choice' | 'action' | 'menu' | 'condition'\nexport type FlowQuestionType = 'text' | 'money' | 'date' | 'int' | 'cpf' | 'choice'\nexport type FlowActionKind = string\nexport type FlowConditionOperator = '>' | '>=' | '<' | '<=' | '==' | '!=' | 'contains'\nexport type FlowNodeNext = string | { byAnswer: Record<string, string>; default: string }\n\n// Destinos \"flow:<key>\" são saltos para outro fluxo — mesma convenção usada pelo editor visual\n// (conversations-ui/flows/flowGraph.ts); backend e frontend precisam concordar no formato.\nexport const CROSS_FLOW_PREFIX = 'flow:'\nexport const isCrossFlowTarget = (target: string): boolean => target.startsWith(CROSS_FLOW_PREFIX)\nexport const crossFlowKey = (target: string): string => target.slice(CROSS_FLOW_PREFIX.length)\n\nexport type FlowNodeData = {\n id: string\n type: FlowNodeType\n contextKey?: string\n questionType?: FlowQuestionType\n question?: string\n options?: [string, string][]\n actionKind?: FlowActionKind\n // Parâmetros arbitrários que o nó carrega para o handler registrado em `actionKind`. O pacote\n // nunca os interpreta — é o que permite um nó de ação ser configurado pelo editor sem que o\n // vocabulário do produto (o antigo `simulationTemplate`) vaze para dentro do contrato.\n actionParams?: Record<string, unknown>\n directMessage?: string\n fallbackMessage?: string\n conditionContextKey?: string\n conditionOperator?: FlowConditionOperator\n conditionValue?: string\n position?: { x: number; y: number }\n next?: FlowNodeNext\n}\n\nexport interface FlowGraphData {\n key: string\n label: string\n startNodeId: string\n version: number\n nodes: Record<string, FlowNodeData>\n}\n\nexport interface FlowGraphSummary {\n key: string\n label: string\n nodeCount: number\n showInMenu: boolean\n menuOptionLabel?: string\n updatedAt: string\n}\n\n// Retorno de GetLiveFlowPositions (T4.2) — quantas sessões ativas estão em cada nó agora,\n// usado pelo editor para desenhar o \"liveCount\" nos cards (FlowNodeCardData.liveCount).\nexport interface LiveFlowPosition {\n flowKey: string\n nodeId: string\n count: number\n}\n\n// Validação de runtime do grafo. O `nodes` é um jsonb que entrou pelo editor (dado de origem\n// cliente) e sai do banco como `unknown` — sem parse, um grafo malformado só se manifestaria\n// como comportamento estranho lá dentro do interpretador, longe da causa.\n//\n// Permissivo de propósito em dois pontos: `actionKind` é string aberta (o host registra os\n// seus) e `.passthrough()` deixa passar campos extras — um grafo salvo por uma versão mais nova\n// do editor não pode ficar irrecuperável numa versão mais antiga do módulo.\nexport const flowNodeNextSchema = z.union([\n z.string(),\n z.object({ byAnswer: z.record(z.string(), z.string()), default: z.string() }),\n])\n\nexport const flowNodeDataSchema = z\n .object({\n id: z.string(),\n type: z.enum(['question', 'entrada_choice', 'action', 'menu', 'condition']),\n contextKey: z.string().optional(),\n questionType: z.enum(['text', 'money', 'date', 'int', 'cpf', 'choice']).optional(),\n question: z.string().optional(),\n options: z.array(z.tuple([z.string(), z.string()])).optional(),\n actionKind: z.string().optional(),\n actionParams: z.record(z.string(), z.unknown()).optional(),\n directMessage: z.string().optional(),\n fallbackMessage: z.string().optional(),\n conditionContextKey: z.string().optional(),\n conditionOperator: z.enum(['>', '>=', '<', '<=', '==', '!=', 'contains']).optional(),\n conditionValue: z.string().optional(),\n position: z.object({ x: z.number(), y: z.number() }).optional(),\n next: flowNodeNextSchema.optional(),\n })\n .passthrough()\n\nexport const flowGraphNodesSchema = z.record(z.string(), flowNodeDataSchema)\n","// Hierarquia de erros do módulo — não depende do framework de erros do host (nenhum DomainError\n// importado); o host mapeia estes para o seu próprio formato de resposta no exception filter.\nexport class MetaWhatsAppError extends Error {\n constructor(\n message: string,\n public readonly statusCode: number,\n public readonly code: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message)\n this.name = 'MetaWhatsAppError'\n }\n}\n\nexport const META_WHATSAPP_ERROR_CODES = {\n WINDOW_EXPIRED: 'META_WHATSAPP_WINDOW_EXPIRED',\n INVALID_SIGNATURE: 'META_WHATSAPP_INVALID_SIGNATURE',\n DUPLICATE_DELIVERY: 'META_WHATSAPP_DUPLICATE_DELIVERY',\n CONFIG_MISSING: 'META_WHATSAPP_CONFIG_MISSING',\n TEMPLATE_NOT_CONFIGURED: 'META_WHATSAPP_TEMPLATE_NOT_CONFIGURED',\n SESSION_NOT_FOUND: 'META_WHATSAPP_SESSION_NOT_FOUND',\n} as const\n\nexport class WindowExpiredError extends MetaWhatsAppError {\n constructor(public readonly hoursSinceLastMessage?: number) {\n super(\n 'Janela de 24h expirada — não é possível enviar mensagem para este contato fora de template.',\n 400,\n META_WHATSAPP_ERROR_CODES.WINDOW_EXPIRED,\n { hoursSinceLastMessage },\n )\n }\n}\n\n// Assinatura HMAC do webhook não confere — Meta ou um terceiro tentando forjar uma entrega.\nexport class InvalidWebhookSignatureError extends MetaWhatsAppError {\n constructor() {\n super('Assinatura do webhook inválida.', 401, META_WHATSAPP_ERROR_CODES.INVALID_SIGNATURE)\n }\n}\n\n// Meta reenviou uma entrega dentro da janela de replay (nonce já visto) — não é erro do\n// cliente, é comportamento esperado da Cloud API; o host deve responder 200 e ignorar.\nexport class DuplicateWebhookDeliveryError extends MetaWhatsAppError {\n constructor(nonce: string) {\n super('Entrega de webhook duplicada.', 409, META_WHATSAPP_ERROR_CODES.DUPLICATE_DELIVERY, { nonce })\n }\n}\n\nexport class ConfigMissingError extends MetaWhatsAppError {\n constructor(missingField: string) {\n super(`Configuração do WhatsApp ausente: ${missingField}.`, 503, META_WHATSAPP_ERROR_CODES.CONFIG_MISSING, {\n missingField,\n })\n }\n}\n\nexport class TemplateNotConfiguredError extends MetaWhatsAppError {\n constructor() {\n super(\n 'Nenhum template de WhatsApp configurado para reabertura de janela.',\n 503,\n META_WHATSAPP_ERROR_CODES.TEMPLATE_NOT_CONFIGURED,\n )\n }\n}\n\nexport class SessionNotFoundError extends MetaWhatsAppError {\n constructor(whatsappNumber: string) {\n super(\n `Sessão de conversa não encontrada para ${whatsappNumber}.`,\n 404,\n META_WHATSAPP_ERROR_CODES.SESSION_NOT_FOUND,\n { whatsappNumber },\n )\n }\n}\n"],"mappings":";;;;AAAA,SAASA,SAAS;AAKX,IAAMC,sBAAsBD,EAAEE,OAAO;EAC1CC,IAAIH,EAAEI,OAAM;EACZC,WAAWL,EAAEI,OAAM;EACnBE,QAAQN,EAAEI,OAAM,EAAGG,SAAQ;EAC3BC,SAASR,EAAEI,OAAM,EAAGG,SAAQ;EAC5BE,UAAUT,EAAEI,OAAM,EAAGG,SAAQ;AAC/B,CAAA;AAGO,IAAMG,4BAA4BV,EAAEE,OAAO;EAChDS,MAAMX,EAAEI,OAAM;EACdQ,cAAcZ,EAAEE,OAAO;IAAEC,IAAIH,EAAEI,OAAM;IAAIS,OAAOb,EAAEI,OAAM;EAAG,CAAA,EAAGG,SAAQ;EACtEO,YAAYd,EAAEE,OAAO;IAAEC,IAAIH,EAAEI,OAAM;IAAIS,OAAOb,EAAEI,OAAM;EAAG,CAAA,EAAGG,SAAQ;AACtE,CAAA;AAGO,IAAMQ,sBAAsBf,EAAEE,OAAO;EAC1Cc,YAAYhB,EAAEI,OAAM;EACpBa,MAAMjB,EAAEI,OAAM,EAAGG,SAAQ;EACzBW,eAAelB,EAAEmB,MACfnB,EAAEE,OAAO;IACPkB,qBAAqBpB,EAAEI,OAAM;IAC7BiB,UAAUrB,EAAEsB,OAAM;IAClBC,YAAYvB,EAAEsB,OAAM;IACpBE,UAAUxB,EAAEI,OAAM;EACpB,CAAA,CAAA;AAEJ,CAAA;AAGO,IAAMqB,wBAAwBzB,EAAEE,OAAO;EAC5CC,IAAIH,EAAEI,OAAM;EACZsB,MAAM1B,EAAEI,OAAM;EACdO,MAAMX,EAAEI,OAAM;EACda,MAAMjB,EAAEE,OAAO;IAAEyB,MAAM3B,EAAEI,OAAM;EAAG,CAAA,EAAGG,SAAQ;EAC7CqB,OAAO3B,oBAAoBM,SAAQ;EACnCsB,OAAO5B,oBAAoBM,SAAQ;EACnCuB,OAAO7B,oBAAoBM,SAAQ;EACnCwB,UAAU9B,oBAAoBM,SAAQ;EACtCyB,SAAS/B,oBAAoBM,SAAQ;EACrC0B,aAAavB,0BAA0BH,SAAQ;;EAE/C2B,OAAOnB,oBAAoBR,SAAQ;;EAEnC4B,SAASnC,EACNE,OAAO;IACNwB,MAAM1B,EAAEI,OAAM,EAAGG,SAAQ;IACzBJ,IAAIH,EAAEI,OAAM,EAAGG,SAAQ;IACvB6B,kBAAkBpC,EAAEE,OAAO;MAAEc,YAAYhB,EAAEI,OAAM;MAAIgB,qBAAqBpB,EAAEI,OAAM;IAAG,CAAA,EAAGG,SAAQ;EAClG,CAAA,EACCA,SAAQ;EACX8B,WAAWrC,EAAEI,OAAM;AACrB,CAAA;AAGO,IAAMkC,4BAA4BtC,EAAEE,OAAO;EAChDC,IAAIH,EAAEI,OAAM;EACZsB,MAAM1B,EAAEI,OAAM;EACdiC,WAAWrC,EAAEI,OAAM;EACnBO,MAAMX,EAAEI,OAAM;AAChB,CAAA;AAGO,IAAMmC,8BAA8BvC,EAAEwC,KAAK;EAAC;EAAQ;EAAa;EAAQ;CAAS;AAGlF,IAAMC,uBAAuBzC,EAAEE,OAAO;EAC3CC,IAAIH,EAAEI,OAAM;EACZsC,QAAQH;EACRF,WAAWrC,EAAEI,OAAM;EACnBuC,cAAc3C,EAAEI,OAAM,EAAGG,SAAQ;AACnC,CAAA;AAGO,IAAMqC,+BAA+B5C,EAAEE,OAAO;EACnDA,QAAQF,EAAEI,OAAM;EAChByC,OAAO7C,EAAEmB,MACPnB,EAAEE,OAAO;IACPC,IAAIH,EAAEI,OAAM;IACZ0C,SAAS9C,EAAEmB,MACTnB,EAAEE,OAAO;MACP6C,OAAO/C,EAAEE,OAAO;QACd8C,mBAAmBhD,EAAEI,OAAM;QAC3B6C,UAAUjD,EAAEmB,MAAMM,qBAAAA,EAAuBlB,SAAQ;QACjD2C,gBAAgBlD,EAAEmB,MAAMmB,yBAAAA,EAA2B/B,SAAQ;QAC3D4C,UAAUnD,EAAEmB,MAAMsB,oBAAAA,EAAsBlC,SAAQ;QAChD6C,UAAUpD,EAAEE,OAAO;UAAEmD,sBAAsBrD,EAAEI,OAAM;UAAIkD,iBAAiBtD,EAAEI,OAAM;QAAG,CAAA,EAAGG,SAAQ;MAChG,CAAA;IACF,CAAA,CAAA;EAEJ,CAAA,CAAA;AAEJ,CAAA;;;AC5FA,SAASgD,KAAAA,UAAS;AAUX,IAAMC,oBAAoB;AAC1B,IAAMC,oBAAoB,wBAACC,WAA4BA,OAAOC,WAAWH,iBAAAA,GAA/C;AAC1B,IAAMI,eAAe,wBAACF,WAA2BA,OAAOG,MAAML,kBAAkBM,MAAM,GAAjE;AAuDrB,IAAMC,qBAAqBC,GAAEC,MAAM;EACxCD,GAAEE,OAAM;EACRF,GAAEG,OAAO;IAAEC,UAAUJ,GAAEK,OAAOL,GAAEE,OAAM,GAAIF,GAAEE,OAAM,CAAA;IAAKI,SAASN,GAAEE,OAAM;EAAG,CAAA;CAC5E;AAEM,IAAMK,qBAAqBP,GAC/BG,OAAO;EACNK,IAAIR,GAAEE,OAAM;EACZO,MAAMT,GAAEU,KAAK;IAAC;IAAY;IAAkB;IAAU;IAAQ;GAAY;EAC1EC,YAAYX,GAAEE,OAAM,EAAGU,SAAQ;EAC/BC,cAAcb,GAAEU,KAAK;IAAC;IAAQ;IAAS;IAAQ;IAAO;IAAO;GAAS,EAAEE,SAAQ;EAChFE,UAAUd,GAAEE,OAAM,EAAGU,SAAQ;EAC7BG,SAASf,GAAEgB,MAAMhB,GAAEiB,MAAM;IAACjB,GAAEE,OAAM;IAAIF,GAAEE,OAAM;GAAG,CAAA,EAAGU,SAAQ;EAC5DM,YAAYlB,GAAEE,OAAM,EAAGU,SAAQ;EAC/BO,cAAcnB,GAAEK,OAAOL,GAAEE,OAAM,GAAIF,GAAEoB,QAAO,CAAA,EAAIR,SAAQ;EACxDS,eAAerB,GAAEE,OAAM,EAAGU,SAAQ;EAClCU,iBAAiBtB,GAAEE,OAAM,EAAGU,SAAQ;EACpCW,qBAAqBvB,GAAEE,OAAM,EAAGU,SAAQ;EACxCY,mBAAmBxB,GAAEU,KAAK;IAAC;IAAK;IAAM;IAAK;IAAM;IAAM;IAAM;GAAW,EAAEE,SAAQ;EAClFa,gBAAgBzB,GAAEE,OAAM,EAAGU,SAAQ;EACnCc,UAAU1B,GAAEG,OAAO;IAAEwB,GAAG3B,GAAE4B,OAAM;IAAIC,GAAG7B,GAAE4B,OAAM;EAAG,CAAA,EAAGhB,SAAQ;EAC7DkB,MAAM/B,mBAAmBa,SAAQ;AACnC,CAAA,EACCmB,YAAW;AAEP,IAAMC,uBAAuBhC,GAAEK,OAAOL,GAAEE,OAAM,GAAIK,kBAAAA;;;AC/FlD,IAAM0B,oBAAN,cAAgCC,MAAAA;EAFvC,OAEuCA;;;;;;EACrC,YACEC,SACgBC,YACAC,MACAC,SAChB;AACA,UAAMH,OAAAA,GAAAA,KAJUC,aAAAA,YAAAA,KACAC,OAAAA,MAAAA,KACAC,UAAAA;AAGhB,SAAKC,OAAO;EACd;AACF;AAEO,IAAMC,4BAA4B;EACvCC,gBAAgB;EAChBC,mBAAmB;EACnBC,oBAAoB;EACpBC,gBAAgB;EAChBC,yBAAyB;EACzBC,mBAAmB;AACrB;AAEO,IAAMC,qBAAN,cAAiCd,kBAAAA;EAvBxC,OAuBwCA;;;;EACtC,YAA4Be,uBAAgC;AAC1D,UACE,6GACA,KACAR,0BAA0BC,gBAC1B;MAAEO;IAAsB,CAAA,GAAA,KALAA,wBAAAA;EAO5B;AACF;AAGO,IAAMC,+BAAN,cAA2ChB,kBAAAA;EAnClD,OAmCkDA;;;EAChD,cAAc;AACZ,UAAM,sCAAmC,KAAKO,0BAA0BE,iBAAiB;EAC3F;AACF;AAIO,IAAMQ,gCAAN,cAA4CjB,kBAAAA;EA3CnD,OA2CmDA;;;EACjD,YAAYkB,OAAe;AACzB,UAAM,iCAAiC,KAAKX,0BAA0BG,oBAAoB;MAAEQ;IAAM,CAAA;EACpG;AACF;AAEO,IAAMC,qBAAN,cAAiCnB,kBAAAA;EAjDxC,OAiDwCA;;;EACtC,YAAYoB,cAAsB;AAChC,UAAM,2CAAqCA,YAAAA,KAAiB,KAAKb,0BAA0BI,gBAAgB;MACzGS;IACF,CAAA;EACF;AACF;AAEO,IAAMC,6BAAN,cAAyCrB,kBAAAA;EAzDhD,OAyDgDA;;;EAC9C,cAAc;AACZ,UACE,sEACA,KACAO,0BAA0BK,uBAAuB;EAErD;AACF;AAEO,IAAMU,uBAAN,cAAmCtB,kBAAAA;EAnE1C,OAmE0CA;;;EACxC,YAAYuB,gBAAwB;AAClC,UACE,gDAA0CA,cAAAA,KAC1C,KACAhB,0BAA0BM,mBAC1B;MAAEU;IAAe,CAAA;EAErB;AACF;","names":["z","whatsAppMediaSchema","object","id","string","mime_type","sha256","optional","caption","filename","whatsAppInteractiveSchema","type","button_reply","title","list_reply","whatsAppOrderSchema","catalog_id","text","product_items","array","product_retailer_id","quantity","number","item_price","currency","whatsAppMessageSchema","from","body","image","audio","video","document","sticker","interactive","order","context","referred_product","timestamp","whatsAppMessageEchoSchema","whatsAppMessageStatusSchema","enum","whatsAppStatusSchema","status","recipient_id","whatsAppWebhookPayloadSchema","entry","changes","value","messaging_product","messages","message_echoes","statuses","metadata","display_phone_number","phone_number_id","z","CROSS_FLOW_PREFIX","isCrossFlowTarget","target","startsWith","crossFlowKey","slice","length","flowNodeNextSchema","z","union","string","object","byAnswer","record","default","flowNodeDataSchema","id","type","enum","contextKey","optional","questionType","question","options","array","tuple","actionKind","actionParams","unknown","directMessage","fallbackMessage","conditionContextKey","conditionOperator","conditionValue","position","x","number","y","next","passthrough","flowGraphNodesSchema","MetaWhatsAppError","Error","message","statusCode","code","details","name","META_WHATSAPP_ERROR_CODES","WINDOW_EXPIRED","INVALID_SIGNATURE","DUPLICATE_DELIVERY","CONFIG_MISSING","TEMPLATE_NOT_CONFIGURED","SESSION_NOT_FOUND","WindowExpiredError","hoursSinceLastMessage","InvalidWebhookSignatureError","DuplicateWebhookDeliveryError","nonce","ConfigMissingError","missingField","TemplateNotConfiguredError","SessionNotFoundError","whatsappNumber"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adatechnology/meta-whatsapp-contracts",
|
|
3
|
-
"version": "0.2.0-rc.
|
|
3
|
+
"version": "0.2.0-rc.5",
|
|
4
4
|
"description": "Shared types, zod schemas, and port interfaces for the meta-whatsapp trio (contracts only — no runtime behavior)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|