@neetru/sdk 3.1.0 → 3.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/dist/auth.cjs +159 -15
  2. package/dist/auth.cjs.map +1 -1
  3. package/dist/auth.d.cts +1 -1
  4. package/dist/auth.d.ts +1 -1
  5. package/dist/auth.mjs +159 -15
  6. package/dist/auth.mjs.map +1 -1
  7. package/dist/catalog.cjs +50 -2
  8. package/dist/catalog.cjs.map +1 -1
  9. package/dist/catalog.d.cts +1 -1
  10. package/dist/catalog.d.ts +1 -1
  11. package/dist/catalog.mjs +50 -2
  12. package/dist/catalog.mjs.map +1 -1
  13. package/dist/checkout.cjs +52 -3
  14. package/dist/checkout.cjs.map +1 -1
  15. package/dist/checkout.d.cts +1 -1
  16. package/dist/checkout.d.ts +1 -1
  17. package/dist/checkout.mjs +52 -3
  18. package/dist/checkout.mjs.map +1 -1
  19. package/dist/db-react.cjs +3 -1
  20. package/dist/db-react.cjs.map +1 -1
  21. package/dist/db-react.d.cts +1 -1
  22. package/dist/db-react.d.ts +1 -1
  23. package/dist/db-react.mjs +3 -1
  24. package/dist/db-react.mjs.map +1 -1
  25. package/dist/db.cjs +93 -6
  26. package/dist/db.cjs.map +1 -1
  27. package/dist/db.d.cts +1 -1
  28. package/dist/db.d.ts +1 -1
  29. package/dist/db.mjs +93 -6
  30. package/dist/db.mjs.map +1 -1
  31. package/dist/entitlements.cjs +50 -2
  32. package/dist/entitlements.cjs.map +1 -1
  33. package/dist/entitlements.d.cts +1 -1
  34. package/dist/entitlements.d.ts +1 -1
  35. package/dist/entitlements.mjs +50 -2
  36. package/dist/entitlements.mjs.map +1 -1
  37. package/dist/errors.cjs.map +1 -1
  38. package/dist/errors.d.cts +3 -1
  39. package/dist/errors.d.ts +3 -1
  40. package/dist/errors.mjs.map +1 -1
  41. package/dist/firestore-compat.cjs +14 -2
  42. package/dist/firestore-compat.cjs.map +1 -1
  43. package/dist/firestore-compat.d.cts +28 -3
  44. package/dist/firestore-compat.d.ts +28 -3
  45. package/dist/firestore-compat.mjs +14 -2
  46. package/dist/firestore-compat.mjs.map +1 -1
  47. package/dist/index.cjs +195 -16
  48. package/dist/index.cjs.map +1 -1
  49. package/dist/index.d.cts +9 -3
  50. package/dist/index.d.ts +9 -3
  51. package/dist/index.mjs +194 -17
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/mocks.cjs.map +1 -1
  54. package/dist/mocks.d.cts +1 -1
  55. package/dist/mocks.d.ts +1 -1
  56. package/dist/mocks.mjs.map +1 -1
  57. package/dist/notifications.cjs +50 -2
  58. package/dist/notifications.cjs.map +1 -1
  59. package/dist/notifications.d.cts +1 -1
  60. package/dist/notifications.d.ts +1 -1
  61. package/dist/notifications.mjs +50 -2
  62. package/dist/notifications.mjs.map +1 -1
  63. package/dist/react.cjs +2 -3
  64. package/dist/react.cjs.map +1 -1
  65. package/dist/react.d.cts +22 -4
  66. package/dist/react.d.ts +22 -4
  67. package/dist/react.mjs +2 -3
  68. package/dist/react.mjs.map +1 -1
  69. package/dist/support.cjs +50 -2
  70. package/dist/support.cjs.map +1 -1
  71. package/dist/support.d.cts +1 -1
  72. package/dist/support.d.ts +1 -1
  73. package/dist/support.mjs +50 -2
  74. package/dist/support.mjs.map +1 -1
  75. package/dist/telemetry.cjs +65 -4
  76. package/dist/telemetry.cjs.map +1 -1
  77. package/dist/telemetry.d.cts +1 -1
  78. package/dist/telemetry.d.ts +1 -1
  79. package/dist/telemetry.mjs +65 -4
  80. package/dist/telemetry.mjs.map +1 -1
  81. package/dist/{types-BRv8wBxX.d.ts → types-B3XFHD4A.d.ts} +60 -1
  82. package/dist/{types-nwErcRX8.d.cts → types-DePdSU3P.d.cts} +60 -1
  83. package/dist/usage.cjs +50 -2
  84. package/dist/usage.cjs.map +1 -1
  85. package/dist/usage.d.cts +1 -1
  86. package/dist/usage.d.ts +1 -1
  87. package/dist/usage.mjs +50 -2
  88. package/dist/usage.mjs.map +1 -1
  89. package/dist/webhooks.cjs +83 -2
  90. package/dist/webhooks.cjs.map +1 -1
  91. package/dist/webhooks.d.cts +1 -1
  92. package/dist/webhooks.d.ts +1 -1
  93. package/dist/webhooks.mjs +83 -3
  94. package/dist/webhooks.mjs.map +1 -1
  95. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/http.ts","../src/validators.ts","../src/notifications.ts"],"names":["err","message"],"mappings":"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","file":"notifications.cjs","sourcesContent":["/**\r\n * Erros tipados do SDK.\r\n *\r\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\r\n * por `.code` (string estável) sem parsing de message.\r\n */\r\n\r\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\r\nexport type NeetruErrorCode =\r\n | 'invalid_config'\r\n | 'missing_api_key'\r\n | 'unauthorized'\r\n | 'forbidden'\r\n | 'not_found'\r\n | 'rate_limited'\r\n | 'validation_failed'\r\n | 'network_error'\r\n | 'invalid_response'\r\n | 'server_error'\r\n | 'token_expired'\r\n | 'token_invalid_signature'\r\n | 'token_invalid_audience'\r\n | 'token_invalid_issuer'\r\n /** 3.0: runtime não expõe API necessária (ex: WebCrypto ausente). */\r\n | 'runtime_unsupported'\r\n | 'unknown';\r\n\r\n/**\r\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\r\n *\r\n * @example\r\n * ```ts\r\n * try { await client.catalog.list(); }\r\n * catch (e) {\r\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\r\n * }\r\n * ```\r\n */\r\nexport class NeetruError extends Error {\r\n public readonly code: NeetruErrorCode | string;\r\n public readonly status?: number;\r\n public readonly requestId?: string;\r\n\r\n constructor(\r\n code: NeetruErrorCode | string,\r\n message: string,\r\n status?: number,\r\n requestId?: string,\r\n ) {\r\n super(message);\r\n this.name = 'NeetruError';\r\n this.code = code;\r\n this.status = status;\r\n this.requestId = requestId;\r\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\r\n Object.setPrototypeOf(this, NeetruError.prototype);\r\n }\r\n}\r\n","/**\n * Idempotency-Key helper — gera UUID v4 cripto-seguro para identificar\n * mutations não-idempotentes (`usage.report`, `support.createTicket`,\n * `notifications.send`, `webhooks.test`).\n *\n * Estratégia 3.0:\n * - SDK gera UUID v4 por chamada via `randomUUID()` (WebCrypto.subtle não\n * necessário aqui — `crypto.randomUUID()` está em Node 14.17+ e em todos\n * os browsers/Edge runtimes modernos).\n * - Header `Idempotency-Key: <uuid>` é injetado pelo `httpRequest` quando\n * `opts.idempotencyKey === true` OU caller passa explicit `opts.idempotencyKeyValue`.\n * - Core dedup em coleção `usage_idempotency_keys/{key}` TTL 24h (vide\n * `docs/CORE_CHANGES_REQUIRED.md` §2). Se Core ainda não dedupa, o header\n * é benign (ignorado).\n *\n * Defesa em camadas: combinado com `retries: 0` em POSTs (vide http.ts), o\n * risco de double-write em transientes vai pra zero.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Gera UUID v4 criptograficamente seguro. Universal: Node 14.17+, browsers\n * modernos, Edge runtimes (Workers/Vercel Edge/Cloudflare).\n *\n * Fallback puro-JS removido em 3.0 — `crypto.randomUUID()` é ubíquo desde\n * 2022. Se runtime não tem, lança `NeetruError('runtime_unsupported')`\n * (consumer deve polyfillar).\n *\n * **L-01 fix (Opus review 2026-05-27):** antes lançava `Error` cru, que\n * não era pego por `catch (err) { if (err instanceof NeetruError) ... }`\n * dos consumers. Agora throw canonical.\n *\n * @throws NeetruError('runtime_unsupported') se `crypto.randomUUID` não disponível.\n */\nexport function generateIdempotencyKey(): string {\n // WebCrypto (browser/Edge) e Node 14.17+ expõem `crypto.randomUUID()`.\n // Node anterior precisa de `node:crypto` mas SDK 3.0 exige Node ≥20 (vide engines).\n const cryptoObj: { randomUUID?: () => string } | undefined =\n typeof globalThis !== 'undefined' && 'crypto' in globalThis\n ? (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n : undefined;\n if (cryptoObj && typeof cryptoObj.randomUUID === 'function') {\n return cryptoObj.randomUUID();\n }\n throw new NeetruError(\n 'runtime_unsupported',\n 'crypto.randomUUID not available in this runtime. SDK 3.0 requires Node ≥20 or modern browser/Edge.',\n );\n}\n\n/** Regex UUID v4 — validação para uso interno. */\nexport const UUID_V4_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n","/**\r\n * HTTP transport interno do SDK.\r\n *\r\n * Responsabilidades:\r\n * - Construir URL absoluta a partir de `baseUrl` + path\r\n * - Injetar Bearer token quando `requireAuth=true`\r\n * - Mapear status HTTP → `NeetruError` com `code` estável\r\n * - Parse defensivo de JSON (não lança em body vazio em 204)\r\n * - Retry/backoff exponencial em `rate_limited` (429), `server_error` (5xx)\r\n * e `network_error` (timeout/falha de rede). Honra `Retry-After` quando\r\n * presente.\r\n *\r\n * Política de retries (mudança breaking 3.0):\r\n * - GET/HEAD: default 2 retries (3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: default **0 retries** — mutations podem duplicar\r\n * side effects (ex: `usage.report` incrementa contador). Caller pode\r\n * reativar passando `retries: N` explicitamente ou usar `Idempotency-Key`\r\n * header (gerado automaticamente se `opts.idempotencyKey=true`).\r\n *\r\n * Idempotency-Key (3.0):\r\n * - `opts.idempotencyKey === true` → SDK gera UUID v4 e injeta header.\r\n * - `opts.idempotencyKey === 'uuid-string'` → usa o valor passado.\r\n * - Caller mantém retentos client-side se quiser; Core dedup serverside\r\n * (vide `docs/CORE_CHANGES_REQUIRED.md` §2).\r\n */\r\nimport { NeetruError, type NeetruErrorCode } from './errors';\r\nimport { generateIdempotencyKey } from './idempotency';\r\nimport type { ResolvedConfig } from './types';\r\n\r\n/** Opções da request HTTP. */\r\nexport interface HttpRequestOptions {\r\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\r\n /** Path relativo (ex: `/api/v1/cli/catalog`). Concatenado a `baseUrl`. */\r\n path: string;\r\n /** Query string params (chave → valor primitivo). Valores `undefined` ignorados. */\r\n query?: Record<string, string | number | boolean | undefined>;\r\n /** Body JSON-serializável. Ignorado em GET/DELETE. */\r\n body?: unknown;\r\n /**\r\n * Se true, injeta `Authorization: Bearer <apiKey>`. Lança `missing_api_key`\r\n * se config.apiKey ausente. Default false.\r\n */\r\n requireAuth?: boolean;\r\n /** Cabeçalhos extras. */\r\n headers?: Record<string, string>;\r\n /**\r\n * Número de retries em códigos transientes (`rate_limited`, `server_error`,\r\n * `network_error`).\r\n *\r\n * Default (3.0):\r\n * - GET/HEAD: 2 (= 3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: 0 — mutations podem duplicar side effects.\r\n *\r\n * Caller pode reativar passando explicitamente: `retries: 2`.\r\n */\r\n retries?: number;\r\n /**\r\n * Injeta `Idempotency-Key` header pra dedup serverside (3.0):\r\n * - `true` → SDK gera UUID v4 cripto-seguro automaticamente.\r\n * - string → usa o valor passado (deve ser UUID v4).\r\n * - `undefined`/`false` → sem header.\r\n */\r\n idempotencyKey?: boolean | string;\r\n}\r\n\r\nconst DEFAULT_RETRIES_READ = 2;\r\nconst DEFAULT_RETRIES_WRITE = 0;\r\nconst READ_METHODS = new Set(['GET', 'HEAD']);\r\nconst RETRYABLE_CODES = new Set<NeetruErrorCode>([\r\n 'rate_limited',\r\n 'server_error',\r\n 'network_error',\r\n]);\r\n\r\n/** Backoff exponencial com jitter ±20%. attempt: 0=primeira, 1=primeiro retry, ... */\r\nfunction backoffMs(attempt: number): number {\r\n const base = 200 * Math.pow(4, attempt); // 200ms, 800ms, 3.2s, ...\r\n const jitter = base * 0.2 * (Math.random() * 2 - 1);\r\n return Math.max(50, Math.round(base + jitter));\r\n}\r\n\r\n/**\r\n * Honra `Retry-After` header (segundos ou HTTP-date). Retorna ms ou null se\r\n * inválido. RFC 9110 §10.2.3.\r\n */\r\nfunction parseRetryAfter(value: string | null): number | null {\r\n if (!value) return null;\r\n const secs = Number(value);\r\n if (Number.isFinite(secs) && secs >= 0) return Math.round(secs * 1000);\r\n const dateMs = Date.parse(value);\r\n if (Number.isFinite(dateMs)) {\r\n const delta = dateMs - Date.now();\r\n if (delta > 0) return delta;\r\n }\r\n return null;\r\n}\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/** Mapeamento status → code estável do NeetruError. */\r\nfunction statusToCode(status: number): NeetruErrorCode {\r\n if (status === 401) return 'unauthorized';\r\n if (status === 403) return 'forbidden';\r\n if (status === 404) return 'not_found';\r\n if (status === 422 || status === 400) return 'validation_failed';\r\n if (status === 429) return 'rate_limited';\r\n if (status >= 500) return 'server_error';\r\n return 'unknown';\r\n}\r\n\r\nfunction buildUrl(baseUrl: string, path: string, query?: HttpRequestOptions['query']): string {\r\n // Trim trailing slash em base e leading em path pra evitar `//`.\r\n const base = baseUrl.replace(/\\/+$/, '');\r\n const p = path.startsWith('/') ? path : `/${path}`;\r\n const url = new URL(`${base}${p}`);\r\n if (query) {\r\n for (const [k, v] of Object.entries(query)) {\r\n if (v === undefined) continue;\r\n url.searchParams.set(k, String(v));\r\n }\r\n }\r\n return url.toString();\r\n}\r\n\r\n/** Parse JSON defensivo — retorna `undefined` em body vazio. */\r\nasync function safeJson(res: Response): Promise<unknown> {\r\n const text = await res.text();\r\n if (!text) return undefined;\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Executa request HTTP. Em sucesso retorna body parseado; em erro lança\r\n * `NeetruError` com `code` derivado do status. Aplica retry/backoff\r\n * automático em códigos transientes (rate_limited/server_error/network_error)\r\n * conforme `opts.retries` (default 2 = 3 tentativas).\r\n */\r\nexport async function httpRequest<T>(\r\n config: ResolvedConfig,\r\n opts: HttpRequestOptions,\r\n): Promise<T> {\r\n const method = opts.method ?? 'GET';\r\n const url = buildUrl(config.baseUrl, opts.path, opts.query);\r\n // Default por método: reads tentam 2x, writes 0x. Caller override sempre vence.\r\n const defaultRetries = READ_METHODS.has(method)\r\n ? DEFAULT_RETRIES_READ\r\n : DEFAULT_RETRIES_WRITE;\r\n const maxRetries = opts.retries ?? defaultRetries;\r\n\r\n const headers: Record<string, string> = {\r\n accept: 'application/json',\r\n ...opts.headers,\r\n };\r\n\r\n if (opts.requireAuth) {\r\n if (!config.apiKey) {\r\n throw new NeetruError(\r\n 'missing_api_key',\r\n 'This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.',\r\n );\r\n }\r\n headers.authorization = `Bearer ${config.apiKey}`;\r\n }\r\n\r\n // Idempotency-Key: gerado por chamada se solicitado. UUID v4 cripto-seguro.\r\n if (opts.idempotencyKey) {\r\n const key =\r\n typeof opts.idempotencyKey === 'string'\r\n ? opts.idempotencyKey\r\n : generateIdempotencyKey();\r\n headers['idempotency-key'] = key;\r\n }\r\n\r\n // Body só é serializado uma vez — reusado entre tentativas.\r\n const bodyString =\r\n opts.body !== undefined && method !== 'GET' && method !== 'DELETE'\r\n ? JSON.stringify(opts.body)\r\n : undefined;\r\n if (bodyString !== undefined) {\r\n headers['content-type'] = 'application/json';\r\n }\r\n\r\n let lastError: NeetruError | null = null;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n const init: RequestInit = { method, headers };\r\n if (bodyString !== undefined) init.body = bodyString;\r\n // BUG-020 fix (2026-05-13): timeout default 30s. AbortSignal.timeout\r\n // requer Node 18+ ou browsers recentes.\r\n init.signal = AbortSignal.timeout(30_000);\r\n\r\n let res: Response;\r\n try {\r\n res = await config.fetch(url, init);\r\n } catch (err) {\r\n const message =\r\n err instanceof DOMException && err.name === 'TimeoutError'\r\n ? 'Network error: timeout after 30s'\r\n : `Network error: ${err instanceof Error ? err.message : 'fetch failed'}`;\r\n lastError = new NeetruError('network_error', message);\r\n if (attempt < maxRetries) {\r\n await sleep(backoffMs(attempt));\r\n continue;\r\n }\r\n throw lastError;\r\n }\r\n\r\n const requestId =\r\n res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined;\r\n\r\n if (res.ok) {\r\n const parsed = await safeJson(res);\r\n return parsed as T;\r\n }\r\n\r\n const body = (await safeJson(res)) as\r\n | { error?: { code?: string; message?: string } | string }\r\n | undefined;\r\n let code: string = statusToCode(res.status);\r\n let message = `HTTP ${res.status}`;\r\n if (body && typeof body === 'object' && 'error' in body) {\r\n const errField = body.error;\r\n if (typeof errField === 'string') {\r\n message = errField;\r\n } else if (errField && typeof errField === 'object') {\r\n if (typeof errField.code === 'string') code = errField.code;\r\n if (typeof errField.message === 'string') message = errField.message;\r\n }\r\n }\r\n const err = new NeetruError(code, message, res.status, requestId);\r\n lastError = err;\r\n\r\n const isRetryable = RETRYABLE_CODES.has(code as NeetruErrorCode);\r\n if (isRetryable && attempt < maxRetries) {\r\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'));\r\n const delay = retryAfter ?? backoffMs(attempt);\r\n await sleep(delay);\r\n continue;\r\n }\r\n throw err;\r\n }\r\n\r\n // Unreachable — loop sempre retorna ou lança. Safety net.\r\n throw lastError ?? new NeetruError('unknown', 'unexpected httpRequest exit');\r\n}\r\n","/**\n * Validators centralizados pra inputs do SDK que precisam casar com\n * regex do Core.\n *\n * **M-03 fix (Opus review 2026-05-27):** o Core rejeita productId que\n * não bate `/^[a-z0-9][a-z0-9_-]{0,62}$/` com 400 `validation_failed`.\n * O SDK não pré-validava — consumer recebia erro só em runtime de\n * produção, depois do round-trip de rede. Agora SDK throws localmente\n * antes do fetch.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Regex canonical de IDs no Neetru Core (productId, tenantId, etc).\n * Espelha `SDK_ID_RE` em `neetru_core/src/lib/schemas/sdk.ts`.\n */\nexport const SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/;\n\n/**\n * Throws `NeetruError('validation_failed')` se `value` não bater no\n * formato canonical.\n *\n * @example\n * ```ts\n * assertValidSdkId('productId', 'gestovendas'); // ok\n * assertValidSdkId('productId', 'GestoVendas'); // throws\n * ```\n */\nexport function assertValidSdkId(field: string, value: string): void {\n if (typeof value !== 'string' || !SDK_ID_RE.test(value)) {\n throw new NeetruError(\n 'validation_failed',\n `${field} must match ${SDK_ID_RE.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`,\n );\n }\n}\n","/**\r\n * Notifications namespace (v1.2) — produtos SaaS enviam notificações in-app\r\n * pros SEUS usuários (distinto das `notifications/` staff-only do Core).\r\n *\r\n * Caso típico: produto gestovendas notifica usuário \"Pedido #X recebido\" no\r\n * portal sem precisar manter a própria coleção Firestore.\r\n *\r\n * Schema isolado por produto: `product_user_notifications/{productId}/{notifId}`.\r\n * Owner Neetru não vê o conteúdo (privacidade do produto), mas o Core\r\n * armazena + serve a leitura. Produto pode também listar via SDK.\r\n *\r\n * Endpoints REST (em prod):\r\n * - `POST /api/sdk/v1/notifications` — produto envia\r\n * - `GET /api/sdk/v1/notifications/user/{userId}` — produto lista do user\r\n * - `POST /api/sdk/v1/notifications/{id}/read` — user marca lida (proxy)\r\n * - `POST /api/sdk/v1/notifications/{id}/dismiss` — user descarta (proxy)\r\n *\r\n * Severidade canônica: `info | success | warning | error`.\r\n *\r\n * Mock em `NEETRU_ENV=dev`: in-memory.\r\n */\r\nimport { NeetruError } from './errors';\r\nimport { httpRequest } from './http';\r\nimport { assertValidSdkId } from './validators';\r\nimport type { ResolvedConfig } from './types';\r\n\r\nexport type ProductNotificationSeverity =\r\n | 'info'\r\n | 'success'\r\n | 'warning'\r\n | 'error';\r\n\r\nexport interface ProductNotification {\r\n id: string;\r\n /** UID do usuário final (do produto, não staff Neetru). */\r\n userId: string;\r\n /** Identificador semântico do evento (ex: `order.received`). */\r\n kind: string;\r\n severity: ProductNotificationSeverity;\r\n title: string;\r\n body?: string;\r\n /** Link opcional pra ação. */\r\n link?: string;\r\n /** Metadata livre (serializável). */\r\n metadata?: Record<string, string | number | boolean | null>;\r\n createdAt: string;\r\n /** ISO quando user marcou lida. */\r\n readAt?: string;\r\n /** ISO quando user descartou. */\r\n dismissedAt?: string;\r\n}\r\n\r\nexport interface SendNotificationInput {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório (Core valida via Zod). Default\r\n * resolve do `config.productId`; lança `validation_failed` se ausente.\r\n */\r\n productId?: string;\r\n userId: string;\r\n kind: string;\r\n title: string;\r\n severity?: ProductNotificationSeverity;\r\n body?: string;\r\n link?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n /**\r\n * Dedup — se já existir notificação com mesmo fingerprint dentro de 24h,\r\n * NÃO cria duplicata. Útil pra evitar spam quando webhook reentrega.\r\n */\r\n fingerprint?: string;\r\n}\r\n\r\nexport interface ListNotificationsOptions {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório no Core. Default resolve do\r\n * `config.productId`.\r\n */\r\n productId?: string;\r\n /** Inclui notificações dismissed (default false). */\r\n includeDismissed?: boolean;\r\n /** Filtro por unread. */\r\n onlyUnread?: boolean;\r\n /** Máx itens (default 50, máx 200). */\r\n limit?: number;\r\n}\r\n\r\n/** 3.0: scope option pra markRead/dismiss (productId obrigatório no Core). */\r\nexport interface NotificationScopeOptions {\r\n productId?: string;\r\n}\r\n\r\nexport interface NotificationsNamespace {\r\n /** Produto envia uma notificação pra um usuário do produto. */\r\n send(input: SendNotificationInput): Promise<ProductNotification>;\r\n /** Lista notificações de um usuário. */\r\n list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]>;\r\n /** Marca como lida. */\r\n markRead(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n /** Descarta. */\r\n dismiss(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n}\r\n\r\n// ─── HTTP impl ──────────────────────────────────────────────────────────────\r\n\r\nconst VALID_SEVERITIES: readonly ProductNotificationSeverity[] = [\r\n 'info',\r\n 'success',\r\n 'warning',\r\n 'error',\r\n];\r\n\r\nfunction toNotification(raw: unknown): ProductNotification {\r\n if (!raw || typeof raw !== 'object') {\r\n throw new NeetruError('invalid_response', 'Notification response is not an object');\r\n }\r\n const r = raw as Record<string, unknown>;\r\n if (typeof r.id !== 'string') {\r\n throw new NeetruError('invalid_response', 'Notification missing id');\r\n }\r\n const sev = VALID_SEVERITIES.includes(r.severity as ProductNotificationSeverity)\r\n ? (r.severity as ProductNotificationSeverity)\r\n : 'info';\r\n return {\r\n id: r.id,\r\n userId: typeof r.userId === 'string' ? r.userId : '',\r\n kind: typeof r.kind === 'string' ? r.kind : 'unknown',\r\n severity: sev,\r\n title: typeof r.title === 'string' ? r.title : '',\r\n body: typeof r.body === 'string' ? r.body : undefined,\r\n link: typeof r.link === 'string' ? r.link : undefined,\r\n metadata:\r\n r.metadata && typeof r.metadata === 'object'\r\n ? (r.metadata as Record<string, string | number | boolean | null>)\r\n : undefined,\r\n createdAt: typeof r.createdAt === 'string' ? r.createdAt : new Date().toISOString(),\r\n readAt: typeof r.readAt === 'string' ? r.readAt : undefined,\r\n dismissedAt: typeof r.dismissedAt === 'string' ? r.dismissedAt : undefined,\r\n };\r\n}\r\n\r\nfunction validateInput(input: SendNotificationInput): void {\r\n if (!input.userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n if (!input.kind) throw new NeetruError('validation_failed', 'kind obrigatório');\r\n if (!input.title) throw new NeetruError('validation_failed', 'title obrigatório');\r\n if (input.severity && !VALID_SEVERITIES.includes(input.severity)) {\r\n throw new NeetruError(\r\n 'validation_failed',\r\n `severity inválida: ${input.severity} (use ${VALID_SEVERITIES.join('|')})`,\r\n );\r\n }\r\n if (input.title.length > 200) {\r\n throw new NeetruError('validation_failed', 'title máx 200 chars');\r\n }\r\n if (input.body && input.body.length > 2000) {\r\n throw new NeetruError('validation_failed', 'body máx 2000 chars');\r\n }\r\n}\r\n\r\n/** Resolve productId fail-closed (option > input > config).\r\n *\r\n * **M-03 fix (Opus review 2026-05-27):** valida client-side contra `SDK_ID_RE`. */\r\nfunction resolveProductId(\r\n config: ResolvedConfig,\r\n ...candidates: Array<string | undefined>\r\n): string {\r\n for (const c of candidates) {\r\n if (typeof c === 'string' && c.length > 0) {\r\n assertValidSdkId('productId', c);\r\n return c;\r\n }\r\n }\r\n if (config.productId) {\r\n assertValidSdkId('productId', config.productId);\r\n return config.productId;\r\n }\r\n throw new NeetruError(\r\n 'validation_failed',\r\n 'productId required (pass to options/input or set on createNeetruClient)',\r\n );\r\n}\r\n\r\nexport function createNotificationsNamespace(\r\n config: ResolvedConfig,\r\n): NotificationsNamespace {\r\n return {\r\n async send(input) {\r\n validateInput(input);\r\n const productId = resolveProductId(config, input.productId);\r\n const body: Record<string, unknown> = {\r\n productId,\r\n userId: input.userId,\r\n kind: input.kind,\r\n title: input.title,\r\n severity: input.severity ?? 'info',\r\n };\r\n if (input.body !== undefined) body.body = input.body;\r\n if (input.link !== undefined) body.link = input.link;\r\n if (input.metadata !== undefined) body.metadata = input.metadata;\r\n if (input.fingerprint !== undefined) body.fingerprint = input.fingerprint;\r\n const raw = await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: '/api/sdk/v1/notifications',\r\n body,\r\n requireAuth: true,\r\n idempotencyKey: true,\r\n });\r\n return toNotification(raw);\r\n },\r\n async list(userId, options) {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n const query: Record<string, string | number | boolean | undefined> = {\r\n productId,\r\n };\r\n if (options?.includeDismissed) query.includeDismissed = true;\r\n if (options?.onlyUnread) query.onlyUnread = true;\r\n if (options?.limit) {\r\n query.limit = Math.min(Math.max(1, options.limit), 200);\r\n }\r\n const raw = await httpRequest<{ notifications?: unknown[] }>(config, {\r\n method: 'GET',\r\n path: `/api/sdk/v1/notifications/user/${encodeURIComponent(userId)}`,\r\n query,\r\n requireAuth: true,\r\n });\r\n const list = Array.isArray(raw?.notifications) ? raw.notifications : [];\r\n return list.map(toNotification);\r\n },\r\n async markRead(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/read`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n async dismiss(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/dismiss`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n };\r\n}\r\n\r\n// ─── Mock impl ──────────────────────────────────────────────────────────────\r\n\r\nexport class MockNotifications implements NotificationsNamespace {\r\n private notifications = new Map<string, ProductNotification>();\r\n private nextId = 1;\r\n\r\n async send(input: SendNotificationInput): Promise<ProductNotification> {\r\n validateInput(input);\r\n // Dedup por fingerprint: se já existe um com mesmo fingerprint < 24h, retorna ele.\r\n if (input.fingerprint) {\r\n const dayAgo = Date.now() - 86_400_000;\r\n for (const existing of this.notifications.values()) {\r\n const meta = existing.metadata ?? {};\r\n if (\r\n meta.fingerprint === input.fingerprint &&\r\n existing.userId === input.userId &&\r\n new Date(existing.createdAt).getTime() > dayAgo\r\n ) {\r\n return existing;\r\n }\r\n }\r\n }\r\n const id = `mock_notif_${this.nextId++}`;\r\n const notif: ProductNotification = {\r\n id,\r\n userId: input.userId,\r\n kind: input.kind,\r\n severity: input.severity ?? 'info',\r\n title: input.title,\r\n body: input.body,\r\n link: input.link,\r\n metadata: input.fingerprint\r\n ? { ...(input.metadata ?? {}), fingerprint: input.fingerprint }\r\n : input.metadata,\r\n createdAt: new Date().toISOString(),\r\n };\r\n this.notifications.set(id, notif);\r\n return notif;\r\n }\r\n\r\n async list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]> {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const limit = Math.min(Math.max(1, options?.limit ?? 50), 200);\r\n return [...this.notifications.values()]\r\n .filter((n) => n.userId === userId)\r\n .filter((n) => options?.includeDismissed || !n.dismissedAt)\r\n .filter((n) => !options?.onlyUnread || !n.readAt)\r\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt))\r\n .slice(0, limit);\r\n }\r\n\r\n async markRead(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.readAt) {\r\n n.readAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n\r\n async dismiss(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.dismissedAt) {\r\n n.dismissedAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/http.ts","../src/validators.ts","../src/notifications.ts"],"names":["err","message"],"mappings":"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","file":"notifications.cjs","sourcesContent":["/**\r\n * Erros tipados do SDK.\r\n *\r\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\r\n * por `.code` (string estável) sem parsing de message.\r\n */\r\n\r\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\r\nexport type NeetruErrorCode =\r\n | 'invalid_config'\r\n | 'missing_api_key'\r\n | 'unauthorized'\r\n | 'forbidden'\r\n | 'not_found'\r\n | 'rate_limited'\r\n | 'validation_failed'\r\n | 'network_error'\r\n | 'invalid_response'\r\n | 'server_error'\r\n | 'token_expired'\r\n | 'token_invalid_signature'\r\n | 'token_invalid_audience'\r\n | 'token_invalid_issuer'\r\n /** 3.0: runtime não expõe API necessária (ex: WebCrypto ausente). */\r\n | 'runtime_unsupported'\r\n /** HTTP 409 — colisão de idempotência ou conflito de recurso. */\r\n | 'conflict'\r\n | 'unknown';\r\n\r\n/**\r\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\r\n *\r\n * @example\r\n * ```ts\r\n * try { await client.catalog.list(); }\r\n * catch (e) {\r\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\r\n * }\r\n * ```\r\n */\r\nexport class NeetruError extends Error {\r\n public readonly code: NeetruErrorCode | string;\r\n public readonly status?: number;\r\n public readonly requestId?: string;\r\n\r\n constructor(\r\n code: NeetruErrorCode | string,\r\n message: string,\r\n status?: number,\r\n requestId?: string,\r\n ) {\r\n super(message);\r\n this.name = 'NeetruError';\r\n this.code = code;\r\n this.status = status;\r\n this.requestId = requestId;\r\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\r\n Object.setPrototypeOf(this, NeetruError.prototype);\r\n }\r\n}\r\n","/**\n * Idempotency-Key helper — gera UUID v4 cripto-seguro para identificar\n * mutations não-idempotentes (`usage.report`, `support.createTicket`,\n * `notifications.send`, `webhooks.test`).\n *\n * Estratégia 3.0:\n * - SDK gera UUID v4 por chamada via `randomUUID()` (WebCrypto.subtle não\n * necessário aqui — `crypto.randomUUID()` está em Node 14.17+ e em todos\n * os browsers/Edge runtimes modernos).\n * - Header `Idempotency-Key: <uuid>` é injetado pelo `httpRequest` quando\n * `opts.idempotencyKey === true` OU caller passa explicit `opts.idempotencyKeyValue`.\n * - Core dedup em coleção `usage_idempotency_keys/{key}` TTL 24h (vide\n * `docs/CORE_CHANGES_REQUIRED.md` §2). Se Core ainda não dedupa, o header\n * é benign (ignorado).\n *\n * Defesa em camadas: combinado com `retries: 0` em POSTs (vide http.ts), o\n * risco de double-write em transientes vai pra zero.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Gera UUID v4 criptograficamente seguro. Universal: Node 14.17+, browsers\n * modernos, Edge runtimes (Workers/Vercel Edge/Cloudflare).\n *\n * Fallback puro-JS removido em 3.0 — `crypto.randomUUID()` é ubíquo desde\n * 2022. Se runtime não tem, lança `NeetruError('runtime_unsupported')`\n * (consumer deve polyfillar).\n *\n * **L-01 fix (Opus review 2026-05-27):** antes lançava `Error` cru, que\n * não era pego por `catch (err) { if (err instanceof NeetruError) ... }`\n * dos consumers. Agora throw canonical.\n *\n * @throws NeetruError('runtime_unsupported') se `crypto.randomUUID` não disponível.\n */\nexport function generateIdempotencyKey(): string {\n // WebCrypto (browser/Edge) e Node 14.17+ expõem `crypto.randomUUID()`.\n // Node anterior precisa de `node:crypto` mas SDK 3.0 exige Node ≥20 (vide engines).\n const cryptoObj: { randomUUID?: () => string } | undefined =\n typeof globalThis !== 'undefined' && 'crypto' in globalThis\n ? (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n : undefined;\n if (cryptoObj && typeof cryptoObj.randomUUID === 'function') {\n return cryptoObj.randomUUID();\n }\n throw new NeetruError(\n 'runtime_unsupported',\n 'crypto.randomUUID not available in this runtime. SDK 3.0 requires Node ≥20 or modern browser/Edge.',\n );\n}\n\n/** Regex UUID v4 — validação para uso interno. */\nexport const UUID_V4_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n","/**\r\n * HTTP transport interno do SDK.\r\n *\r\n * Responsabilidades:\r\n * - Construir URL absoluta a partir de `baseUrl` + path\r\n * - Injetar Bearer token quando `requireAuth=true`\r\n * - Mapear status HTTP → `NeetruError` com `code` estável\r\n * - Parse defensivo de JSON (não lança em body vazio em 204)\r\n * - Retry/backoff exponencial em `rate_limited` (429), `server_error` (5xx)\r\n * e `network_error` (timeout/falha de rede). Honra `Retry-After` quando\r\n * presente.\r\n * - **Captura `X-Neetru-Version`** das respostas e emite `console.warn` quando\r\n * o Core está abaixo da versão mínima para a major do SDK.\r\n *\r\n * Política de retries (mudança breaking 3.0):\r\n * - GET/HEAD: default 2 retries (3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: default **0 retries** — mutations podem duplicar\r\n * side effects (ex: `usage.report` incrementa contador). Caller pode\r\n * reativar passando `retries: N` explicitamente ou usar `Idempotency-Key`\r\n * header (gerado automaticamente se `opts.idempotencyKey=true`).\r\n *\r\n * Idempotency-Key (3.0):\r\n * - `opts.idempotencyKey === true` → SDK gera UUID v4 e injeta header.\r\n * - `opts.idempotencyKey === 'uuid-string'` → usa o valor passado.\r\n * - Caller mantém retentos client-side se quiser; Core dedup serverside\r\n * (vide `docs/CORE_CHANGES_REQUIRED.md` §2).\r\n */\r\nimport { NeetruError, type NeetruErrorCode } from './errors';\r\nimport { generateIdempotencyKey } from './idempotency';\r\nimport type { ResolvedConfig } from './types';\r\n\r\n// ─── Compat Matrix SDK↔Core ──────────────────────────────────────────────────\r\n\r\n/**\r\n * Matriz de compatibilidade SDK major → versão mínima do Core.\r\n *\r\n * Formato do Core: CalVer `YYYY.MM.patch+revision` (ex: `2026.05.1+neetru-core-00096-79t`).\r\n * A comparação é feita apenas nas partes `YYYY.MM.patch` (prefixo antes de `+`).\r\n *\r\n * Quando o Core reporta `X-Neetru-Version` abaixo do mínimo para a SDK major\r\n * corrente, o SDK emite `console.warn` uma única vez por sessão de processo.\r\n *\r\n * Atualize esta tabela a cada major de SDK.\r\n */\r\nconst COMPAT_MATRIX: Record<number, string> = {\r\n // SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,\r\n // runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)\r\n 3: '2026.05.1',\r\n};\r\n\r\n/** CalVer sem sufixo `+revision`. Ex: `2026.05.1+abc` → `2026.05.1`. */\r\nfunction stripRevision(v: string): string {\r\n return v.split('+')[0] ?? v;\r\n}\r\n\r\n/**\r\n * Compara dois CalVer (`YYYY.MM.patch`). Retorna negativo se `a < b`,\r\n * positivo se `a > b`, 0 se iguais. Partes não numéricas tratadas como 0.\r\n */\r\nfunction compareCalVer(a: string, b: string): number {\r\n const partsA = stripRevision(a).split('.').map(Number);\r\n const partsB = stripRevision(b).split('.').map(Number);\r\n const len = Math.max(partsA.length, partsB.length);\r\n for (let i = 0; i < len; i++) {\r\n const pa = partsA[i] ?? 0;\r\n const pb = partsB[i] ?? 0;\r\n if (pa !== pb) return pa - pb;\r\n }\r\n return 0;\r\n}\r\n\r\n/** Lê a SDK major a partir da string `VERSION` exportada de `./index`. Fallback 3. */\r\nfunction getSdkMajor(): number {\r\n try {\r\n // Importação estática não disponível aqui (evita ciclo). Usa variável injetada\r\n // em tempo de build pela tsup via `define`. Fallback para 3 (current major).\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const ver = (globalThis as any).__NEETRU_SDK_VERSION__ as string | undefined;\r\n if (ver) return parseInt(ver.split('.')[0] ?? '3', 10);\r\n } catch {\r\n // ignore\r\n }\r\n return 3;\r\n}\r\n\r\n/** Aviso emitido no máximo uma vez por major detectada pra não spammar logs. */\r\nconst _warnedCoreTooOld = new Set<string>();\r\n\r\n/**\r\n * Verifica se a versão do Core (`X-Neetru-Version`) é compatível com a SDK major.\r\n * Emite `console.warn` quando incompatível (uma vez por processo por versão detectada).\r\n */\r\nexport function checkCoreVersionCompat(coreVersion: string): void {\r\n if (!coreVersion) return;\r\n const sdkMajor = getSdkMajor();\r\n const minCore = COMPAT_MATRIX[sdkMajor];\r\n if (!minCore) return; // sem restrição para esta major\r\n const stripped = stripRevision(coreVersion);\r\n if (compareCalVer(stripped, minCore) < 0) {\r\n const key = `${sdkMajor}:${stripped}`;\r\n if (!_warnedCoreTooOld.has(key)) {\r\n _warnedCoreTooOld.add(key);\r\n console.warn(\r\n `[Neetru SDK] Atenção: Core versão \"${coreVersion}\" é anterior ao mínimo recomendado` +\r\n ` \"${minCore}\" para SDK major ${sdkMajor}. Alguns recursos podem não funcionar` +\r\n ` corretamente. Atualize o Core para a versão mais recente.`,\r\n );\r\n }\r\n }\r\n}\r\n\r\n/** Opções da request HTTP. */\r\nexport interface HttpRequestOptions {\r\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\r\n /** Path relativo (ex: `/api/v1/cli/catalog`). Concatenado a `baseUrl`. */\r\n path: string;\r\n /** Query string params (chave → valor primitivo). Valores `undefined` ignorados. */\r\n query?: Record<string, string | number | boolean | undefined>;\r\n /** Body JSON-serializável. Ignorado em GET/DELETE. */\r\n body?: unknown;\r\n /**\r\n * Se true, injeta `Authorization: Bearer <apiKey>`. Lança `missing_api_key`\r\n * se config.apiKey ausente. Default false.\r\n */\r\n requireAuth?: boolean;\r\n /** Cabeçalhos extras. */\r\n headers?: Record<string, string>;\r\n /**\r\n * Número de retries em códigos transientes (`rate_limited`, `server_error`,\r\n * `network_error`).\r\n *\r\n * Default (3.0):\r\n * - GET/HEAD: 2 (= 3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: 0 — mutations podem duplicar side effects.\r\n *\r\n * Caller pode reativar passando explicitamente: `retries: 2`.\r\n */\r\n retries?: number;\r\n /**\r\n * Injeta `Idempotency-Key` header pra dedup serverside (3.0):\r\n * - `true` → SDK gera UUID v4 cripto-seguro automaticamente.\r\n * - string → usa o valor passado (deve ser UUID v4).\r\n * - `undefined`/`false` → sem header.\r\n */\r\n idempotencyKey?: boolean | string;\r\n}\r\n\r\nconst DEFAULT_RETRIES_READ = 2;\r\nconst DEFAULT_RETRIES_WRITE = 0;\r\nconst READ_METHODS = new Set(['GET', 'HEAD']);\r\nconst RETRYABLE_CODES = new Set<NeetruErrorCode>([\r\n 'rate_limited',\r\n 'server_error',\r\n 'network_error',\r\n]);\r\n\r\n/** Backoff exponencial com jitter ±20%. attempt: 0=primeira, 1=primeiro retry, ... */\r\nfunction backoffMs(attempt: number): number {\r\n const base = 200 * Math.pow(4, attempt); // 200ms, 800ms, 3.2s, ...\r\n const jitter = base * 0.2 * (Math.random() * 2 - 1);\r\n return Math.max(50, Math.round(base + jitter));\r\n}\r\n\r\n/**\r\n * Honra `Retry-After` header (segundos ou HTTP-date). Retorna ms ou null se\r\n * inválido. RFC 9110 §10.2.3.\r\n *\r\n * Bug fix: sem teto, um servidor hostil/mal-configurado poderia retornar\r\n * `Retry-After: 86400` (24h) ou uma HTTP-date anos no futuro, pendurando o\r\n * processo indefinidamente. Aplica teto de MAX_RETRY_AFTER_MS em ambos os caminhos.\r\n */\r\nconst MAX_RETRY_AFTER_MS = 60_000; // 60s — teto razoável para retry automático\r\n\r\nfunction parseRetryAfter(value: string | null): number | null {\r\n if (!value) return null;\r\n const secs = Number(value);\r\n if (Number.isFinite(secs) && secs >= 0) return Math.min(Math.round(secs * 1000), MAX_RETRY_AFTER_MS);\r\n const dateMs = Date.parse(value);\r\n if (Number.isFinite(dateMs)) {\r\n const delta = dateMs - Date.now();\r\n if (delta > 0) return Math.min(delta, MAX_RETRY_AFTER_MS);\r\n }\r\n return null;\r\n}\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/** Mapeamento status → code estável do NeetruError. */\r\nfunction statusToCode(status: number): NeetruErrorCode {\r\n if (status === 401) return 'unauthorized';\r\n if (status === 403) return 'forbidden';\r\n if (status === 404) return 'not_found';\r\n if (status === 409) return 'conflict'; // Bug fix: 409 vira 'conflict' (não 'unknown')\r\n if (status === 422 || status === 400) return 'validation_failed';\r\n if (status === 429) return 'rate_limited';\r\n if (status >= 500) return 'server_error';\r\n return 'unknown';\r\n}\r\n\r\nfunction buildUrl(baseUrl: string, path: string, query?: HttpRequestOptions['query']): string {\r\n // Trim trailing slash em base e leading em path pra evitar `//`.\r\n const base = baseUrl.replace(/\\/+$/, '');\r\n const p = path.startsWith('/') ? path : `/${path}`;\r\n const url = new URL(`${base}${p}`);\r\n if (query) {\r\n for (const [k, v] of Object.entries(query)) {\r\n if (v === undefined) continue;\r\n url.searchParams.set(k, String(v));\r\n }\r\n }\r\n return url.toString();\r\n}\r\n\r\n/** Parse JSON defensivo — retorna `undefined` em body vazio. */\r\nasync function safeJson(res: Response): Promise<unknown> {\r\n const text = await res.text();\r\n if (!text) return undefined;\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Executa request HTTP. Em sucesso retorna body parseado; em erro lança\r\n * `NeetruError` com `code` derivado do status. Aplica retry/backoff\r\n * automático em códigos transientes (rate_limited/server_error/network_error)\r\n * conforme `opts.retries` (default 2 = 3 tentativas).\r\n */\r\nexport async function httpRequest<T>(\r\n config: ResolvedConfig,\r\n opts: HttpRequestOptions,\r\n): Promise<T> {\r\n const method = opts.method ?? 'GET';\r\n const url = buildUrl(config.baseUrl, opts.path, opts.query);\r\n // Default por método: reads tentam 2x, writes 0x. Caller override sempre vence.\r\n const defaultRetries = READ_METHODS.has(method)\r\n ? DEFAULT_RETRIES_READ\r\n : DEFAULT_RETRIES_WRITE;\r\n const maxRetries = opts.retries ?? defaultRetries;\r\n\r\n const headers: Record<string, string> = {\r\n accept: 'application/json',\r\n ...opts.headers,\r\n };\r\n\r\n if (opts.requireAuth) {\r\n if (!config.apiKey) {\r\n throw new NeetruError(\r\n 'missing_api_key',\r\n 'This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.',\r\n );\r\n }\r\n headers.authorization = `Bearer ${config.apiKey}`;\r\n }\r\n\r\n // Idempotency-Key: gerado por chamada se solicitado. UUID v4 cripto-seguro.\r\n if (opts.idempotencyKey) {\r\n const key =\r\n typeof opts.idempotencyKey === 'string'\r\n ? opts.idempotencyKey\r\n : generateIdempotencyKey();\r\n headers['idempotency-key'] = key;\r\n }\r\n\r\n // Body só é serializado uma vez — reusado entre tentativas.\r\n const bodyString =\r\n opts.body !== undefined && method !== 'GET' && method !== 'DELETE'\r\n ? JSON.stringify(opts.body)\r\n : undefined;\r\n if (bodyString !== undefined) {\r\n headers['content-type'] = 'application/json';\r\n }\r\n\r\n let lastError: NeetruError | null = null;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n const init: RequestInit = { method, headers };\r\n if (bodyString !== undefined) init.body = bodyString;\r\n // BUG-020 fix (2026-05-13): timeout default 30s. AbortSignal.timeout\r\n // requer Node 18+ ou browsers recentes.\r\n init.signal = AbortSignal.timeout(30_000);\r\n\r\n let res: Response;\r\n try {\r\n res = await config.fetch(url, init);\r\n } catch (err) {\r\n const message =\r\n err instanceof DOMException && err.name === 'TimeoutError'\r\n ? 'Network error: timeout after 30s'\r\n : `Network error: ${err instanceof Error ? err.message : 'fetch failed'}`;\r\n lastError = new NeetruError('network_error', message);\r\n if (attempt < maxRetries) {\r\n await sleep(backoffMs(attempt));\r\n continue;\r\n }\r\n throw lastError;\r\n }\r\n\r\n const requestId =\r\n res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined;\r\n\r\n if (res.ok) {\r\n // Captura X-Neetru-Version e verifica compat com a SDK major.\r\n const coreVersion = res.headers.get('x-neetru-version');\r\n if (coreVersion) checkCoreVersionCompat(coreVersion);\r\n const parsed = await safeJson(res);\r\n return parsed as T;\r\n }\r\n\r\n const body = (await safeJson(res)) as\r\n | { error?: { code?: string; message?: string } | string }\r\n | undefined;\r\n let code: string = statusToCode(res.status);\r\n let message = `HTTP ${res.status}`;\r\n if (body && typeof body === 'object' && 'error' in body) {\r\n const errField = body.error;\r\n if (typeof errField === 'string') {\r\n message = errField;\r\n } else if (errField && typeof errField === 'object') {\r\n if (typeof errField.code === 'string') code = errField.code;\r\n if (typeof errField.message === 'string') message = errField.message;\r\n }\r\n }\r\n const err = new NeetruError(code, message, res.status, requestId);\r\n lastError = err;\r\n\r\n const isRetryable = RETRYABLE_CODES.has(code as NeetruErrorCode);\r\n if (isRetryable && attempt < maxRetries) {\r\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'));\r\n const delay = retryAfter ?? backoffMs(attempt);\r\n await sleep(delay);\r\n continue;\r\n }\r\n throw err;\r\n }\r\n\r\n // Unreachable — loop sempre retorna ou lança. Safety net.\r\n throw lastError ?? new NeetruError('unknown', 'unexpected httpRequest exit');\r\n}\r\n","/**\n * Validators centralizados pra inputs do SDK que precisam casar com\n * regex do Core.\n *\n * **M-03 fix (Opus review 2026-05-27):** o Core rejeita productId que\n * não bate `/^[a-z0-9][a-z0-9_-]{0,62}$/` com 400 `validation_failed`.\n * O SDK não pré-validava — consumer recebia erro só em runtime de\n * produção, depois do round-trip de rede. Agora SDK throws localmente\n * antes do fetch.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Regex canonical de IDs no Neetru Core (productId, tenantId, etc).\n * Espelha `SDK_ID_RE` em `neetru_core/src/lib/schemas/sdk.ts`.\n */\nexport const SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/;\n\n/**\n * Throws `NeetruError('validation_failed')` se `value` não bater no\n * formato canonical.\n *\n * @example\n * ```ts\n * assertValidSdkId('productId', 'gestovendas'); // ok\n * assertValidSdkId('productId', 'GestoVendas'); // throws\n * ```\n */\nexport function assertValidSdkId(field: string, value: string): void {\n if (typeof value !== 'string' || !SDK_ID_RE.test(value)) {\n throw new NeetruError(\n 'validation_failed',\n `${field} must match ${SDK_ID_RE.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`,\n );\n }\n}\n","/**\r\n * Notifications namespace (v1.2) — produtos SaaS enviam notificações in-app\r\n * pros SEUS usuários (distinto das `notifications/` staff-only do Core).\r\n *\r\n * Caso típico: produto gestovendas notifica usuário \"Pedido #X recebido\" no\r\n * portal sem precisar manter a própria coleção Firestore.\r\n *\r\n * Schema isolado por produto: `product_user_notifications/{productId}/{notifId}`.\r\n * Owner Neetru não vê o conteúdo (privacidade do produto), mas o Core\r\n * armazena + serve a leitura. Produto pode também listar via SDK.\r\n *\r\n * Endpoints REST (em prod):\r\n * - `POST /api/sdk/v1/notifications` — produto envia\r\n * - `GET /api/sdk/v1/notifications/user/{userId}` — produto lista do user\r\n * - `POST /api/sdk/v1/notifications/{id}/read` — user marca lida (proxy)\r\n * - `POST /api/sdk/v1/notifications/{id}/dismiss` — user descarta (proxy)\r\n *\r\n * Severidade canônica: `info | success | warning | error`.\r\n *\r\n * Mock em `NEETRU_ENV=dev`: in-memory.\r\n */\r\nimport { NeetruError } from './errors';\r\nimport { httpRequest } from './http';\r\nimport { assertValidSdkId } from './validators';\r\nimport type { ResolvedConfig } from './types';\r\n\r\nexport type ProductNotificationSeverity =\r\n | 'info'\r\n | 'success'\r\n | 'warning'\r\n | 'error';\r\n\r\nexport interface ProductNotification {\r\n id: string;\r\n /** UID do usuário final (do produto, não staff Neetru). */\r\n userId: string;\r\n /** Identificador semântico do evento (ex: `order.received`). */\r\n kind: string;\r\n severity: ProductNotificationSeverity;\r\n title: string;\r\n body?: string;\r\n /** Link opcional pra ação. */\r\n link?: string;\r\n /** Metadata livre (serializável). */\r\n metadata?: Record<string, string | number | boolean | null>;\r\n createdAt: string;\r\n /** ISO quando user marcou lida. */\r\n readAt?: string;\r\n /** ISO quando user descartou. */\r\n dismissedAt?: string;\r\n}\r\n\r\nexport interface SendNotificationInput {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório (Core valida via Zod). Default\r\n * resolve do `config.productId`; lança `validation_failed` se ausente.\r\n */\r\n productId?: string;\r\n userId: string;\r\n kind: string;\r\n title: string;\r\n severity?: ProductNotificationSeverity;\r\n body?: string;\r\n link?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n /**\r\n * Dedup — se já existir notificação com mesmo fingerprint dentro de 24h,\r\n * NÃO cria duplicata. Útil pra evitar spam quando webhook reentrega.\r\n */\r\n fingerprint?: string;\r\n}\r\n\r\nexport interface ListNotificationsOptions {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório no Core. Default resolve do\r\n * `config.productId`.\r\n */\r\n productId?: string;\r\n /** Inclui notificações dismissed (default false). */\r\n includeDismissed?: boolean;\r\n /** Filtro por unread. */\r\n onlyUnread?: boolean;\r\n /** Máx itens (default 50, máx 200). */\r\n limit?: number;\r\n}\r\n\r\n/** 3.0: scope option pra markRead/dismiss (productId obrigatório no Core). */\r\nexport interface NotificationScopeOptions {\r\n productId?: string;\r\n}\r\n\r\nexport interface NotificationsNamespace {\r\n /** Produto envia uma notificação pra um usuário do produto. */\r\n send(input: SendNotificationInput): Promise<ProductNotification>;\r\n /** Lista notificações de um usuário. */\r\n list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]>;\r\n /** Marca como lida. */\r\n markRead(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n /** Descarta. */\r\n dismiss(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n}\r\n\r\n// ─── HTTP impl ──────────────────────────────────────────────────────────────\r\n\r\nconst VALID_SEVERITIES: readonly ProductNotificationSeverity[] = [\r\n 'info',\r\n 'success',\r\n 'warning',\r\n 'error',\r\n];\r\n\r\nfunction toNotification(raw: unknown): ProductNotification {\r\n if (!raw || typeof raw !== 'object') {\r\n throw new NeetruError('invalid_response', 'Notification response is not an object');\r\n }\r\n const r = raw as Record<string, unknown>;\r\n if (typeof r.id !== 'string') {\r\n throw new NeetruError('invalid_response', 'Notification missing id');\r\n }\r\n const sev = VALID_SEVERITIES.includes(r.severity as ProductNotificationSeverity)\r\n ? (r.severity as ProductNotificationSeverity)\r\n : 'info';\r\n return {\r\n id: r.id,\r\n userId: typeof r.userId === 'string' ? r.userId : '',\r\n kind: typeof r.kind === 'string' ? r.kind : 'unknown',\r\n severity: sev,\r\n title: typeof r.title === 'string' ? r.title : '',\r\n body: typeof r.body === 'string' ? r.body : undefined,\r\n link: typeof r.link === 'string' ? r.link : undefined,\r\n metadata:\r\n r.metadata && typeof r.metadata === 'object'\r\n ? (r.metadata as Record<string, string | number | boolean | null>)\r\n : undefined,\r\n createdAt: typeof r.createdAt === 'string' ? r.createdAt : new Date().toISOString(),\r\n readAt: typeof r.readAt === 'string' ? r.readAt : undefined,\r\n dismissedAt: typeof r.dismissedAt === 'string' ? r.dismissedAt : undefined,\r\n };\r\n}\r\n\r\nfunction validateInput(input: SendNotificationInput): void {\r\n if (!input.userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n if (!input.kind) throw new NeetruError('validation_failed', 'kind obrigatório');\r\n if (!input.title) throw new NeetruError('validation_failed', 'title obrigatório');\r\n if (input.severity && !VALID_SEVERITIES.includes(input.severity)) {\r\n throw new NeetruError(\r\n 'validation_failed',\r\n `severity inválida: ${input.severity} (use ${VALID_SEVERITIES.join('|')})`,\r\n );\r\n }\r\n if (input.title.length > 200) {\r\n throw new NeetruError('validation_failed', 'title máx 200 chars');\r\n }\r\n if (input.body && input.body.length > 2000) {\r\n throw new NeetruError('validation_failed', 'body máx 2000 chars');\r\n }\r\n}\r\n\r\n/** Resolve productId fail-closed (option > input > config).\r\n *\r\n * **M-03 fix (Opus review 2026-05-27):** valida client-side contra `SDK_ID_RE`. */\r\nfunction resolveProductId(\r\n config: ResolvedConfig,\r\n ...candidates: Array<string | undefined>\r\n): string {\r\n for (const c of candidates) {\r\n if (typeof c === 'string' && c.length > 0) {\r\n assertValidSdkId('productId', c);\r\n return c;\r\n }\r\n }\r\n if (config.productId) {\r\n assertValidSdkId('productId', config.productId);\r\n return config.productId;\r\n }\r\n throw new NeetruError(\r\n 'validation_failed',\r\n 'productId required (pass to options/input or set on createNeetruClient)',\r\n );\r\n}\r\n\r\nexport function createNotificationsNamespace(\r\n config: ResolvedConfig,\r\n): NotificationsNamespace {\r\n return {\r\n async send(input) {\r\n validateInput(input);\r\n const productId = resolveProductId(config, input.productId);\r\n const body: Record<string, unknown> = {\r\n productId,\r\n userId: input.userId,\r\n kind: input.kind,\r\n title: input.title,\r\n severity: input.severity ?? 'info',\r\n };\r\n if (input.body !== undefined) body.body = input.body;\r\n if (input.link !== undefined) body.link = input.link;\r\n if (input.metadata !== undefined) body.metadata = input.metadata;\r\n if (input.fingerprint !== undefined) body.fingerprint = input.fingerprint;\r\n const raw = await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: '/api/sdk/v1/notifications',\r\n body,\r\n requireAuth: true,\r\n idempotencyKey: true,\r\n });\r\n return toNotification(raw);\r\n },\r\n async list(userId, options) {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n const query: Record<string, string | number | boolean | undefined> = {\r\n productId,\r\n };\r\n if (options?.includeDismissed) query.includeDismissed = true;\r\n if (options?.onlyUnread) query.onlyUnread = true;\r\n if (options?.limit) {\r\n query.limit = Math.min(Math.max(1, options.limit), 200);\r\n }\r\n const raw = await httpRequest<{ notifications?: unknown[] }>(config, {\r\n method: 'GET',\r\n path: `/api/sdk/v1/notifications/user/${encodeURIComponent(userId)}`,\r\n query,\r\n requireAuth: true,\r\n });\r\n const list = Array.isArray(raw?.notifications) ? raw.notifications : [];\r\n return list.map(toNotification);\r\n },\r\n async markRead(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/read`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n async dismiss(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/dismiss`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n };\r\n}\r\n\r\n// ─── Mock impl ──────────────────────────────────────────────────────────────\r\n\r\nexport class MockNotifications implements NotificationsNamespace {\r\n private notifications = new Map<string, ProductNotification>();\r\n private nextId = 1;\r\n\r\n async send(input: SendNotificationInput): Promise<ProductNotification> {\r\n validateInput(input);\r\n // Dedup por fingerprint: se já existe um com mesmo fingerprint < 24h, retorna ele.\r\n if (input.fingerprint) {\r\n const dayAgo = Date.now() - 86_400_000;\r\n for (const existing of this.notifications.values()) {\r\n const meta = existing.metadata ?? {};\r\n if (\r\n meta.fingerprint === input.fingerprint &&\r\n existing.userId === input.userId &&\r\n new Date(existing.createdAt).getTime() > dayAgo\r\n ) {\r\n return existing;\r\n }\r\n }\r\n }\r\n const id = `mock_notif_${this.nextId++}`;\r\n const notif: ProductNotification = {\r\n id,\r\n userId: input.userId,\r\n kind: input.kind,\r\n severity: input.severity ?? 'info',\r\n title: input.title,\r\n body: input.body,\r\n link: input.link,\r\n metadata: input.fingerprint\r\n ? { ...(input.metadata ?? {}), fingerprint: input.fingerprint }\r\n : input.metadata,\r\n createdAt: new Date().toISOString(),\r\n };\r\n this.notifications.set(id, notif);\r\n return notif;\r\n }\r\n\r\n async list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]> {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const limit = Math.min(Math.max(1, options?.limit ?? 50), 200);\r\n return [...this.notifications.values()]\r\n .filter((n) => n.userId === userId)\r\n .filter((n) => options?.includeDismissed || !n.dismissedAt)\r\n .filter((n) => !options?.onlyUnread || !n.readAt)\r\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt))\r\n .slice(0, limit);\r\n }\r\n\r\n async markRead(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.readAt) {\r\n n.readAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n\r\n async dismiss(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.dismissedAt) {\r\n n.dismissedAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n}\r\n"]}
@@ -1,3 +1,3 @@
1
- export { L as ListNotificationsOptions, x as MockNotifications, U as NotificationScopeOptions, V as NotificationsNamespace, X as ProductNotification, Y as ProductNotificationSeverity, a2 as SendNotificationInput, as as createNotificationsNamespace } from './types-nwErcRX8.cjs';
1
+ export { L as ListNotificationsOptions, x as MockNotifications, U as NotificationScopeOptions, V as NotificationsNamespace, X as ProductNotification, Y as ProductNotificationSeverity, a2 as SendNotificationInput, au as createNotificationsNamespace } from './types-DePdSU3P.cjs';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.cjs';
@@ -1,3 +1,3 @@
1
- export { L as ListNotificationsOptions, x as MockNotifications, U as NotificationScopeOptions, V as NotificationsNamespace, X as ProductNotification, Y as ProductNotificationSeverity, a2 as SendNotificationInput, as as createNotificationsNamespace } from './types-BRv8wBxX.js';
1
+ export { L as ListNotificationsOptions, x as MockNotifications, U as NotificationScopeOptions, V as NotificationsNamespace, X as ProductNotification, Y as ProductNotificationSeverity, a2 as SendNotificationInput, au as createNotificationsNamespace } from './types-B3XFHD4A.js';
2
2
  import 'drizzle-orm/node-postgres';
3
3
  import './errors.js';
@@ -26,6 +26,50 @@ function generateIdempotencyKey() {
26
26
  }
27
27
 
28
28
  // src/http.ts
29
+ var COMPAT_MATRIX = {
30
+ // SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,
31
+ // runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)
32
+ 3: "2026.05.1"
33
+ };
34
+ function stripRevision(v) {
35
+ return v.split("+")[0] ?? v;
36
+ }
37
+ function compareCalVer(a, b) {
38
+ const partsA = stripRevision(a).split(".").map(Number);
39
+ const partsB = stripRevision(b).split(".").map(Number);
40
+ const len = Math.max(partsA.length, partsB.length);
41
+ for (let i = 0; i < len; i++) {
42
+ const pa = partsA[i] ?? 0;
43
+ const pb = partsB[i] ?? 0;
44
+ if (pa !== pb) return pa - pb;
45
+ }
46
+ return 0;
47
+ }
48
+ function getSdkMajor() {
49
+ try {
50
+ const ver = globalThis.__NEETRU_SDK_VERSION__;
51
+ if (ver) return parseInt(ver.split(".")[0] ?? "3", 10);
52
+ } catch {
53
+ }
54
+ return 3;
55
+ }
56
+ var _warnedCoreTooOld = /* @__PURE__ */ new Set();
57
+ function checkCoreVersionCompat(coreVersion) {
58
+ if (!coreVersion) return;
59
+ const sdkMajor = getSdkMajor();
60
+ const minCore = COMPAT_MATRIX[sdkMajor];
61
+ if (!minCore) return;
62
+ const stripped = stripRevision(coreVersion);
63
+ if (compareCalVer(stripped, minCore) < 0) {
64
+ const key = `${sdkMajor}:${stripped}`;
65
+ if (!_warnedCoreTooOld.has(key)) {
66
+ _warnedCoreTooOld.add(key);
67
+ console.warn(
68
+ `[Neetru SDK] Aten\xE7\xE3o: Core vers\xE3o "${coreVersion}" \xE9 anterior ao m\xEDnimo recomendado "${minCore}" para SDK major ${sdkMajor}. Alguns recursos podem n\xE3o funcionar corretamente. Atualize o Core para a vers\xE3o mais recente.`
69
+ );
70
+ }
71
+ }
72
+ }
29
73
  var DEFAULT_RETRIES_READ = 2;
30
74
  var DEFAULT_RETRIES_WRITE = 0;
31
75
  var READ_METHODS = /* @__PURE__ */ new Set(["GET", "HEAD"]);
@@ -39,14 +83,15 @@ function backoffMs(attempt) {
39
83
  const jitter = base * 0.2 * (Math.random() * 2 - 1);
40
84
  return Math.max(50, Math.round(base + jitter));
41
85
  }
86
+ var MAX_RETRY_AFTER_MS = 6e4;
42
87
  function parseRetryAfter(value) {
43
88
  if (!value) return null;
44
89
  const secs = Number(value);
45
- if (Number.isFinite(secs) && secs >= 0) return Math.round(secs * 1e3);
90
+ if (Number.isFinite(secs) && secs >= 0) return Math.min(Math.round(secs * 1e3), MAX_RETRY_AFTER_MS);
46
91
  const dateMs = Date.parse(value);
47
92
  if (Number.isFinite(dateMs)) {
48
93
  const delta = dateMs - Date.now();
49
- if (delta > 0) return delta;
94
+ if (delta > 0) return Math.min(delta, MAX_RETRY_AFTER_MS);
50
95
  }
51
96
  return null;
52
97
  }
@@ -57,6 +102,7 @@ function statusToCode(status) {
57
102
  if (status === 401) return "unauthorized";
58
103
  if (status === 403) return "forbidden";
59
104
  if (status === 404) return "not_found";
105
+ if (status === 409) return "conflict";
60
106
  if (status === 422 || status === 400) return "validation_failed";
61
107
  if (status === 429) return "rate_limited";
62
108
  if (status >= 500) return "server_error";
@@ -128,6 +174,8 @@ async function httpRequest(config, opts) {
128
174
  }
129
175
  const requestId = res.headers.get("x-request-id") ?? res.headers.get("x-correlation-id") ?? void 0;
130
176
  if (res.ok) {
177
+ const coreVersion = res.headers.get("x-neetru-version");
178
+ if (coreVersion) checkCoreVersionCompat(coreVersion);
131
179
  const parsed = await safeJson(res);
132
180
  return parsed;
133
181
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/http.ts","../src/validators.ts","../src/notifications.ts"],"names":["err","message"],"mappings":"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","file":"notifications.mjs","sourcesContent":["/**\r\n * Erros tipados do SDK.\r\n *\r\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\r\n * por `.code` (string estável) sem parsing de message.\r\n */\r\n\r\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\r\nexport type NeetruErrorCode =\r\n | 'invalid_config'\r\n | 'missing_api_key'\r\n | 'unauthorized'\r\n | 'forbidden'\r\n | 'not_found'\r\n | 'rate_limited'\r\n | 'validation_failed'\r\n | 'network_error'\r\n | 'invalid_response'\r\n | 'server_error'\r\n | 'token_expired'\r\n | 'token_invalid_signature'\r\n | 'token_invalid_audience'\r\n | 'token_invalid_issuer'\r\n /** 3.0: runtime não expõe API necessária (ex: WebCrypto ausente). */\r\n | 'runtime_unsupported'\r\n | 'unknown';\r\n\r\n/**\r\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\r\n *\r\n * @example\r\n * ```ts\r\n * try { await client.catalog.list(); }\r\n * catch (e) {\r\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\r\n * }\r\n * ```\r\n */\r\nexport class NeetruError extends Error {\r\n public readonly code: NeetruErrorCode | string;\r\n public readonly status?: number;\r\n public readonly requestId?: string;\r\n\r\n constructor(\r\n code: NeetruErrorCode | string,\r\n message: string,\r\n status?: number,\r\n requestId?: string,\r\n ) {\r\n super(message);\r\n this.name = 'NeetruError';\r\n this.code = code;\r\n this.status = status;\r\n this.requestId = requestId;\r\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\r\n Object.setPrototypeOf(this, NeetruError.prototype);\r\n }\r\n}\r\n","/**\n * Idempotency-Key helper — gera UUID v4 cripto-seguro para identificar\n * mutations não-idempotentes (`usage.report`, `support.createTicket`,\n * `notifications.send`, `webhooks.test`).\n *\n * Estratégia 3.0:\n * - SDK gera UUID v4 por chamada via `randomUUID()` (WebCrypto.subtle não\n * necessário aqui — `crypto.randomUUID()` está em Node 14.17+ e em todos\n * os browsers/Edge runtimes modernos).\n * - Header `Idempotency-Key: <uuid>` é injetado pelo `httpRequest` quando\n * `opts.idempotencyKey === true` OU caller passa explicit `opts.idempotencyKeyValue`.\n * - Core dedup em coleção `usage_idempotency_keys/{key}` TTL 24h (vide\n * `docs/CORE_CHANGES_REQUIRED.md` §2). Se Core ainda não dedupa, o header\n * é benign (ignorado).\n *\n * Defesa em camadas: combinado com `retries: 0` em POSTs (vide http.ts), o\n * risco de double-write em transientes vai pra zero.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Gera UUID v4 criptograficamente seguro. Universal: Node 14.17+, browsers\n * modernos, Edge runtimes (Workers/Vercel Edge/Cloudflare).\n *\n * Fallback puro-JS removido em 3.0 — `crypto.randomUUID()` é ubíquo desde\n * 2022. Se runtime não tem, lança `NeetruError('runtime_unsupported')`\n * (consumer deve polyfillar).\n *\n * **L-01 fix (Opus review 2026-05-27):** antes lançava `Error` cru, que\n * não era pego por `catch (err) { if (err instanceof NeetruError) ... }`\n * dos consumers. Agora throw canonical.\n *\n * @throws NeetruError('runtime_unsupported') se `crypto.randomUUID` não disponível.\n */\nexport function generateIdempotencyKey(): string {\n // WebCrypto (browser/Edge) e Node 14.17+ expõem `crypto.randomUUID()`.\n // Node anterior precisa de `node:crypto` mas SDK 3.0 exige Node ≥20 (vide engines).\n const cryptoObj: { randomUUID?: () => string } | undefined =\n typeof globalThis !== 'undefined' && 'crypto' in globalThis\n ? (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n : undefined;\n if (cryptoObj && typeof cryptoObj.randomUUID === 'function') {\n return cryptoObj.randomUUID();\n }\n throw new NeetruError(\n 'runtime_unsupported',\n 'crypto.randomUUID not available in this runtime. SDK 3.0 requires Node ≥20 or modern browser/Edge.',\n );\n}\n\n/** Regex UUID v4 — validação para uso interno. */\nexport const UUID_V4_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n","/**\r\n * HTTP transport interno do SDK.\r\n *\r\n * Responsabilidades:\r\n * - Construir URL absoluta a partir de `baseUrl` + path\r\n * - Injetar Bearer token quando `requireAuth=true`\r\n * - Mapear status HTTP → `NeetruError` com `code` estável\r\n * - Parse defensivo de JSON (não lança em body vazio em 204)\r\n * - Retry/backoff exponencial em `rate_limited` (429), `server_error` (5xx)\r\n * e `network_error` (timeout/falha de rede). Honra `Retry-After` quando\r\n * presente.\r\n *\r\n * Política de retries (mudança breaking 3.0):\r\n * - GET/HEAD: default 2 retries (3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: default **0 retries** — mutations podem duplicar\r\n * side effects (ex: `usage.report` incrementa contador). Caller pode\r\n * reativar passando `retries: N` explicitamente ou usar `Idempotency-Key`\r\n * header (gerado automaticamente se `opts.idempotencyKey=true`).\r\n *\r\n * Idempotency-Key (3.0):\r\n * - `opts.idempotencyKey === true` → SDK gera UUID v4 e injeta header.\r\n * - `opts.idempotencyKey === 'uuid-string'` → usa o valor passado.\r\n * - Caller mantém retentos client-side se quiser; Core dedup serverside\r\n * (vide `docs/CORE_CHANGES_REQUIRED.md` §2).\r\n */\r\nimport { NeetruError, type NeetruErrorCode } from './errors';\r\nimport { generateIdempotencyKey } from './idempotency';\r\nimport type { ResolvedConfig } from './types';\r\n\r\n/** Opções da request HTTP. */\r\nexport interface HttpRequestOptions {\r\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\r\n /** Path relativo (ex: `/api/v1/cli/catalog`). Concatenado a `baseUrl`. */\r\n path: string;\r\n /** Query string params (chave → valor primitivo). Valores `undefined` ignorados. */\r\n query?: Record<string, string | number | boolean | undefined>;\r\n /** Body JSON-serializável. Ignorado em GET/DELETE. */\r\n body?: unknown;\r\n /**\r\n * Se true, injeta `Authorization: Bearer <apiKey>`. Lança `missing_api_key`\r\n * se config.apiKey ausente. Default false.\r\n */\r\n requireAuth?: boolean;\r\n /** Cabeçalhos extras. */\r\n headers?: Record<string, string>;\r\n /**\r\n * Número de retries em códigos transientes (`rate_limited`, `server_error`,\r\n * `network_error`).\r\n *\r\n * Default (3.0):\r\n * - GET/HEAD: 2 (= 3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: 0 — mutations podem duplicar side effects.\r\n *\r\n * Caller pode reativar passando explicitamente: `retries: 2`.\r\n */\r\n retries?: number;\r\n /**\r\n * Injeta `Idempotency-Key` header pra dedup serverside (3.0):\r\n * - `true` → SDK gera UUID v4 cripto-seguro automaticamente.\r\n * - string → usa o valor passado (deve ser UUID v4).\r\n * - `undefined`/`false` → sem header.\r\n */\r\n idempotencyKey?: boolean | string;\r\n}\r\n\r\nconst DEFAULT_RETRIES_READ = 2;\r\nconst DEFAULT_RETRIES_WRITE = 0;\r\nconst READ_METHODS = new Set(['GET', 'HEAD']);\r\nconst RETRYABLE_CODES = new Set<NeetruErrorCode>([\r\n 'rate_limited',\r\n 'server_error',\r\n 'network_error',\r\n]);\r\n\r\n/** Backoff exponencial com jitter ±20%. attempt: 0=primeira, 1=primeiro retry, ... */\r\nfunction backoffMs(attempt: number): number {\r\n const base = 200 * Math.pow(4, attempt); // 200ms, 800ms, 3.2s, ...\r\n const jitter = base * 0.2 * (Math.random() * 2 - 1);\r\n return Math.max(50, Math.round(base + jitter));\r\n}\r\n\r\n/**\r\n * Honra `Retry-After` header (segundos ou HTTP-date). Retorna ms ou null se\r\n * inválido. RFC 9110 §10.2.3.\r\n */\r\nfunction parseRetryAfter(value: string | null): number | null {\r\n if (!value) return null;\r\n const secs = Number(value);\r\n if (Number.isFinite(secs) && secs >= 0) return Math.round(secs * 1000);\r\n const dateMs = Date.parse(value);\r\n if (Number.isFinite(dateMs)) {\r\n const delta = dateMs - Date.now();\r\n if (delta > 0) return delta;\r\n }\r\n return null;\r\n}\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/** Mapeamento status → code estável do NeetruError. */\r\nfunction statusToCode(status: number): NeetruErrorCode {\r\n if (status === 401) return 'unauthorized';\r\n if (status === 403) return 'forbidden';\r\n if (status === 404) return 'not_found';\r\n if (status === 422 || status === 400) return 'validation_failed';\r\n if (status === 429) return 'rate_limited';\r\n if (status >= 500) return 'server_error';\r\n return 'unknown';\r\n}\r\n\r\nfunction buildUrl(baseUrl: string, path: string, query?: HttpRequestOptions['query']): string {\r\n // Trim trailing slash em base e leading em path pra evitar `//`.\r\n const base = baseUrl.replace(/\\/+$/, '');\r\n const p = path.startsWith('/') ? path : `/${path}`;\r\n const url = new URL(`${base}${p}`);\r\n if (query) {\r\n for (const [k, v] of Object.entries(query)) {\r\n if (v === undefined) continue;\r\n url.searchParams.set(k, String(v));\r\n }\r\n }\r\n return url.toString();\r\n}\r\n\r\n/** Parse JSON defensivo — retorna `undefined` em body vazio. */\r\nasync function safeJson(res: Response): Promise<unknown> {\r\n const text = await res.text();\r\n if (!text) return undefined;\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Executa request HTTP. Em sucesso retorna body parseado; em erro lança\r\n * `NeetruError` com `code` derivado do status. Aplica retry/backoff\r\n * automático em códigos transientes (rate_limited/server_error/network_error)\r\n * conforme `opts.retries` (default 2 = 3 tentativas).\r\n */\r\nexport async function httpRequest<T>(\r\n config: ResolvedConfig,\r\n opts: HttpRequestOptions,\r\n): Promise<T> {\r\n const method = opts.method ?? 'GET';\r\n const url = buildUrl(config.baseUrl, opts.path, opts.query);\r\n // Default por método: reads tentam 2x, writes 0x. Caller override sempre vence.\r\n const defaultRetries = READ_METHODS.has(method)\r\n ? DEFAULT_RETRIES_READ\r\n : DEFAULT_RETRIES_WRITE;\r\n const maxRetries = opts.retries ?? defaultRetries;\r\n\r\n const headers: Record<string, string> = {\r\n accept: 'application/json',\r\n ...opts.headers,\r\n };\r\n\r\n if (opts.requireAuth) {\r\n if (!config.apiKey) {\r\n throw new NeetruError(\r\n 'missing_api_key',\r\n 'This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.',\r\n );\r\n }\r\n headers.authorization = `Bearer ${config.apiKey}`;\r\n }\r\n\r\n // Idempotency-Key: gerado por chamada se solicitado. UUID v4 cripto-seguro.\r\n if (opts.idempotencyKey) {\r\n const key =\r\n typeof opts.idempotencyKey === 'string'\r\n ? opts.idempotencyKey\r\n : generateIdempotencyKey();\r\n headers['idempotency-key'] = key;\r\n }\r\n\r\n // Body só é serializado uma vez — reusado entre tentativas.\r\n const bodyString =\r\n opts.body !== undefined && method !== 'GET' && method !== 'DELETE'\r\n ? JSON.stringify(opts.body)\r\n : undefined;\r\n if (bodyString !== undefined) {\r\n headers['content-type'] = 'application/json';\r\n }\r\n\r\n let lastError: NeetruError | null = null;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n const init: RequestInit = { method, headers };\r\n if (bodyString !== undefined) init.body = bodyString;\r\n // BUG-020 fix (2026-05-13): timeout default 30s. AbortSignal.timeout\r\n // requer Node 18+ ou browsers recentes.\r\n init.signal = AbortSignal.timeout(30_000);\r\n\r\n let res: Response;\r\n try {\r\n res = await config.fetch(url, init);\r\n } catch (err) {\r\n const message =\r\n err instanceof DOMException && err.name === 'TimeoutError'\r\n ? 'Network error: timeout after 30s'\r\n : `Network error: ${err instanceof Error ? err.message : 'fetch failed'}`;\r\n lastError = new NeetruError('network_error', message);\r\n if (attempt < maxRetries) {\r\n await sleep(backoffMs(attempt));\r\n continue;\r\n }\r\n throw lastError;\r\n }\r\n\r\n const requestId =\r\n res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined;\r\n\r\n if (res.ok) {\r\n const parsed = await safeJson(res);\r\n return parsed as T;\r\n }\r\n\r\n const body = (await safeJson(res)) as\r\n | { error?: { code?: string; message?: string } | string }\r\n | undefined;\r\n let code: string = statusToCode(res.status);\r\n let message = `HTTP ${res.status}`;\r\n if (body && typeof body === 'object' && 'error' in body) {\r\n const errField = body.error;\r\n if (typeof errField === 'string') {\r\n message = errField;\r\n } else if (errField && typeof errField === 'object') {\r\n if (typeof errField.code === 'string') code = errField.code;\r\n if (typeof errField.message === 'string') message = errField.message;\r\n }\r\n }\r\n const err = new NeetruError(code, message, res.status, requestId);\r\n lastError = err;\r\n\r\n const isRetryable = RETRYABLE_CODES.has(code as NeetruErrorCode);\r\n if (isRetryable && attempt < maxRetries) {\r\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'));\r\n const delay = retryAfter ?? backoffMs(attempt);\r\n await sleep(delay);\r\n continue;\r\n }\r\n throw err;\r\n }\r\n\r\n // Unreachable — loop sempre retorna ou lança. Safety net.\r\n throw lastError ?? new NeetruError('unknown', 'unexpected httpRequest exit');\r\n}\r\n","/**\n * Validators centralizados pra inputs do SDK que precisam casar com\n * regex do Core.\n *\n * **M-03 fix (Opus review 2026-05-27):** o Core rejeita productId que\n * não bate `/^[a-z0-9][a-z0-9_-]{0,62}$/` com 400 `validation_failed`.\n * O SDK não pré-validava — consumer recebia erro só em runtime de\n * produção, depois do round-trip de rede. Agora SDK throws localmente\n * antes do fetch.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Regex canonical de IDs no Neetru Core (productId, tenantId, etc).\n * Espelha `SDK_ID_RE` em `neetru_core/src/lib/schemas/sdk.ts`.\n */\nexport const SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/;\n\n/**\n * Throws `NeetruError('validation_failed')` se `value` não bater no\n * formato canonical.\n *\n * @example\n * ```ts\n * assertValidSdkId('productId', 'gestovendas'); // ok\n * assertValidSdkId('productId', 'GestoVendas'); // throws\n * ```\n */\nexport function assertValidSdkId(field: string, value: string): void {\n if (typeof value !== 'string' || !SDK_ID_RE.test(value)) {\n throw new NeetruError(\n 'validation_failed',\n `${field} must match ${SDK_ID_RE.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`,\n );\n }\n}\n","/**\r\n * Notifications namespace (v1.2) — produtos SaaS enviam notificações in-app\r\n * pros SEUS usuários (distinto das `notifications/` staff-only do Core).\r\n *\r\n * Caso típico: produto gestovendas notifica usuário \"Pedido #X recebido\" no\r\n * portal sem precisar manter a própria coleção Firestore.\r\n *\r\n * Schema isolado por produto: `product_user_notifications/{productId}/{notifId}`.\r\n * Owner Neetru não vê o conteúdo (privacidade do produto), mas o Core\r\n * armazena + serve a leitura. Produto pode também listar via SDK.\r\n *\r\n * Endpoints REST (em prod):\r\n * - `POST /api/sdk/v1/notifications` — produto envia\r\n * - `GET /api/sdk/v1/notifications/user/{userId}` — produto lista do user\r\n * - `POST /api/sdk/v1/notifications/{id}/read` — user marca lida (proxy)\r\n * - `POST /api/sdk/v1/notifications/{id}/dismiss` — user descarta (proxy)\r\n *\r\n * Severidade canônica: `info | success | warning | error`.\r\n *\r\n * Mock em `NEETRU_ENV=dev`: in-memory.\r\n */\r\nimport { NeetruError } from './errors';\r\nimport { httpRequest } from './http';\r\nimport { assertValidSdkId } from './validators';\r\nimport type { ResolvedConfig } from './types';\r\n\r\nexport type ProductNotificationSeverity =\r\n | 'info'\r\n | 'success'\r\n | 'warning'\r\n | 'error';\r\n\r\nexport interface ProductNotification {\r\n id: string;\r\n /** UID do usuário final (do produto, não staff Neetru). */\r\n userId: string;\r\n /** Identificador semântico do evento (ex: `order.received`). */\r\n kind: string;\r\n severity: ProductNotificationSeverity;\r\n title: string;\r\n body?: string;\r\n /** Link opcional pra ação. */\r\n link?: string;\r\n /** Metadata livre (serializável). */\r\n metadata?: Record<string, string | number | boolean | null>;\r\n createdAt: string;\r\n /** ISO quando user marcou lida. */\r\n readAt?: string;\r\n /** ISO quando user descartou. */\r\n dismissedAt?: string;\r\n}\r\n\r\nexport interface SendNotificationInput {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório (Core valida via Zod). Default\r\n * resolve do `config.productId`; lança `validation_failed` se ausente.\r\n */\r\n productId?: string;\r\n userId: string;\r\n kind: string;\r\n title: string;\r\n severity?: ProductNotificationSeverity;\r\n body?: string;\r\n link?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n /**\r\n * Dedup — se já existir notificação com mesmo fingerprint dentro de 24h,\r\n * NÃO cria duplicata. Útil pra evitar spam quando webhook reentrega.\r\n */\r\n fingerprint?: string;\r\n}\r\n\r\nexport interface ListNotificationsOptions {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório no Core. Default resolve do\r\n * `config.productId`.\r\n */\r\n productId?: string;\r\n /** Inclui notificações dismissed (default false). */\r\n includeDismissed?: boolean;\r\n /** Filtro por unread. */\r\n onlyUnread?: boolean;\r\n /** Máx itens (default 50, máx 200). */\r\n limit?: number;\r\n}\r\n\r\n/** 3.0: scope option pra markRead/dismiss (productId obrigatório no Core). */\r\nexport interface NotificationScopeOptions {\r\n productId?: string;\r\n}\r\n\r\nexport interface NotificationsNamespace {\r\n /** Produto envia uma notificação pra um usuário do produto. */\r\n send(input: SendNotificationInput): Promise<ProductNotification>;\r\n /** Lista notificações de um usuário. */\r\n list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]>;\r\n /** Marca como lida. */\r\n markRead(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n /** Descarta. */\r\n dismiss(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n}\r\n\r\n// ─── HTTP impl ──────────────────────────────────────────────────────────────\r\n\r\nconst VALID_SEVERITIES: readonly ProductNotificationSeverity[] = [\r\n 'info',\r\n 'success',\r\n 'warning',\r\n 'error',\r\n];\r\n\r\nfunction toNotification(raw: unknown): ProductNotification {\r\n if (!raw || typeof raw !== 'object') {\r\n throw new NeetruError('invalid_response', 'Notification response is not an object');\r\n }\r\n const r = raw as Record<string, unknown>;\r\n if (typeof r.id !== 'string') {\r\n throw new NeetruError('invalid_response', 'Notification missing id');\r\n }\r\n const sev = VALID_SEVERITIES.includes(r.severity as ProductNotificationSeverity)\r\n ? (r.severity as ProductNotificationSeverity)\r\n : 'info';\r\n return {\r\n id: r.id,\r\n userId: typeof r.userId === 'string' ? r.userId : '',\r\n kind: typeof r.kind === 'string' ? r.kind : 'unknown',\r\n severity: sev,\r\n title: typeof r.title === 'string' ? r.title : '',\r\n body: typeof r.body === 'string' ? r.body : undefined,\r\n link: typeof r.link === 'string' ? r.link : undefined,\r\n metadata:\r\n r.metadata && typeof r.metadata === 'object'\r\n ? (r.metadata as Record<string, string | number | boolean | null>)\r\n : undefined,\r\n createdAt: typeof r.createdAt === 'string' ? r.createdAt : new Date().toISOString(),\r\n readAt: typeof r.readAt === 'string' ? r.readAt : undefined,\r\n dismissedAt: typeof r.dismissedAt === 'string' ? r.dismissedAt : undefined,\r\n };\r\n}\r\n\r\nfunction validateInput(input: SendNotificationInput): void {\r\n if (!input.userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n if (!input.kind) throw new NeetruError('validation_failed', 'kind obrigatório');\r\n if (!input.title) throw new NeetruError('validation_failed', 'title obrigatório');\r\n if (input.severity && !VALID_SEVERITIES.includes(input.severity)) {\r\n throw new NeetruError(\r\n 'validation_failed',\r\n `severity inválida: ${input.severity} (use ${VALID_SEVERITIES.join('|')})`,\r\n );\r\n }\r\n if (input.title.length > 200) {\r\n throw new NeetruError('validation_failed', 'title máx 200 chars');\r\n }\r\n if (input.body && input.body.length > 2000) {\r\n throw new NeetruError('validation_failed', 'body máx 2000 chars');\r\n }\r\n}\r\n\r\n/** Resolve productId fail-closed (option > input > config).\r\n *\r\n * **M-03 fix (Opus review 2026-05-27):** valida client-side contra `SDK_ID_RE`. */\r\nfunction resolveProductId(\r\n config: ResolvedConfig,\r\n ...candidates: Array<string | undefined>\r\n): string {\r\n for (const c of candidates) {\r\n if (typeof c === 'string' && c.length > 0) {\r\n assertValidSdkId('productId', c);\r\n return c;\r\n }\r\n }\r\n if (config.productId) {\r\n assertValidSdkId('productId', config.productId);\r\n return config.productId;\r\n }\r\n throw new NeetruError(\r\n 'validation_failed',\r\n 'productId required (pass to options/input or set on createNeetruClient)',\r\n );\r\n}\r\n\r\nexport function createNotificationsNamespace(\r\n config: ResolvedConfig,\r\n): NotificationsNamespace {\r\n return {\r\n async send(input) {\r\n validateInput(input);\r\n const productId = resolveProductId(config, input.productId);\r\n const body: Record<string, unknown> = {\r\n productId,\r\n userId: input.userId,\r\n kind: input.kind,\r\n title: input.title,\r\n severity: input.severity ?? 'info',\r\n };\r\n if (input.body !== undefined) body.body = input.body;\r\n if (input.link !== undefined) body.link = input.link;\r\n if (input.metadata !== undefined) body.metadata = input.metadata;\r\n if (input.fingerprint !== undefined) body.fingerprint = input.fingerprint;\r\n const raw = await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: '/api/sdk/v1/notifications',\r\n body,\r\n requireAuth: true,\r\n idempotencyKey: true,\r\n });\r\n return toNotification(raw);\r\n },\r\n async list(userId, options) {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n const query: Record<string, string | number | boolean | undefined> = {\r\n productId,\r\n };\r\n if (options?.includeDismissed) query.includeDismissed = true;\r\n if (options?.onlyUnread) query.onlyUnread = true;\r\n if (options?.limit) {\r\n query.limit = Math.min(Math.max(1, options.limit), 200);\r\n }\r\n const raw = await httpRequest<{ notifications?: unknown[] }>(config, {\r\n method: 'GET',\r\n path: `/api/sdk/v1/notifications/user/${encodeURIComponent(userId)}`,\r\n query,\r\n requireAuth: true,\r\n });\r\n const list = Array.isArray(raw?.notifications) ? raw.notifications : [];\r\n return list.map(toNotification);\r\n },\r\n async markRead(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/read`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n async dismiss(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/dismiss`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n };\r\n}\r\n\r\n// ─── Mock impl ──────────────────────────────────────────────────────────────\r\n\r\nexport class MockNotifications implements NotificationsNamespace {\r\n private notifications = new Map<string, ProductNotification>();\r\n private nextId = 1;\r\n\r\n async send(input: SendNotificationInput): Promise<ProductNotification> {\r\n validateInput(input);\r\n // Dedup por fingerprint: se já existe um com mesmo fingerprint < 24h, retorna ele.\r\n if (input.fingerprint) {\r\n const dayAgo = Date.now() - 86_400_000;\r\n for (const existing of this.notifications.values()) {\r\n const meta = existing.metadata ?? {};\r\n if (\r\n meta.fingerprint === input.fingerprint &&\r\n existing.userId === input.userId &&\r\n new Date(existing.createdAt).getTime() > dayAgo\r\n ) {\r\n return existing;\r\n }\r\n }\r\n }\r\n const id = `mock_notif_${this.nextId++}`;\r\n const notif: ProductNotification = {\r\n id,\r\n userId: input.userId,\r\n kind: input.kind,\r\n severity: input.severity ?? 'info',\r\n title: input.title,\r\n body: input.body,\r\n link: input.link,\r\n metadata: input.fingerprint\r\n ? { ...(input.metadata ?? {}), fingerprint: input.fingerprint }\r\n : input.metadata,\r\n createdAt: new Date().toISOString(),\r\n };\r\n this.notifications.set(id, notif);\r\n return notif;\r\n }\r\n\r\n async list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]> {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const limit = Math.min(Math.max(1, options?.limit ?? 50), 200);\r\n return [...this.notifications.values()]\r\n .filter((n) => n.userId === userId)\r\n .filter((n) => options?.includeDismissed || !n.dismissedAt)\r\n .filter((n) => !options?.onlyUnread || !n.readAt)\r\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt))\r\n .slice(0, limit);\r\n }\r\n\r\n async markRead(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.readAt) {\r\n n.readAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n\r\n async dismiss(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.dismissedAt) {\r\n n.dismissedAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/idempotency.ts","../src/http.ts","../src/validators.ts","../src/notifications.ts"],"names":["err","message"],"mappings":"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","file":"notifications.mjs","sourcesContent":["/**\r\n * Erros tipados do SDK.\r\n *\r\n * Todo erro lançado pelo SDK estende `NeetruError` — caller pode discriminar\r\n * por `.code` (string estável) sem parsing de message.\r\n */\r\n\r\n/** Códigos de erro estáveis do SDK. Adicionar aqui requer minor bump. */\r\nexport type NeetruErrorCode =\r\n | 'invalid_config'\r\n | 'missing_api_key'\r\n | 'unauthorized'\r\n | 'forbidden'\r\n | 'not_found'\r\n | 'rate_limited'\r\n | 'validation_failed'\r\n | 'network_error'\r\n | 'invalid_response'\r\n | 'server_error'\r\n | 'token_expired'\r\n | 'token_invalid_signature'\r\n | 'token_invalid_audience'\r\n | 'token_invalid_issuer'\r\n /** 3.0: runtime não expõe API necessária (ex: WebCrypto ausente). */\r\n | 'runtime_unsupported'\r\n /** HTTP 409 — colisão de idempotência ou conflito de recurso. */\r\n | 'conflict'\r\n | 'unknown';\r\n\r\n/**\r\n * Erro tipado padrão do SDK. Sempre lançado em vez de Error genérico.\r\n *\r\n * @example\r\n * ```ts\r\n * try { await client.catalog.list(); }\r\n * catch (e) {\r\n * if (e instanceof NeetruError && e.code === 'rate_limited') retry();\r\n * }\r\n * ```\r\n */\r\nexport class NeetruError extends Error {\r\n public readonly code: NeetruErrorCode | string;\r\n public readonly status?: number;\r\n public readonly requestId?: string;\r\n\r\n constructor(\r\n code: NeetruErrorCode | string,\r\n message: string,\r\n status?: number,\r\n requestId?: string,\r\n ) {\r\n super(message);\r\n this.name = 'NeetruError';\r\n this.code = code;\r\n this.status = status;\r\n this.requestId = requestId;\r\n // Preserva o prototype chain ao herdar de Error (downlevel quirk de TS).\r\n Object.setPrototypeOf(this, NeetruError.prototype);\r\n }\r\n}\r\n","/**\n * Idempotency-Key helper — gera UUID v4 cripto-seguro para identificar\n * mutations não-idempotentes (`usage.report`, `support.createTicket`,\n * `notifications.send`, `webhooks.test`).\n *\n * Estratégia 3.0:\n * - SDK gera UUID v4 por chamada via `randomUUID()` (WebCrypto.subtle não\n * necessário aqui — `crypto.randomUUID()` está em Node 14.17+ e em todos\n * os browsers/Edge runtimes modernos).\n * - Header `Idempotency-Key: <uuid>` é injetado pelo `httpRequest` quando\n * `opts.idempotencyKey === true` OU caller passa explicit `opts.idempotencyKeyValue`.\n * - Core dedup em coleção `usage_idempotency_keys/{key}` TTL 24h (vide\n * `docs/CORE_CHANGES_REQUIRED.md` §2). Se Core ainda não dedupa, o header\n * é benign (ignorado).\n *\n * Defesa em camadas: combinado com `retries: 0` em POSTs (vide http.ts), o\n * risco de double-write em transientes vai pra zero.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Gera UUID v4 criptograficamente seguro. Universal: Node 14.17+, browsers\n * modernos, Edge runtimes (Workers/Vercel Edge/Cloudflare).\n *\n * Fallback puro-JS removido em 3.0 — `crypto.randomUUID()` é ubíquo desde\n * 2022. Se runtime não tem, lança `NeetruError('runtime_unsupported')`\n * (consumer deve polyfillar).\n *\n * **L-01 fix (Opus review 2026-05-27):** antes lançava `Error` cru, que\n * não era pego por `catch (err) { if (err instanceof NeetruError) ... }`\n * dos consumers. Agora throw canonical.\n *\n * @throws NeetruError('runtime_unsupported') se `crypto.randomUUID` não disponível.\n */\nexport function generateIdempotencyKey(): string {\n // WebCrypto (browser/Edge) e Node 14.17+ expõem `crypto.randomUUID()`.\n // Node anterior precisa de `node:crypto` mas SDK 3.0 exige Node ≥20 (vide engines).\n const cryptoObj: { randomUUID?: () => string } | undefined =\n typeof globalThis !== 'undefined' && 'crypto' in globalThis\n ? (globalThis as { crypto?: { randomUUID?: () => string } }).crypto\n : undefined;\n if (cryptoObj && typeof cryptoObj.randomUUID === 'function') {\n return cryptoObj.randomUUID();\n }\n throw new NeetruError(\n 'runtime_unsupported',\n 'crypto.randomUUID not available in this runtime. SDK 3.0 requires Node ≥20 or modern browser/Edge.',\n );\n}\n\n/** Regex UUID v4 — validação para uso interno. */\nexport const UUID_V4_RE =\n /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n","/**\r\n * HTTP transport interno do SDK.\r\n *\r\n * Responsabilidades:\r\n * - Construir URL absoluta a partir de `baseUrl` + path\r\n * - Injetar Bearer token quando `requireAuth=true`\r\n * - Mapear status HTTP → `NeetruError` com `code` estável\r\n * - Parse defensivo de JSON (não lança em body vazio em 204)\r\n * - Retry/backoff exponencial em `rate_limited` (429), `server_error` (5xx)\r\n * e `network_error` (timeout/falha de rede). Honra `Retry-After` quando\r\n * presente.\r\n * - **Captura `X-Neetru-Version`** das respostas e emite `console.warn` quando\r\n * o Core está abaixo da versão mínima para a major do SDK.\r\n *\r\n * Política de retries (mudança breaking 3.0):\r\n * - GET/HEAD: default 2 retries (3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: default **0 retries** — mutations podem duplicar\r\n * side effects (ex: `usage.report` incrementa contador). Caller pode\r\n * reativar passando `retries: N` explicitamente ou usar `Idempotency-Key`\r\n * header (gerado automaticamente se `opts.idempotencyKey=true`).\r\n *\r\n * Idempotency-Key (3.0):\r\n * - `opts.idempotencyKey === true` → SDK gera UUID v4 e injeta header.\r\n * - `opts.idempotencyKey === 'uuid-string'` → usa o valor passado.\r\n * - Caller mantém retentos client-side se quiser; Core dedup serverside\r\n * (vide `docs/CORE_CHANGES_REQUIRED.md` §2).\r\n */\r\nimport { NeetruError, type NeetruErrorCode } from './errors';\r\nimport { generateIdempotencyKey } from './idempotency';\r\nimport type { ResolvedConfig } from './types';\r\n\r\n// ─── Compat Matrix SDK↔Core ──────────────────────────────────────────────────\r\n\r\n/**\r\n * Matriz de compatibilidade SDK major → versão mínima do Core.\r\n *\r\n * Formato do Core: CalVer `YYYY.MM.patch+revision` (ex: `2026.05.1+neetru-core-00096-79t`).\r\n * A comparação é feita apenas nas partes `YYYY.MM.patch` (prefixo antes de `+`).\r\n *\r\n * Quando o Core reporta `X-Neetru-Version` abaixo do mínimo para a SDK major\r\n * corrente, o SDK emite `console.warn` uma única vez por sessão de processo.\r\n *\r\n * Atualize esta tabela a cada major de SDK.\r\n */\r\nconst COMPAT_MATRIX: Record<number, string> = {\r\n // SDK major 3.x requer Core ≥ 2026.05.1 (suporte a X-Neetru-Version header,\r\n // runTransaction write-after-read, verifyWebhookRequest, webhooks 3.0+)\r\n 3: '2026.05.1',\r\n};\r\n\r\n/** CalVer sem sufixo `+revision`. Ex: `2026.05.1+abc` → `2026.05.1`. */\r\nfunction stripRevision(v: string): string {\r\n return v.split('+')[0] ?? v;\r\n}\r\n\r\n/**\r\n * Compara dois CalVer (`YYYY.MM.patch`). Retorna negativo se `a < b`,\r\n * positivo se `a > b`, 0 se iguais. Partes não numéricas tratadas como 0.\r\n */\r\nfunction compareCalVer(a: string, b: string): number {\r\n const partsA = stripRevision(a).split('.').map(Number);\r\n const partsB = stripRevision(b).split('.').map(Number);\r\n const len = Math.max(partsA.length, partsB.length);\r\n for (let i = 0; i < len; i++) {\r\n const pa = partsA[i] ?? 0;\r\n const pb = partsB[i] ?? 0;\r\n if (pa !== pb) return pa - pb;\r\n }\r\n return 0;\r\n}\r\n\r\n/** Lê a SDK major a partir da string `VERSION` exportada de `./index`. Fallback 3. */\r\nfunction getSdkMajor(): number {\r\n try {\r\n // Importação estática não disponível aqui (evita ciclo). Usa variável injetada\r\n // em tempo de build pela tsup via `define`. Fallback para 3 (current major).\r\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n const ver = (globalThis as any).__NEETRU_SDK_VERSION__ as string | undefined;\r\n if (ver) return parseInt(ver.split('.')[0] ?? '3', 10);\r\n } catch {\r\n // ignore\r\n }\r\n return 3;\r\n}\r\n\r\n/** Aviso emitido no máximo uma vez por major detectada pra não spammar logs. */\r\nconst _warnedCoreTooOld = new Set<string>();\r\n\r\n/**\r\n * Verifica se a versão do Core (`X-Neetru-Version`) é compatível com a SDK major.\r\n * Emite `console.warn` quando incompatível (uma vez por processo por versão detectada).\r\n */\r\nexport function checkCoreVersionCompat(coreVersion: string): void {\r\n if (!coreVersion) return;\r\n const sdkMajor = getSdkMajor();\r\n const minCore = COMPAT_MATRIX[sdkMajor];\r\n if (!minCore) return; // sem restrição para esta major\r\n const stripped = stripRevision(coreVersion);\r\n if (compareCalVer(stripped, minCore) < 0) {\r\n const key = `${sdkMajor}:${stripped}`;\r\n if (!_warnedCoreTooOld.has(key)) {\r\n _warnedCoreTooOld.add(key);\r\n console.warn(\r\n `[Neetru SDK] Atenção: Core versão \"${coreVersion}\" é anterior ao mínimo recomendado` +\r\n ` \"${minCore}\" para SDK major ${sdkMajor}. Alguns recursos podem não funcionar` +\r\n ` corretamente. Atualize o Core para a versão mais recente.`,\r\n );\r\n }\r\n }\r\n}\r\n\r\n/** Opções da request HTTP. */\r\nexport interface HttpRequestOptions {\r\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\r\n /** Path relativo (ex: `/api/v1/cli/catalog`). Concatenado a `baseUrl`. */\r\n path: string;\r\n /** Query string params (chave → valor primitivo). Valores `undefined` ignorados. */\r\n query?: Record<string, string | number | boolean | undefined>;\r\n /** Body JSON-serializável. Ignorado em GET/DELETE. */\r\n body?: unknown;\r\n /**\r\n * Se true, injeta `Authorization: Bearer <apiKey>`. Lança `missing_api_key`\r\n * se config.apiKey ausente. Default false.\r\n */\r\n requireAuth?: boolean;\r\n /** Cabeçalhos extras. */\r\n headers?: Record<string, string>;\r\n /**\r\n * Número de retries em códigos transientes (`rate_limited`, `server_error`,\r\n * `network_error`).\r\n *\r\n * Default (3.0):\r\n * - GET/HEAD: 2 (= 3 tentativas total) — idempotente, seguro.\r\n * - POST/PUT/PATCH/DELETE: 0 — mutations podem duplicar side effects.\r\n *\r\n * Caller pode reativar passando explicitamente: `retries: 2`.\r\n */\r\n retries?: number;\r\n /**\r\n * Injeta `Idempotency-Key` header pra dedup serverside (3.0):\r\n * - `true` → SDK gera UUID v4 cripto-seguro automaticamente.\r\n * - string → usa o valor passado (deve ser UUID v4).\r\n * - `undefined`/`false` → sem header.\r\n */\r\n idempotencyKey?: boolean | string;\r\n}\r\n\r\nconst DEFAULT_RETRIES_READ = 2;\r\nconst DEFAULT_RETRIES_WRITE = 0;\r\nconst READ_METHODS = new Set(['GET', 'HEAD']);\r\nconst RETRYABLE_CODES = new Set<NeetruErrorCode>([\r\n 'rate_limited',\r\n 'server_error',\r\n 'network_error',\r\n]);\r\n\r\n/** Backoff exponencial com jitter ±20%. attempt: 0=primeira, 1=primeiro retry, ... */\r\nfunction backoffMs(attempt: number): number {\r\n const base = 200 * Math.pow(4, attempt); // 200ms, 800ms, 3.2s, ...\r\n const jitter = base * 0.2 * (Math.random() * 2 - 1);\r\n return Math.max(50, Math.round(base + jitter));\r\n}\r\n\r\n/**\r\n * Honra `Retry-After` header (segundos ou HTTP-date). Retorna ms ou null se\r\n * inválido. RFC 9110 §10.2.3.\r\n *\r\n * Bug fix: sem teto, um servidor hostil/mal-configurado poderia retornar\r\n * `Retry-After: 86400` (24h) ou uma HTTP-date anos no futuro, pendurando o\r\n * processo indefinidamente. Aplica teto de MAX_RETRY_AFTER_MS em ambos os caminhos.\r\n */\r\nconst MAX_RETRY_AFTER_MS = 60_000; // 60s — teto razoável para retry automático\r\n\r\nfunction parseRetryAfter(value: string | null): number | null {\r\n if (!value) return null;\r\n const secs = Number(value);\r\n if (Number.isFinite(secs) && secs >= 0) return Math.min(Math.round(secs * 1000), MAX_RETRY_AFTER_MS);\r\n const dateMs = Date.parse(value);\r\n if (Number.isFinite(dateMs)) {\r\n const delta = dateMs - Date.now();\r\n if (delta > 0) return Math.min(delta, MAX_RETRY_AFTER_MS);\r\n }\r\n return null;\r\n}\r\n\r\nfunction sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n}\r\n\r\n/** Mapeamento status → code estável do NeetruError. */\r\nfunction statusToCode(status: number): NeetruErrorCode {\r\n if (status === 401) return 'unauthorized';\r\n if (status === 403) return 'forbidden';\r\n if (status === 404) return 'not_found';\r\n if (status === 409) return 'conflict'; // Bug fix: 409 vira 'conflict' (não 'unknown')\r\n if (status === 422 || status === 400) return 'validation_failed';\r\n if (status === 429) return 'rate_limited';\r\n if (status >= 500) return 'server_error';\r\n return 'unknown';\r\n}\r\n\r\nfunction buildUrl(baseUrl: string, path: string, query?: HttpRequestOptions['query']): string {\r\n // Trim trailing slash em base e leading em path pra evitar `//`.\r\n const base = baseUrl.replace(/\\/+$/, '');\r\n const p = path.startsWith('/') ? path : `/${path}`;\r\n const url = new URL(`${base}${p}`);\r\n if (query) {\r\n for (const [k, v] of Object.entries(query)) {\r\n if (v === undefined) continue;\r\n url.searchParams.set(k, String(v));\r\n }\r\n }\r\n return url.toString();\r\n}\r\n\r\n/** Parse JSON defensivo — retorna `undefined` em body vazio. */\r\nasync function safeJson(res: Response): Promise<unknown> {\r\n const text = await res.text();\r\n if (!text) return undefined;\r\n try {\r\n return JSON.parse(text);\r\n } catch {\r\n return undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Executa request HTTP. Em sucesso retorna body parseado; em erro lança\r\n * `NeetruError` com `code` derivado do status. Aplica retry/backoff\r\n * automático em códigos transientes (rate_limited/server_error/network_error)\r\n * conforme `opts.retries` (default 2 = 3 tentativas).\r\n */\r\nexport async function httpRequest<T>(\r\n config: ResolvedConfig,\r\n opts: HttpRequestOptions,\r\n): Promise<T> {\r\n const method = opts.method ?? 'GET';\r\n const url = buildUrl(config.baseUrl, opts.path, opts.query);\r\n // Default por método: reads tentam 2x, writes 0x. Caller override sempre vence.\r\n const defaultRetries = READ_METHODS.has(method)\r\n ? DEFAULT_RETRIES_READ\r\n : DEFAULT_RETRIES_WRITE;\r\n const maxRetries = opts.retries ?? defaultRetries;\r\n\r\n const headers: Record<string, string> = {\r\n accept: 'application/json',\r\n ...opts.headers,\r\n };\r\n\r\n if (opts.requireAuth) {\r\n if (!config.apiKey) {\r\n throw new NeetruError(\r\n 'missing_api_key',\r\n 'This operation requires an apiKey. Pass it to createNeetruClient({ apiKey }) or set NEETRU_API_KEY env var.',\r\n );\r\n }\r\n headers.authorization = `Bearer ${config.apiKey}`;\r\n }\r\n\r\n // Idempotency-Key: gerado por chamada se solicitado. UUID v4 cripto-seguro.\r\n if (opts.idempotencyKey) {\r\n const key =\r\n typeof opts.idempotencyKey === 'string'\r\n ? opts.idempotencyKey\r\n : generateIdempotencyKey();\r\n headers['idempotency-key'] = key;\r\n }\r\n\r\n // Body só é serializado uma vez — reusado entre tentativas.\r\n const bodyString =\r\n opts.body !== undefined && method !== 'GET' && method !== 'DELETE'\r\n ? JSON.stringify(opts.body)\r\n : undefined;\r\n if (bodyString !== undefined) {\r\n headers['content-type'] = 'application/json';\r\n }\r\n\r\n let lastError: NeetruError | null = null;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n const init: RequestInit = { method, headers };\r\n if (bodyString !== undefined) init.body = bodyString;\r\n // BUG-020 fix (2026-05-13): timeout default 30s. AbortSignal.timeout\r\n // requer Node 18+ ou browsers recentes.\r\n init.signal = AbortSignal.timeout(30_000);\r\n\r\n let res: Response;\r\n try {\r\n res = await config.fetch(url, init);\r\n } catch (err) {\r\n const message =\r\n err instanceof DOMException && err.name === 'TimeoutError'\r\n ? 'Network error: timeout after 30s'\r\n : `Network error: ${err instanceof Error ? err.message : 'fetch failed'}`;\r\n lastError = new NeetruError('network_error', message);\r\n if (attempt < maxRetries) {\r\n await sleep(backoffMs(attempt));\r\n continue;\r\n }\r\n throw lastError;\r\n }\r\n\r\n const requestId =\r\n res.headers.get('x-request-id') ?? res.headers.get('x-correlation-id') ?? undefined;\r\n\r\n if (res.ok) {\r\n // Captura X-Neetru-Version e verifica compat com a SDK major.\r\n const coreVersion = res.headers.get('x-neetru-version');\r\n if (coreVersion) checkCoreVersionCompat(coreVersion);\r\n const parsed = await safeJson(res);\r\n return parsed as T;\r\n }\r\n\r\n const body = (await safeJson(res)) as\r\n | { error?: { code?: string; message?: string } | string }\r\n | undefined;\r\n let code: string = statusToCode(res.status);\r\n let message = `HTTP ${res.status}`;\r\n if (body && typeof body === 'object' && 'error' in body) {\r\n const errField = body.error;\r\n if (typeof errField === 'string') {\r\n message = errField;\r\n } else if (errField && typeof errField === 'object') {\r\n if (typeof errField.code === 'string') code = errField.code;\r\n if (typeof errField.message === 'string') message = errField.message;\r\n }\r\n }\r\n const err = new NeetruError(code, message, res.status, requestId);\r\n lastError = err;\r\n\r\n const isRetryable = RETRYABLE_CODES.has(code as NeetruErrorCode);\r\n if (isRetryable && attempt < maxRetries) {\r\n const retryAfter = parseRetryAfter(res.headers.get('retry-after'));\r\n const delay = retryAfter ?? backoffMs(attempt);\r\n await sleep(delay);\r\n continue;\r\n }\r\n throw err;\r\n }\r\n\r\n // Unreachable — loop sempre retorna ou lança. Safety net.\r\n throw lastError ?? new NeetruError('unknown', 'unexpected httpRequest exit');\r\n}\r\n","/**\n * Validators centralizados pra inputs do SDK que precisam casar com\n * regex do Core.\n *\n * **M-03 fix (Opus review 2026-05-27):** o Core rejeita productId que\n * não bate `/^[a-z0-9][a-z0-9_-]{0,62}$/` com 400 `validation_failed`.\n * O SDK não pré-validava — consumer recebia erro só em runtime de\n * produção, depois do round-trip de rede. Agora SDK throws localmente\n * antes do fetch.\n */\nimport { NeetruError } from './errors';\n\n/**\n * Regex canonical de IDs no Neetru Core (productId, tenantId, etc).\n * Espelha `SDK_ID_RE` em `neetru_core/src/lib/schemas/sdk.ts`.\n */\nexport const SDK_ID_RE = /^[a-z0-9][a-z0-9_-]{0,62}$/;\n\n/**\n * Throws `NeetruError('validation_failed')` se `value` não bater no\n * formato canonical.\n *\n * @example\n * ```ts\n * assertValidSdkId('productId', 'gestovendas'); // ok\n * assertValidSdkId('productId', 'GestoVendas'); // throws\n * ```\n */\nexport function assertValidSdkId(field: string, value: string): void {\n if (typeof value !== 'string' || !SDK_ID_RE.test(value)) {\n throw new NeetruError(\n 'validation_failed',\n `${field} must match ${SDK_ID_RE.source} (lowercase alphanumeric, _, -; first char must be alphanumeric; max 63 chars)`,\n );\n }\n}\n","/**\r\n * Notifications namespace (v1.2) — produtos SaaS enviam notificações in-app\r\n * pros SEUS usuários (distinto das `notifications/` staff-only do Core).\r\n *\r\n * Caso típico: produto gestovendas notifica usuário \"Pedido #X recebido\" no\r\n * portal sem precisar manter a própria coleção Firestore.\r\n *\r\n * Schema isolado por produto: `product_user_notifications/{productId}/{notifId}`.\r\n * Owner Neetru não vê o conteúdo (privacidade do produto), mas o Core\r\n * armazena + serve a leitura. Produto pode também listar via SDK.\r\n *\r\n * Endpoints REST (em prod):\r\n * - `POST /api/sdk/v1/notifications` — produto envia\r\n * - `GET /api/sdk/v1/notifications/user/{userId}` — produto lista do user\r\n * - `POST /api/sdk/v1/notifications/{id}/read` — user marca lida (proxy)\r\n * - `POST /api/sdk/v1/notifications/{id}/dismiss` — user descarta (proxy)\r\n *\r\n * Severidade canônica: `info | success | warning | error`.\r\n *\r\n * Mock em `NEETRU_ENV=dev`: in-memory.\r\n */\r\nimport { NeetruError } from './errors';\r\nimport { httpRequest } from './http';\r\nimport { assertValidSdkId } from './validators';\r\nimport type { ResolvedConfig } from './types';\r\n\r\nexport type ProductNotificationSeverity =\r\n | 'info'\r\n | 'success'\r\n | 'warning'\r\n | 'error';\r\n\r\nexport interface ProductNotification {\r\n id: string;\r\n /** UID do usuário final (do produto, não staff Neetru). */\r\n userId: string;\r\n /** Identificador semântico do evento (ex: `order.received`). */\r\n kind: string;\r\n severity: ProductNotificationSeverity;\r\n title: string;\r\n body?: string;\r\n /** Link opcional pra ação. */\r\n link?: string;\r\n /** Metadata livre (serializável). */\r\n metadata?: Record<string, string | number | boolean | null>;\r\n createdAt: string;\r\n /** ISO quando user marcou lida. */\r\n readAt?: string;\r\n /** ISO quando user descartou. */\r\n dismissedAt?: string;\r\n}\r\n\r\nexport interface SendNotificationInput {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório (Core valida via Zod). Default\r\n * resolve do `config.productId`; lança `validation_failed` se ausente.\r\n */\r\n productId?: string;\r\n userId: string;\r\n kind: string;\r\n title: string;\r\n severity?: ProductNotificationSeverity;\r\n body?: string;\r\n link?: string;\r\n metadata?: Record<string, string | number | boolean | null>;\r\n /**\r\n * Dedup — se já existir notificação com mesmo fingerprint dentro de 24h,\r\n * NÃO cria duplicata. Útil pra evitar spam quando webhook reentrega.\r\n */\r\n fingerprint?: string;\r\n}\r\n\r\nexport interface ListNotificationsOptions {\r\n /**\r\n * **3.0 (breaking):** productId é obrigatório no Core. Default resolve do\r\n * `config.productId`.\r\n */\r\n productId?: string;\r\n /** Inclui notificações dismissed (default false). */\r\n includeDismissed?: boolean;\r\n /** Filtro por unread. */\r\n onlyUnread?: boolean;\r\n /** Máx itens (default 50, máx 200). */\r\n limit?: number;\r\n}\r\n\r\n/** 3.0: scope option pra markRead/dismiss (productId obrigatório no Core). */\r\nexport interface NotificationScopeOptions {\r\n productId?: string;\r\n}\r\n\r\nexport interface NotificationsNamespace {\r\n /** Produto envia uma notificação pra um usuário do produto. */\r\n send(input: SendNotificationInput): Promise<ProductNotification>;\r\n /** Lista notificações de um usuário. */\r\n list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]>;\r\n /** Marca como lida. */\r\n markRead(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n /** Descarta. */\r\n dismiss(id: string, options?: NotificationScopeOptions): Promise<{ ok: true }>;\r\n}\r\n\r\n// ─── HTTP impl ──────────────────────────────────────────────────────────────\r\n\r\nconst VALID_SEVERITIES: readonly ProductNotificationSeverity[] = [\r\n 'info',\r\n 'success',\r\n 'warning',\r\n 'error',\r\n];\r\n\r\nfunction toNotification(raw: unknown): ProductNotification {\r\n if (!raw || typeof raw !== 'object') {\r\n throw new NeetruError('invalid_response', 'Notification response is not an object');\r\n }\r\n const r = raw as Record<string, unknown>;\r\n if (typeof r.id !== 'string') {\r\n throw new NeetruError('invalid_response', 'Notification missing id');\r\n }\r\n const sev = VALID_SEVERITIES.includes(r.severity as ProductNotificationSeverity)\r\n ? (r.severity as ProductNotificationSeverity)\r\n : 'info';\r\n return {\r\n id: r.id,\r\n userId: typeof r.userId === 'string' ? r.userId : '',\r\n kind: typeof r.kind === 'string' ? r.kind : 'unknown',\r\n severity: sev,\r\n title: typeof r.title === 'string' ? r.title : '',\r\n body: typeof r.body === 'string' ? r.body : undefined,\r\n link: typeof r.link === 'string' ? r.link : undefined,\r\n metadata:\r\n r.metadata && typeof r.metadata === 'object'\r\n ? (r.metadata as Record<string, string | number | boolean | null>)\r\n : undefined,\r\n createdAt: typeof r.createdAt === 'string' ? r.createdAt : new Date().toISOString(),\r\n readAt: typeof r.readAt === 'string' ? r.readAt : undefined,\r\n dismissedAt: typeof r.dismissedAt === 'string' ? r.dismissedAt : undefined,\r\n };\r\n}\r\n\r\nfunction validateInput(input: SendNotificationInput): void {\r\n if (!input.userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n if (!input.kind) throw new NeetruError('validation_failed', 'kind obrigatório');\r\n if (!input.title) throw new NeetruError('validation_failed', 'title obrigatório');\r\n if (input.severity && !VALID_SEVERITIES.includes(input.severity)) {\r\n throw new NeetruError(\r\n 'validation_failed',\r\n `severity inválida: ${input.severity} (use ${VALID_SEVERITIES.join('|')})`,\r\n );\r\n }\r\n if (input.title.length > 200) {\r\n throw new NeetruError('validation_failed', 'title máx 200 chars');\r\n }\r\n if (input.body && input.body.length > 2000) {\r\n throw new NeetruError('validation_failed', 'body máx 2000 chars');\r\n }\r\n}\r\n\r\n/** Resolve productId fail-closed (option > input > config).\r\n *\r\n * **M-03 fix (Opus review 2026-05-27):** valida client-side contra `SDK_ID_RE`. */\r\nfunction resolveProductId(\r\n config: ResolvedConfig,\r\n ...candidates: Array<string | undefined>\r\n): string {\r\n for (const c of candidates) {\r\n if (typeof c === 'string' && c.length > 0) {\r\n assertValidSdkId('productId', c);\r\n return c;\r\n }\r\n }\r\n if (config.productId) {\r\n assertValidSdkId('productId', config.productId);\r\n return config.productId;\r\n }\r\n throw new NeetruError(\r\n 'validation_failed',\r\n 'productId required (pass to options/input or set on createNeetruClient)',\r\n );\r\n}\r\n\r\nexport function createNotificationsNamespace(\r\n config: ResolvedConfig,\r\n): NotificationsNamespace {\r\n return {\r\n async send(input) {\r\n validateInput(input);\r\n const productId = resolveProductId(config, input.productId);\r\n const body: Record<string, unknown> = {\r\n productId,\r\n userId: input.userId,\r\n kind: input.kind,\r\n title: input.title,\r\n severity: input.severity ?? 'info',\r\n };\r\n if (input.body !== undefined) body.body = input.body;\r\n if (input.link !== undefined) body.link = input.link;\r\n if (input.metadata !== undefined) body.metadata = input.metadata;\r\n if (input.fingerprint !== undefined) body.fingerprint = input.fingerprint;\r\n const raw = await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: '/api/sdk/v1/notifications',\r\n body,\r\n requireAuth: true,\r\n idempotencyKey: true,\r\n });\r\n return toNotification(raw);\r\n },\r\n async list(userId, options) {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n const query: Record<string, string | number | boolean | undefined> = {\r\n productId,\r\n };\r\n if (options?.includeDismissed) query.includeDismissed = true;\r\n if (options?.onlyUnread) query.onlyUnread = true;\r\n if (options?.limit) {\r\n query.limit = Math.min(Math.max(1, options.limit), 200);\r\n }\r\n const raw = await httpRequest<{ notifications?: unknown[] }>(config, {\r\n method: 'GET',\r\n path: `/api/sdk/v1/notifications/user/${encodeURIComponent(userId)}`,\r\n query,\r\n requireAuth: true,\r\n });\r\n const list = Array.isArray(raw?.notifications) ? raw.notifications : [];\r\n return list.map(toNotification);\r\n },\r\n async markRead(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/read`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n async dismiss(id, options) {\r\n if (!id) throw new NeetruError('validation_failed', 'id obrigatório');\r\n const productId = resolveProductId(config, options?.productId);\r\n await httpRequest<unknown>(config, {\r\n method: 'POST',\r\n path: `/api/sdk/v1/notifications/${encodeURIComponent(id)}/dismiss`,\r\n query: { productId },\r\n requireAuth: true,\r\n });\r\n return { ok: true };\r\n },\r\n };\r\n}\r\n\r\n// ─── Mock impl ──────────────────────────────────────────────────────────────\r\n\r\nexport class MockNotifications implements NotificationsNamespace {\r\n private notifications = new Map<string, ProductNotification>();\r\n private nextId = 1;\r\n\r\n async send(input: SendNotificationInput): Promise<ProductNotification> {\r\n validateInput(input);\r\n // Dedup por fingerprint: se já existe um com mesmo fingerprint < 24h, retorna ele.\r\n if (input.fingerprint) {\r\n const dayAgo = Date.now() - 86_400_000;\r\n for (const existing of this.notifications.values()) {\r\n const meta = existing.metadata ?? {};\r\n if (\r\n meta.fingerprint === input.fingerprint &&\r\n existing.userId === input.userId &&\r\n new Date(existing.createdAt).getTime() > dayAgo\r\n ) {\r\n return existing;\r\n }\r\n }\r\n }\r\n const id = `mock_notif_${this.nextId++}`;\r\n const notif: ProductNotification = {\r\n id,\r\n userId: input.userId,\r\n kind: input.kind,\r\n severity: input.severity ?? 'info',\r\n title: input.title,\r\n body: input.body,\r\n link: input.link,\r\n metadata: input.fingerprint\r\n ? { ...(input.metadata ?? {}), fingerprint: input.fingerprint }\r\n : input.metadata,\r\n createdAt: new Date().toISOString(),\r\n };\r\n this.notifications.set(id, notif);\r\n return notif;\r\n }\r\n\r\n async list(\r\n userId: string,\r\n options?: ListNotificationsOptions,\r\n ): Promise<ProductNotification[]> {\r\n if (!userId) throw new NeetruError('validation_failed', 'userId obrigatório');\r\n const limit = Math.min(Math.max(1, options?.limit ?? 50), 200);\r\n return [...this.notifications.values()]\r\n .filter((n) => n.userId === userId)\r\n .filter((n) => options?.includeDismissed || !n.dismissedAt)\r\n .filter((n) => !options?.onlyUnread || !n.readAt)\r\n .sort((a, b) => b.createdAt.localeCompare(a.createdAt))\r\n .slice(0, limit);\r\n }\r\n\r\n async markRead(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.readAt) {\r\n n.readAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n\r\n async dismiss(id: string, _options?: NotificationScopeOptions): Promise<{ ok: true }> {\r\n const n = this.notifications.get(id);\r\n if (!n) throw new NeetruError('not_found', `Notification ${id} não encontrada`);\r\n if (!n.dismissedAt) {\r\n n.dismissedAt = new Date().toISOString();\r\n this.notifications.set(id, n);\r\n }\r\n return { ok: true };\r\n }\r\n}\r\n"]}
package/dist/react.cjs CHANGED
@@ -47,7 +47,6 @@ function toDbQuery(constraints) {
47
47
  return out;
48
48
  }
49
49
  function normalizeOp(op) {
50
- if (op === "array-contains-any") return "array-contains";
51
50
  return op;
52
51
  }
53
52
 
@@ -151,9 +150,9 @@ function EntitlementGate({
151
150
  if (!cancelled) setState({ status: "ready", result: result2 });
152
151
  } catch (err) {
153
152
  if (!cancelled) {
154
- setState({ status: "ready", result: { allowed: false, reason: "check_failed" } });
153
+ setState({ status: "ready", result: { allowed: true, reason: "check_error_fallback" } });
155
154
  }
156
- if (typeof console !== "undefined") console.warn("[EntitlementGate] check failed", err);
155
+ if (typeof console !== "undefined") console.warn("[EntitlementGate] check failed \u2014 fail-open", err);
157
156
  }
158
157
  };
159
158
  run();