@notifica/node 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1705 @@
1
+ // src/errors.ts
2
+ var NotificaError = class extends Error {
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "NotificaError";
6
+ Object.setPrototypeOf(this, new.target.prototype);
7
+ }
8
+ };
9
+ var ApiError = class extends NotificaError {
10
+ /** HTTP status code */
11
+ status;
12
+ /** Código do erro retornado pela API (ex: "validation_failed") */
13
+ code;
14
+ /** Detalhes de validação por campo */
15
+ details;
16
+ /** ID da request para suporte/debugging */
17
+ requestId;
18
+ constructor(message, status, code, details = {}, requestId = null) {
19
+ super(message);
20
+ this.name = "ApiError";
21
+ this.status = status;
22
+ this.code = code;
23
+ this.details = details;
24
+ this.requestId = requestId;
25
+ }
26
+ };
27
+ var ValidationError = class extends ApiError {
28
+ constructor(message, details = {}, requestId = null) {
29
+ super(message, 422, "validation_failed", details, requestId);
30
+ this.name = "ValidationError";
31
+ }
32
+ };
33
+ var RateLimitError = class extends ApiError {
34
+ /** Segundos até poder tentar novamente */
35
+ retryAfter;
36
+ constructor(message, retryAfter = null, requestId = null) {
37
+ super(message, 429, "rate_limit_exceeded", {}, requestId);
38
+ this.name = "RateLimitError";
39
+ this.retryAfter = retryAfter;
40
+ }
41
+ };
42
+ var TimeoutError = class extends NotificaError {
43
+ constructor(timeoutMs) {
44
+ super(`Request timed out after ${timeoutMs}ms`);
45
+ this.name = "TimeoutError";
46
+ }
47
+ };
48
+
49
+ // src/client.ts
50
+ var DEFAULT_BASE_URL = "https://app.usenotifica.com.br/v1";
51
+ var DEFAULT_TIMEOUT = 3e4;
52
+ var DEFAULT_MAX_RETRIES = 3;
53
+ var RETRYABLE_STATUS_CODES = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
54
+ var NotificaClient = class {
55
+ apiKey;
56
+ baseUrl;
57
+ timeout;
58
+ maxRetries;
59
+ autoIdempotency;
60
+ constructor(config) {
61
+ if (!config.apiKey) {
62
+ throw new NotificaError(
63
+ 'API key \xE9 obrigat\xF3ria. Passe via: new Notifica("nk_live_...")'
64
+ );
65
+ }
66
+ this.apiKey = config.apiKey;
67
+ this.baseUrl = (config.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
68
+ this.timeout = config.timeout ?? DEFAULT_TIMEOUT;
69
+ this.maxRetries = config.maxRetries ?? DEFAULT_MAX_RETRIES;
70
+ this.autoIdempotency = config.autoIdempotency ?? true;
71
+ }
72
+ // ── Public methods ──────────────────────────────────
73
+ async get(path, query, options) {
74
+ return this.request("GET", path, void 0, query, options);
75
+ }
76
+ async post(path, body, options) {
77
+ return this.request("POST", path, body, void 0, options);
78
+ }
79
+ async put(path, body, options) {
80
+ return this.request("PUT", path, body, void 0, options);
81
+ }
82
+ async patch(path, body, options) {
83
+ return this.request("PATCH", path, body, void 0, options);
84
+ }
85
+ async delete(path, options) {
86
+ return this.request("DELETE", path, void 0, void 0, options);
87
+ }
88
+ // ── Pagination helpers ──────────────────────────────
89
+ /**
90
+ * Lista com paginação manual.
91
+ * Retorna { data, meta } com cursor para próxima página.
92
+ */
93
+ async list(path, query, options) {
94
+ return this.get(path, query, options);
95
+ }
96
+ /**
97
+ * Async iterator para auto-paginação.
98
+ *
99
+ * @example
100
+ * ```ts
101
+ * for await (const notification of client.paginate<Notification>('/notifications')) {
102
+ * console.log(notification.id);
103
+ * }
104
+ * ```
105
+ */
106
+ async *paginate(path, query) {
107
+ let cursor;
108
+ do {
109
+ const params = { ...query, ...cursor ? { cursor } : {} };
110
+ const response = await this.list(path, params);
111
+ for (const item of response.data) {
112
+ yield item;
113
+ }
114
+ cursor = response.meta.has_more && response.meta.cursor ? response.meta.cursor : void 0;
115
+ } while (cursor);
116
+ }
117
+ /**
118
+ * Wrapper para respostas { data: T }.
119
+ */
120
+ async getOne(path, options) {
121
+ const response = await this.get(path, void 0, options);
122
+ return response.data;
123
+ }
124
+ // ── Private methods ─────────────────────────────────
125
+ async request(method, path, body, query, options) {
126
+ const url = this.buildUrl(path, query);
127
+ const headers = this.buildHeaders(method, options);
128
+ const timeoutMs = options?.timeout ?? this.timeout;
129
+ let lastError;
130
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
131
+ if (attempt > 0) {
132
+ await this.backoff(attempt, lastError);
133
+ }
134
+ const controller = new AbortController();
135
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
136
+ if (options?.signal) {
137
+ if (options.signal.aborted) {
138
+ clearTimeout(timeoutId);
139
+ throw new NotificaError("Request aborted");
140
+ }
141
+ options.signal.addEventListener("abort", () => controller.abort(), { once: true });
142
+ }
143
+ try {
144
+ const response = await fetch(url, {
145
+ method,
146
+ headers,
147
+ body: body !== void 0 ? JSON.stringify(body) : void 0,
148
+ signal: controller.signal
149
+ });
150
+ clearTimeout(timeoutId);
151
+ if (response.ok) {
152
+ if (response.status === 204) {
153
+ return void 0;
154
+ }
155
+ return await response.json();
156
+ }
157
+ const errorBody = await this.safeParseJson(response);
158
+ const requestId = response.headers.get("x-request-id");
159
+ if (response.status === 429) {
160
+ const retryAfter = this.parseRetryAfter(response);
161
+ const error = new RateLimitError(
162
+ errorBody?.error?.message ?? "Rate limit exceeded",
163
+ retryAfter,
164
+ requestId
165
+ );
166
+ if (attempt < this.maxRetries) {
167
+ lastError = error;
168
+ continue;
169
+ }
170
+ throw error;
171
+ }
172
+ if (RETRYABLE_STATUS_CODES.has(response.status) && attempt < this.maxRetries) {
173
+ lastError = new ApiError(
174
+ errorBody?.error?.message ?? `Server error (${response.status})`,
175
+ response.status,
176
+ errorBody?.error?.code ?? "server_error",
177
+ errorBody?.error?.details ?? {},
178
+ requestId
179
+ );
180
+ continue;
181
+ }
182
+ if (response.status === 422) {
183
+ throw new ValidationError(
184
+ errorBody?.error?.message ?? "Validation failed",
185
+ errorBody?.error?.details ?? {},
186
+ requestId
187
+ );
188
+ }
189
+ throw new ApiError(
190
+ errorBody?.error?.message ?? `API error (${response.status})`,
191
+ response.status,
192
+ errorBody?.error?.code ?? "api_error",
193
+ errorBody?.error?.details ?? {},
194
+ requestId
195
+ );
196
+ } catch (error) {
197
+ clearTimeout(timeoutId);
198
+ if (error instanceof NotificaError) {
199
+ throw error;
200
+ }
201
+ if (error instanceof Error && error.name === "AbortError") {
202
+ if (attempt < this.maxRetries) {
203
+ lastError = new TimeoutError(timeoutMs);
204
+ continue;
205
+ }
206
+ throw new TimeoutError(timeoutMs);
207
+ }
208
+ if (attempt < this.maxRetries) {
209
+ lastError = error instanceof Error ? error : new Error(String(error));
210
+ continue;
211
+ }
212
+ throw new NotificaError(
213
+ `Request failed: ${error instanceof Error ? error.message : String(error)}`
214
+ );
215
+ }
216
+ }
217
+ throw lastError ?? new NotificaError("Request failed after max retries");
218
+ }
219
+ buildUrl(path, query) {
220
+ const url = new URL(`${this.baseUrl}${path}`);
221
+ if (query) {
222
+ for (const [key, value] of Object.entries(query)) {
223
+ if (value !== void 0 && value !== null) {
224
+ url.searchParams.set(key, String(value));
225
+ }
226
+ }
227
+ }
228
+ return url.toString();
229
+ }
230
+ buildHeaders(method, options) {
231
+ const headers = {
232
+ "Authorization": `Bearer ${this.apiKey}`,
233
+ "Content-Type": "application/json",
234
+ "Accept": "application/json",
235
+ "User-Agent": "@notifica/node/0.1.0"
236
+ };
237
+ if (method === "POST") {
238
+ if (options?.idempotencyKey) {
239
+ headers["Idempotency-Key"] = options.idempotencyKey;
240
+ } else if (this.autoIdempotency) {
241
+ headers["Idempotency-Key"] = this.generateIdempotencyKey();
242
+ }
243
+ }
244
+ return headers;
245
+ }
246
+ generateIdempotencyKey() {
247
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
248
+ return crypto.randomUUID();
249
+ }
250
+ return `${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
251
+ }
252
+ async backoff(attempt, lastError) {
253
+ let delayMs;
254
+ if (lastError instanceof RateLimitError && lastError.retryAfter !== null) {
255
+ delayMs = lastError.retryAfter * 1e3;
256
+ } else {
257
+ const base = 500 * Math.pow(2, attempt - 1);
258
+ const jitter = Math.random() * base * 0.5;
259
+ delayMs = base + jitter;
260
+ }
261
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
262
+ }
263
+ parseRetryAfter(response) {
264
+ const header = response.headers.get("retry-after");
265
+ if (!header) return null;
266
+ const seconds = Number(header);
267
+ if (!Number.isNaN(seconds)) return seconds;
268
+ const date = Date.parse(header);
269
+ if (!Number.isNaN(date)) {
270
+ return Math.max(0, Math.ceil((date - Date.now()) / 1e3));
271
+ }
272
+ return null;
273
+ }
274
+ async safeParseJson(response) {
275
+ try {
276
+ return await response.json();
277
+ } catch {
278
+ return null;
279
+ }
280
+ }
281
+ };
282
+
283
+ // src/resources/notifications.ts
284
+ var Notifications = class {
285
+ client;
286
+ constructor(client) {
287
+ this.client = client;
288
+ }
289
+ /**
290
+ * Envia uma notificação.
291
+ * A notificação é enfileirada para entrega assíncrona.
292
+ *
293
+ * @example
294
+ * ```ts
295
+ * const notification = await notifica.notifications.send({
296
+ * channel: 'whatsapp',
297
+ * to: '+5511999999999',
298
+ * template: 'welcome',
299
+ * data: { name: 'João' },
300
+ * });
301
+ * ```
302
+ */
303
+ async send(params, options) {
304
+ const response = await this.client.post(
305
+ "/notifications",
306
+ params,
307
+ options
308
+ );
309
+ return response.data;
310
+ }
311
+ /**
312
+ * Lista notificações com paginação.
313
+ *
314
+ * @example
315
+ * ```ts
316
+ * const { data, meta } = await notifica.notifications.list({ channel: 'email', limit: 50 });
317
+ * ```
318
+ */
319
+ async list(params, options) {
320
+ return this.client.list("/notifications", params, options);
321
+ }
322
+ /**
323
+ * Itera automaticamente por todas as notificações.
324
+ *
325
+ * @example
326
+ * ```ts
327
+ * for await (const notification of notifica.notifications.listAll({ channel: 'email' })) {
328
+ * console.log(notification.id);
329
+ * }
330
+ * ```
331
+ */
332
+ listAll(params) {
333
+ return this.client.paginate("/notifications", params);
334
+ }
335
+ /**
336
+ * Obtém detalhes de uma notificação.
337
+ */
338
+ async get(id, options) {
339
+ return this.client.getOne(`/notifications/${id}`, options);
340
+ }
341
+ /**
342
+ * Lista tentativas de entrega de uma notificação.
343
+ */
344
+ async listAttempts(notificationId, options) {
345
+ const response = await this.client.get(
346
+ `/notifications/${notificationId}/attempts`,
347
+ void 0,
348
+ options
349
+ );
350
+ return response.data;
351
+ }
352
+ };
353
+
354
+ // src/resources/templates.ts
355
+ var Templates = class {
356
+ client;
357
+ constructor(client) {
358
+ this.client = client;
359
+ }
360
+ /**
361
+ * Cria um novo template.
362
+ *
363
+ * @example
364
+ * ```ts
365
+ * const template = await notifica.templates.create({
366
+ * channel: 'email',
367
+ * slug: 'welcome-email',
368
+ * name: 'Email de Boas-Vindas',
369
+ * content: 'Olá {{name}}, bem-vindo!',
370
+ * });
371
+ * ```
372
+ */
373
+ async create(params, options) {
374
+ const response = await this.client.post(
375
+ "/templates",
376
+ params,
377
+ options
378
+ );
379
+ return response.data;
380
+ }
381
+ /**
382
+ * Lista templates com paginação.
383
+ */
384
+ async list(params, options) {
385
+ return this.client.list("/templates", params, options);
386
+ }
387
+ /**
388
+ * Itera automaticamente por todos os templates.
389
+ */
390
+ listAll(params) {
391
+ return this.client.paginate("/templates", params);
392
+ }
393
+ /**
394
+ * Obtém detalhes de um template.
395
+ */
396
+ async get(id, options) {
397
+ return this.client.getOne(`/templates/${id}`, options);
398
+ }
399
+ /**
400
+ * Atualiza um template.
401
+ */
402
+ async update(id, params, options) {
403
+ const response = await this.client.put(
404
+ `/templates/${id}`,
405
+ params,
406
+ options
407
+ );
408
+ return response.data;
409
+ }
410
+ /**
411
+ * Deleta um template.
412
+ */
413
+ async delete(id, options) {
414
+ await this.client.delete(`/templates/${id}`, options);
415
+ }
416
+ /**
417
+ * Preview de um template salvo com variáveis.
418
+ *
419
+ * @example
420
+ * ```ts
421
+ * const preview = await notifica.templates.preview('tpl_abc', {
422
+ * variables: { name: 'João' },
423
+ * });
424
+ * ```
425
+ */
426
+ async preview(id, params, options) {
427
+ const response = await this.client.post(
428
+ `/templates/${id}/preview`,
429
+ params,
430
+ options
431
+ );
432
+ return response.data;
433
+ }
434
+ /**
435
+ * Preview de conteúdo arbitrário (útil para editor em tempo real).
436
+ */
437
+ async previewContent(params, options) {
438
+ const response = await this.client.post(
439
+ "/templates/preview",
440
+ params,
441
+ options
442
+ );
443
+ return response.data;
444
+ }
445
+ /**
446
+ * Valida um template salvo.
447
+ */
448
+ async validate(id, options) {
449
+ const response = await this.client.post(
450
+ `/templates/${id}/validate`,
451
+ void 0,
452
+ options
453
+ );
454
+ return response.data;
455
+ }
456
+ /**
457
+ * Valida conteúdo arbitrário.
458
+ */
459
+ async validateContent(params, options) {
460
+ const response = await this.client.post(
461
+ "/templates/validate",
462
+ params,
463
+ options
464
+ );
465
+ return response.data;
466
+ }
467
+ };
468
+
469
+ // src/resources/workflows.ts
470
+ var Workflows = class {
471
+ client;
472
+ constructor(client) {
473
+ this.client = client;
474
+ }
475
+ /**
476
+ * Cria um novo workflow.
477
+ *
478
+ * @example
479
+ * ```ts
480
+ * const workflow = await notifica.workflows.create({
481
+ * slug: 'welcome-flow',
482
+ * name: 'Fluxo de Boas-Vindas',
483
+ * steps: [
484
+ * { type: 'send', channel: 'email', template: 'welcome-email' },
485
+ * { type: 'delay', duration: '1h' },
486
+ * { type: 'send', channel: 'whatsapp', template: 'welcome-whatsapp' },
487
+ * ],
488
+ * });
489
+ * ```
490
+ */
491
+ async create(params, options) {
492
+ const response = await this.client.post(
493
+ "/workflows",
494
+ params,
495
+ options
496
+ );
497
+ return response.data;
498
+ }
499
+ /**
500
+ * Lista workflows com paginação.
501
+ */
502
+ async list(params, options) {
503
+ return this.client.list("/workflows", params, options);
504
+ }
505
+ /**
506
+ * Itera automaticamente por todos os workflows.
507
+ */
508
+ listAll(params) {
509
+ return this.client.paginate("/workflows", params);
510
+ }
511
+ /**
512
+ * Obtém detalhes de um workflow.
513
+ */
514
+ async get(id, options) {
515
+ return this.client.getOne(`/workflows/${id}`, options);
516
+ }
517
+ /**
518
+ * Atualiza um workflow (cria nova versão).
519
+ */
520
+ async update(id, params, options) {
521
+ const response = await this.client.put(
522
+ `/workflows/${id}`,
523
+ params,
524
+ options
525
+ );
526
+ return response.data;
527
+ }
528
+ /**
529
+ * Deleta um workflow (soft delete).
530
+ */
531
+ async delete(id, options) {
532
+ await this.client.delete(`/workflows/${id}`, options);
533
+ }
534
+ /**
535
+ * Dispara a execução de um workflow.
536
+ *
537
+ * @param slug — Slug do workflow
538
+ * @param params — Recipient e dados
539
+ *
540
+ * @example
541
+ * ```ts
542
+ * const run = await notifica.workflows.trigger('welcome-flow', {
543
+ * recipient: '+5511999999999',
544
+ * data: { name: 'João', plan: 'pro' },
545
+ * });
546
+ * ```
547
+ */
548
+ async trigger(slug, params, options) {
549
+ const response = await this.client.post(
550
+ `/workflows/${slug}/trigger`,
551
+ params,
552
+ options
553
+ );
554
+ return response.data;
555
+ }
556
+ // ── Workflow Runs ───────────────────────────────────
557
+ /**
558
+ * Lista execuções de workflows.
559
+ */
560
+ async listRuns(params, options) {
561
+ return this.client.list("/workflow-runs", params, options);
562
+ }
563
+ /**
564
+ * Obtém detalhes de uma execução (incluindo step_results).
565
+ */
566
+ async getRun(id, options) {
567
+ return this.client.getOne(`/workflow-runs/${id}`, options);
568
+ }
569
+ /**
570
+ * Cancela uma execução em andamento.
571
+ */
572
+ async cancelRun(id, options) {
573
+ const response = await this.client.post(
574
+ `/workflow-runs/${id}/cancel`,
575
+ void 0,
576
+ options
577
+ );
578
+ return response.data;
579
+ }
580
+ };
581
+
582
+ // src/resources/subscribers.ts
583
+ var Subscribers = class {
584
+ client;
585
+ constructor(client) {
586
+ this.client = client;
587
+ }
588
+ /**
589
+ * Cria ou atualiza um subscriber (upsert por external_id).
590
+ * LGPD: registra consentimento automaticamente.
591
+ *
592
+ * @example
593
+ * ```ts
594
+ * const subscriber = await notifica.subscribers.create({
595
+ * external_id: 'user-123',
596
+ * email: 'joao@empresa.com.br',
597
+ * phone: '+5511999998888',
598
+ * name: 'João Silva',
599
+ * });
600
+ * ```
601
+ */
602
+ async create(params, options) {
603
+ const response = await this.client.post(
604
+ "/subscribers",
605
+ params,
606
+ options
607
+ );
608
+ return response.data;
609
+ }
610
+ /**
611
+ * Lista subscribers com paginação.
612
+ */
613
+ async list(params, options) {
614
+ return this.client.list("/subscribers", params, options);
615
+ }
616
+ /**
617
+ * Itera automaticamente por todos os subscribers.
618
+ */
619
+ listAll(params) {
620
+ return this.client.paginate("/subscribers", params);
621
+ }
622
+ /**
623
+ * Obtém detalhes de um subscriber.
624
+ */
625
+ async get(id, options) {
626
+ return this.client.getOne(`/subscribers/${id}`, options);
627
+ }
628
+ /**
629
+ * Atualiza um subscriber.
630
+ */
631
+ async update(id, params, options) {
632
+ const response = await this.client.put(
633
+ `/subscribers/${id}`,
634
+ params,
635
+ options
636
+ );
637
+ return response.data;
638
+ }
639
+ /**
640
+ * Deleta um subscriber (soft delete com nullificação de PII — LGPD).
641
+ * ⚠️ Irreversível: email, telefone e nome são removidos.
642
+ */
643
+ async delete(id, options) {
644
+ await this.client.delete(`/subscribers/${id}`, options);
645
+ }
646
+ // ── Preferences ─────────────────────────────────────
647
+ /**
648
+ * Obtém preferências de notificação do subscriber.
649
+ */
650
+ async getPreferences(id, options) {
651
+ return this.client.getOne(`/subscribers/${id}/preferences`, options);
652
+ }
653
+ /**
654
+ * Atualiza preferências de notificação do subscriber.
655
+ *
656
+ * @example
657
+ * ```ts
658
+ * await notifica.subscribers.updatePreferences('sub_123', {
659
+ * preferences: [
660
+ * { category: 'marketing', channel: 'email', enabled: false },
661
+ * { category: 'transactional', channel: 'whatsapp', enabled: true },
662
+ * ],
663
+ * });
664
+ * ```
665
+ */
666
+ async updatePreferences(id, params, options) {
667
+ const response = await this.client.put(
668
+ `/subscribers/${id}/preferences`,
669
+ params,
670
+ options
671
+ );
672
+ return response.data;
673
+ }
674
+ // ── Bulk import ─────────────────────────────────────
675
+ /**
676
+ * Importa subscribers em lote (upsert transacional).
677
+ * Se um subscriber falhar validação, todo o lote é revertido.
678
+ */
679
+ async bulkImport(params, options) {
680
+ const response = await this.client.post(
681
+ "/subscribers/import",
682
+ params,
683
+ options
684
+ );
685
+ return response.data;
686
+ }
687
+ // ── In-App Notifications ────────────────────────────
688
+ /**
689
+ * Lista notificações in-app de um subscriber.
690
+ */
691
+ async listNotifications(subscriberId, params, options) {
692
+ return this.client.get(
693
+ `/subscribers/${subscriberId}/notifications`,
694
+ params,
695
+ options
696
+ );
697
+ }
698
+ /**
699
+ * Marca uma notificação in-app como lida.
700
+ */
701
+ async markRead(subscriberId, notificationId, options) {
702
+ await this.client.post(
703
+ `/subscribers/${subscriberId}/notifications/${notificationId}/read`,
704
+ void 0,
705
+ options
706
+ );
707
+ }
708
+ /**
709
+ * Marca todas as notificações in-app como lidas.
710
+ */
711
+ async markAllRead(subscriberId, options) {
712
+ await this.client.post(
713
+ `/subscribers/${subscriberId}/notifications/read-all`,
714
+ void 0,
715
+ options
716
+ );
717
+ }
718
+ /**
719
+ * Obtém contagem de notificações não lidas.
720
+ */
721
+ async getUnreadCount(subscriberId, options) {
722
+ const response = await this.client.get(
723
+ `/subscribers/${subscriberId}/notifications/unread-count`,
724
+ void 0,
725
+ options
726
+ );
727
+ return response.data.count;
728
+ }
729
+ };
730
+
731
+ // src/resources/channels.ts
732
+ var Channels = class {
733
+ client;
734
+ constructor(client) {
735
+ this.client = client;
736
+ }
737
+ /**
738
+ * Configura um canal de notificação.
739
+ *
740
+ * @example
741
+ * ```ts
742
+ * const channel = await notifica.channels.create({
743
+ * channel: 'email',
744
+ * provider: 'aws_ses',
745
+ * credentials: {
746
+ * access_key_id: 'AKIA...',
747
+ * secret_access_key: '...',
748
+ * region: 'us-east-1',
749
+ * },
750
+ * settings: {
751
+ * from_address: 'noreply@empresa.com.br',
752
+ * from_name: 'Empresa',
753
+ * },
754
+ * });
755
+ * ```
756
+ */
757
+ async create(params, options) {
758
+ const response = await this.client.post(
759
+ "/channels",
760
+ params,
761
+ options
762
+ );
763
+ return response.data;
764
+ }
765
+ /**
766
+ * Lista todas as configurações de canal.
767
+ */
768
+ async list(options) {
769
+ const response = await this.client.get(
770
+ "/channels",
771
+ void 0,
772
+ options
773
+ );
774
+ return response.data;
775
+ }
776
+ /**
777
+ * Obtém a configuração de um canal específico.
778
+ */
779
+ async get(channel, options) {
780
+ return this.client.getOne(`/channels/${channel}`, options);
781
+ }
782
+ /**
783
+ * Atualiza a configuração de um canal.
784
+ */
785
+ async update(channel, params, options) {
786
+ const response = await this.client.put(
787
+ `/channels/${channel}`,
788
+ params,
789
+ options
790
+ );
791
+ return response.data;
792
+ }
793
+ /**
794
+ * Remove a configuração de um canal.
795
+ */
796
+ async delete(channel, options) {
797
+ await this.client.delete(`/channels/${channel}`, options);
798
+ }
799
+ /**
800
+ * Envia uma notificação de teste usando a configuração atual do canal.
801
+ */
802
+ async test(channel, options) {
803
+ const response = await this.client.post(
804
+ `/channels/${channel}/test`,
805
+ void 0,
806
+ options
807
+ );
808
+ return response.data;
809
+ }
810
+ };
811
+
812
+ // src/resources/domains.ts
813
+ var Domains = class {
814
+ client;
815
+ constructor(client) {
816
+ this.client = client;
817
+ }
818
+ /**
819
+ * Registra um novo domínio de envio.
820
+ *
821
+ * @example
822
+ * ```ts
823
+ * const domain = await notifica.domains.create({ domain: 'suaempresa.com.br' });
824
+ * // Configure os registros DNS retornados em domain.dns_records
825
+ * ```
826
+ */
827
+ async create(params, options) {
828
+ const response = await this.client.post(
829
+ "/domains",
830
+ params,
831
+ options
832
+ );
833
+ return response.data;
834
+ }
835
+ /**
836
+ * Lista domínios registrados.
837
+ */
838
+ async list(params, options) {
839
+ return this.client.list("/domains", params, options);
840
+ }
841
+ /**
842
+ * Obtém detalhes de um domínio.
843
+ */
844
+ async get(id, options) {
845
+ return this.client.getOne(`/domains/${id}`, options);
846
+ }
847
+ /**
848
+ * Dispara verificação DNS do domínio.
849
+ */
850
+ async verify(id, options) {
851
+ const response = await this.client.post(
852
+ `/domains/${id}/verify`,
853
+ void 0,
854
+ options
855
+ );
856
+ return response.data;
857
+ }
858
+ /**
859
+ * Remove um domínio.
860
+ */
861
+ async delete(id, options) {
862
+ await this.client.delete(`/domains/${id}`, options);
863
+ }
864
+ // ── Health ──────────────────────────────────────────
865
+ /**
866
+ * Obtém status de saúde do domínio.
867
+ */
868
+ async getHealth(domainId, options) {
869
+ return this.client.getOne(`/domains/${domainId}/health`, options);
870
+ }
871
+ /**
872
+ * Força verificação de saúde (rate limit: 1/min).
873
+ */
874
+ async checkHealth(domainId, options) {
875
+ const response = await this.client.post(
876
+ `/domains/${domainId}/health/check`,
877
+ void 0,
878
+ options
879
+ );
880
+ return response.data;
881
+ }
882
+ /**
883
+ * Lista alertas de domínio.
884
+ */
885
+ async listAlerts(options) {
886
+ const response = await this.client.get(
887
+ "/domains/alerts",
888
+ void 0,
889
+ options
890
+ );
891
+ return response.data;
892
+ }
893
+ };
894
+
895
+ // src/resources/webhooks.ts
896
+ var Webhooks = class {
897
+ client;
898
+ constructor(client) {
899
+ this.client = client;
900
+ }
901
+ /**
902
+ * Cria um novo webhook.
903
+ * ⚠️ O signing_secret é retornado apenas na criação. Salve-o!
904
+ *
905
+ * @example
906
+ * ```ts
907
+ * const webhook = await notifica.webhooks.create({
908
+ * url: 'https://meuapp.com.br/webhooks/notifica',
909
+ * events: ['notification.delivered', 'notification.failed'],
910
+ * });
911
+ * // Salve: webhook.signing_secret
912
+ * ```
913
+ */
914
+ async create(params, options) {
915
+ const response = await this.client.post(
916
+ "/webhooks",
917
+ params,
918
+ options
919
+ );
920
+ return response.data;
921
+ }
922
+ /**
923
+ * Lista webhooks com paginação.
924
+ */
925
+ async list(params, options) {
926
+ return this.client.list("/webhooks", params, options);
927
+ }
928
+ /**
929
+ * Obtém detalhes de um webhook.
930
+ */
931
+ async get(id, options) {
932
+ return this.client.getOne(`/webhooks/${id}`, options);
933
+ }
934
+ /**
935
+ * Atualiza um webhook.
936
+ */
937
+ async update(id, params, options) {
938
+ const response = await this.client.put(
939
+ `/webhooks/${id}`,
940
+ params,
941
+ options
942
+ );
943
+ return response.data;
944
+ }
945
+ /**
946
+ * Deleta um webhook.
947
+ */
948
+ async delete(id, options) {
949
+ await this.client.delete(`/webhooks/${id}`, options);
950
+ }
951
+ /**
952
+ * Envia um evento de teste para o webhook.
953
+ */
954
+ async test(id, options) {
955
+ await this.client.post(`/webhooks/${id}/test`, void 0, options);
956
+ }
957
+ /**
958
+ * Lista entregas recentes de um webhook.
959
+ */
960
+ async listDeliveries(id, params, options) {
961
+ const response = await this.client.get(
962
+ `/webhooks/${id}/deliveries`,
963
+ params,
964
+ options
965
+ );
966
+ return response.data;
967
+ }
968
+ // ── Webhook signature verification ──────────────────
969
+ /**
970
+ * Verifica a assinatura HMAC de um payload de webhook.
971
+ *
972
+ * Use para validar que o payload foi realmente enviado pelo Notifica.
973
+ *
974
+ * @param payload — Body da request (string ou Buffer)
975
+ * @param signature — Valor do header `X-Notifica-Signature`
976
+ * @param secret — signing_secret do webhook
977
+ * @returns true se a assinatura é válida
978
+ *
979
+ * @example
980
+ * ```ts
981
+ * app.post('/webhooks/notifica', (req, res) => {
982
+ * const payload = req.body; // raw body string
983
+ * const signature = req.headers['x-notifica-signature'];
984
+ * const secret = process.env.WEBHOOK_SECRET;
985
+ *
986
+ * if (!notifica.webhooks.verify(payload, signature, secret)) {
987
+ * return res.status(401).send('Invalid signature');
988
+ * }
989
+ *
990
+ * // Processar evento...
991
+ * res.status(200).send('OK');
992
+ * });
993
+ * ```
994
+ */
995
+ async verify(payload, signature, secret) {
996
+ if (!payload || !signature || !secret) {
997
+ return false;
998
+ }
999
+ try {
1000
+ const encoder = new TextEncoder();
1001
+ const key = await crypto.subtle.importKey(
1002
+ "raw",
1003
+ encoder.encode(secret),
1004
+ { name: "HMAC", hash: "SHA-256" },
1005
+ false,
1006
+ ["sign"]
1007
+ );
1008
+ const payloadBytes = typeof payload === "string" ? encoder.encode(payload) : payload instanceof ArrayBuffer ? new Uint8Array(payload) : payload;
1009
+ const signatureBytes = await crypto.subtle.sign("HMAC", key, payloadBytes);
1010
+ const computed = this.toHex(new Uint8Array(signatureBytes));
1011
+ return this.timingSafeEqual(computed, signature);
1012
+ } catch {
1013
+ return false;
1014
+ }
1015
+ }
1016
+ /**
1017
+ * Verifica a assinatura e lança erro se inválida.
1018
+ * Versão "fail-fast" do verify().
1019
+ */
1020
+ async verifyOrThrow(payload, signature, secret) {
1021
+ const valid = await this.verify(payload, signature, secret);
1022
+ if (!valid) {
1023
+ throw new NotificaError("Invalid webhook signature");
1024
+ }
1025
+ }
1026
+ toHex(bytes) {
1027
+ return Array.from(bytes).map((b) => b.toString(16).padStart(2, "0")).join("");
1028
+ }
1029
+ /**
1030
+ * Constant-time string comparison to prevent timing attacks.
1031
+ */
1032
+ timingSafeEqual(a, b) {
1033
+ if (a.length !== b.length) return false;
1034
+ let result = 0;
1035
+ for (let i = 0; i < a.length; i++) {
1036
+ result |= a.charCodeAt(i) ^ b.charCodeAt(i);
1037
+ }
1038
+ return result === 0;
1039
+ }
1040
+ };
1041
+
1042
+ // src/resources/api-keys.ts
1043
+ var ApiKeys = class {
1044
+ client;
1045
+ constructor(client) {
1046
+ this.client = client;
1047
+ }
1048
+ /**
1049
+ * Cria uma nova API key.
1050
+ * ⚠️ O raw_key é retornado apenas na criação. Salve-o!
1051
+ *
1052
+ * @example
1053
+ * ```ts
1054
+ * const key = await notifica.apiKeys.create({
1055
+ * key_type: 'secret',
1056
+ * label: 'Backend Production',
1057
+ * environment: 'production',
1058
+ * });
1059
+ * // Salve: key.raw_key
1060
+ * ```
1061
+ */
1062
+ async create(params, options) {
1063
+ const response = await this.client.post(
1064
+ "/api-keys",
1065
+ params,
1066
+ options
1067
+ );
1068
+ return response.data;
1069
+ }
1070
+ /**
1071
+ * Lista API keys (sem raw_key).
1072
+ */
1073
+ async list(options) {
1074
+ const response = await this.client.get(
1075
+ "/api-keys",
1076
+ void 0,
1077
+ options
1078
+ );
1079
+ return response.data;
1080
+ }
1081
+ /**
1082
+ * Revoga (deleta) uma API key.
1083
+ */
1084
+ async revoke(id, options) {
1085
+ await this.client.delete(`/api-keys/${id}`, options);
1086
+ }
1087
+ };
1088
+
1089
+ // src/resources/analytics.ts
1090
+ var Analytics = class {
1091
+ client;
1092
+ constructor(client) {
1093
+ this.client = client;
1094
+ }
1095
+ /**
1096
+ * Métricas gerais (total enviado, entregue, falhas, taxa de entrega).
1097
+ *
1098
+ * @example
1099
+ * ```ts
1100
+ * const overview = await notifica.analytics.overview({ period: '7d' });
1101
+ * console.log(`Taxa de entrega: ${overview.delivery_rate}%`);
1102
+ * ```
1103
+ */
1104
+ async overview(params, options) {
1105
+ const response = await this.client.get(
1106
+ "/analytics/overview",
1107
+ params,
1108
+ options
1109
+ );
1110
+ return response.data;
1111
+ }
1112
+ /**
1113
+ * Métricas por canal.
1114
+ */
1115
+ async byChannel(params, options) {
1116
+ const response = await this.client.get(
1117
+ "/analytics/channels",
1118
+ params,
1119
+ options
1120
+ );
1121
+ return response.data;
1122
+ }
1123
+ /**
1124
+ * Série temporal de envios.
1125
+ */
1126
+ async timeseries(params, options) {
1127
+ const response = await this.client.get(
1128
+ "/analytics/timeseries",
1129
+ params,
1130
+ options
1131
+ );
1132
+ return response.data;
1133
+ }
1134
+ /**
1135
+ * Templates mais utilizados.
1136
+ */
1137
+ async topTemplates(params, options) {
1138
+ const response = await this.client.get(
1139
+ "/analytics/templates",
1140
+ params,
1141
+ options
1142
+ );
1143
+ return response.data;
1144
+ }
1145
+ };
1146
+
1147
+ // src/resources/sms.ts
1148
+ var SmsProviders = class {
1149
+ client;
1150
+ constructor(client) {
1151
+ this.client = client;
1152
+ }
1153
+ /**
1154
+ * Lista todos os provedores SMS configurados.
1155
+ */
1156
+ async list(options) {
1157
+ const response = await this.client.get(
1158
+ "/channels/sms/providers",
1159
+ void 0,
1160
+ options
1161
+ );
1162
+ return response.data;
1163
+ }
1164
+ /**
1165
+ * Cria um novo provedor SMS (idempotent).
1166
+ */
1167
+ async create(params, options) {
1168
+ const response = await this.client.post(
1169
+ "/channels/sms/providers",
1170
+ params,
1171
+ options
1172
+ );
1173
+ return response.data;
1174
+ }
1175
+ /**
1176
+ * Obtém detalhes de um provedor SMS.
1177
+ */
1178
+ async get(id, options) {
1179
+ return this.client.getOne(`/channels/sms/providers/${id}`, options);
1180
+ }
1181
+ /**
1182
+ * Atualiza um provedor SMS (PATCH parcial).
1183
+ */
1184
+ async update(id, params, options) {
1185
+ const response = await this.client.patch(
1186
+ `/channels/sms/providers/${id}`,
1187
+ params,
1188
+ options
1189
+ );
1190
+ return response.data;
1191
+ }
1192
+ /**
1193
+ * Ativa um provedor SMS.
1194
+ */
1195
+ async activate(id, options) {
1196
+ const response = await this.client.post(
1197
+ `/channels/sms/providers/${id}/activate`,
1198
+ void 0,
1199
+ options
1200
+ );
1201
+ return response.data;
1202
+ }
1203
+ /**
1204
+ * Remove um provedor SMS.
1205
+ */
1206
+ async delete(id, options) {
1207
+ await this.client.delete(`/channels/sms/providers/${id}`, options);
1208
+ }
1209
+ /**
1210
+ * Valida a configuração de um provedor SMS.
1211
+ */
1212
+ async validate(params, options) {
1213
+ const response = await this.client.post(
1214
+ "/channels/sms/providers/validate",
1215
+ params,
1216
+ options
1217
+ );
1218
+ return response.data;
1219
+ }
1220
+ /**
1221
+ * Envia um SMS de teste.
1222
+ */
1223
+ async test(params, options) {
1224
+ const response = await this.client.post(
1225
+ "/channels/sms/providers/test",
1226
+ params,
1227
+ options
1228
+ );
1229
+ return response.data;
1230
+ }
1231
+ };
1232
+ var SmsCompliance = class {
1233
+ client;
1234
+ constructor(client) {
1235
+ this.client = client;
1236
+ }
1237
+ /**
1238
+ * Obtém as configurações de compliance SMS.
1239
+ */
1240
+ async show(options) {
1241
+ return this.client.getOne("/channels/sms/compliance", options);
1242
+ }
1243
+ /**
1244
+ * Atualiza as configurações de compliance SMS (PATCH parcial).
1245
+ */
1246
+ async update(params, options) {
1247
+ const response = await this.client.patch(
1248
+ "/channels/sms/compliance",
1249
+ params,
1250
+ options
1251
+ );
1252
+ return response.data;
1253
+ }
1254
+ /**
1255
+ * Obtém estatísticas de compliance.
1256
+ */
1257
+ async analytics(options) {
1258
+ return this.client.getOne("/channels/sms/compliance/analytics", options);
1259
+ }
1260
+ /**
1261
+ * Lista logs de compliance com paginação.
1262
+ */
1263
+ async logs(params, options) {
1264
+ return this.client.list("/channels/sms/compliance/logs", params, options);
1265
+ }
1266
+ };
1267
+ var SmsConsents = class {
1268
+ client;
1269
+ constructor(client) {
1270
+ this.client = client;
1271
+ }
1272
+ /**
1273
+ * Lista consentimentos SMS com paginação.
1274
+ */
1275
+ async list(params, options) {
1276
+ return this.client.list("/channels/sms/consents", params, options);
1277
+ }
1278
+ /**
1279
+ * Obtém resumo estatístico dos consentimentos.
1280
+ */
1281
+ async summary(options) {
1282
+ return this.client.getOne("/channels/sms/consents/summary", options);
1283
+ }
1284
+ /**
1285
+ * Obtém o consentimento de um número específico.
1286
+ */
1287
+ async get(phone, options) {
1288
+ return this.client.getOne(`/channels/sms/consents/${encodeURIComponent(phone)}`, options);
1289
+ }
1290
+ /**
1291
+ * Revoga o consentimento de um número (DELETE).
1292
+ */
1293
+ async revoke(phone, options) {
1294
+ await this.client.delete(`/channels/sms/consents/${encodeURIComponent(phone)}`, options);
1295
+ }
1296
+ /**
1297
+ * Cria ou atualiza um consentimento SMS (idempotent).
1298
+ */
1299
+ async create(params, options) {
1300
+ const response = await this.client.post(
1301
+ "/channels/sms/consents",
1302
+ params,
1303
+ options
1304
+ );
1305
+ return response.data;
1306
+ }
1307
+ /**
1308
+ * Importa consentimentos em lote.
1309
+ */
1310
+ async import(params, options) {
1311
+ const response = await this.client.post(
1312
+ "/channels/sms/consents/import",
1313
+ params,
1314
+ options
1315
+ );
1316
+ return response.data;
1317
+ }
1318
+ };
1319
+ var Sms = class {
1320
+ providers;
1321
+ compliance;
1322
+ consents;
1323
+ constructor(client) {
1324
+ this.providers = new SmsProviders(client);
1325
+ this.compliance = new SmsCompliance(client);
1326
+ this.consents = new SmsConsents(client);
1327
+ }
1328
+ };
1329
+
1330
+ // src/resources/billing.ts
1331
+ var BillingPlans = class {
1332
+ client;
1333
+ constructor(client) {
1334
+ this.client = client;
1335
+ }
1336
+ /**
1337
+ * Lista todos os planos disponíveis.
1338
+ */
1339
+ async list(options) {
1340
+ const response = await this.client.get(
1341
+ "/billing/plans",
1342
+ void 0,
1343
+ options
1344
+ );
1345
+ return response.data;
1346
+ }
1347
+ /**
1348
+ * Obtém detalhes de um plano específico.
1349
+ */
1350
+ async get(name, options) {
1351
+ return this.client.getOne(`/billing/plans/${name}`, options);
1352
+ }
1353
+ };
1354
+ var BillingSettingsResource = class {
1355
+ client;
1356
+ constructor(client) {
1357
+ this.client = client;
1358
+ }
1359
+ /**
1360
+ * Obtém as configurações de faturamento do tenant.
1361
+ */
1362
+ async get(options) {
1363
+ return this.client.getOne("/billing/settings", options);
1364
+ }
1365
+ };
1366
+ var BillingSubscription = class {
1367
+ client;
1368
+ constructor(client) {
1369
+ this.client = client;
1370
+ }
1371
+ /**
1372
+ * Obtém a assinatura atual.
1373
+ */
1374
+ async get(options) {
1375
+ return this.client.getOne("/billing/subscription", options);
1376
+ }
1377
+ /**
1378
+ * Cria uma nova assinatura (idempotent).
1379
+ */
1380
+ async subscribe(params, options) {
1381
+ const response = await this.client.post(
1382
+ "/billing/subscribe",
1383
+ params,
1384
+ options
1385
+ );
1386
+ return response.data;
1387
+ }
1388
+ /**
1389
+ * Altera o plano da assinatura (idempotent).
1390
+ */
1391
+ async changePlan(params, options) {
1392
+ const response = await this.client.post(
1393
+ "/billing/change-plan",
1394
+ params,
1395
+ options
1396
+ );
1397
+ return response.data;
1398
+ }
1399
+ /**
1400
+ * Cancela a assinatura (idempotent).
1401
+ */
1402
+ async cancel(params, options) {
1403
+ const response = await this.client.post(
1404
+ "/billing/cancel",
1405
+ params,
1406
+ options
1407
+ );
1408
+ return response.data;
1409
+ }
1410
+ /**
1411
+ * Calcula o valor de proration para mudança de plano.
1412
+ */
1413
+ async calculateProration(params, options) {
1414
+ const response = await this.client.post(
1415
+ "/billing/calculate-proration",
1416
+ params,
1417
+ options
1418
+ );
1419
+ return response.data;
1420
+ }
1421
+ /**
1422
+ * Reativa uma assinatura cancelada (idempotent).
1423
+ */
1424
+ async reactivate(params, options) {
1425
+ const response = await this.client.post(
1426
+ "/billing/reactivate",
1427
+ params,
1428
+ options
1429
+ );
1430
+ return response.data;
1431
+ }
1432
+ };
1433
+ var BillingUsageResource = class {
1434
+ client;
1435
+ constructor(client) {
1436
+ this.client = client;
1437
+ }
1438
+ /**
1439
+ * Obtém o uso atual e quotas do tenant.
1440
+ */
1441
+ async get(options) {
1442
+ return this.client.getOne("/billing/usage", options);
1443
+ }
1444
+ };
1445
+ var BillingInvoices = class {
1446
+ client;
1447
+ constructor(client) {
1448
+ this.client = client;
1449
+ }
1450
+ /**
1451
+ * Lista faturas com paginação.
1452
+ */
1453
+ async list(params, options) {
1454
+ return this.client.list("/billing/invoices", params, options);
1455
+ }
1456
+ /**
1457
+ * Obtém detalhes de uma fatura.
1458
+ */
1459
+ async get(id, options) {
1460
+ return this.client.getOne(`/billing/invoices/${id}`, options);
1461
+ }
1462
+ };
1463
+ var BillingPaymentMethods = class {
1464
+ client;
1465
+ constructor(client) {
1466
+ this.client = client;
1467
+ }
1468
+ /**
1469
+ * Lista métodos de pagamento.
1470
+ */
1471
+ async list(options) {
1472
+ const response = await this.client.get(
1473
+ "/billing/payment-methods",
1474
+ void 0,
1475
+ options
1476
+ );
1477
+ return response.data;
1478
+ }
1479
+ /**
1480
+ * Cria um novo método de pagamento (idempotent).
1481
+ */
1482
+ async create(params, options) {
1483
+ const response = await this.client.post(
1484
+ "/billing/payment-methods",
1485
+ params,
1486
+ options
1487
+ );
1488
+ return response.data;
1489
+ }
1490
+ /**
1491
+ * Obtém detalhes de um método de pagamento.
1492
+ */
1493
+ async get(id, options) {
1494
+ return this.client.getOne(`/billing/payment-methods/${id}`, options);
1495
+ }
1496
+ /**
1497
+ * Atualiza um método de pagamento.
1498
+ */
1499
+ async update(id, params, options) {
1500
+ const response = await this.client.put(
1501
+ `/billing/payment-methods/${id}`,
1502
+ params,
1503
+ options
1504
+ );
1505
+ return response.data;
1506
+ }
1507
+ /**
1508
+ * Remove um método de pagamento.
1509
+ */
1510
+ async delete(id, options) {
1511
+ await this.client.delete(`/billing/payment-methods/${id}`, options);
1512
+ }
1513
+ /**
1514
+ * Define um método de pagamento como padrão.
1515
+ */
1516
+ async setDefault(id, options) {
1517
+ const response = await this.client.post(
1518
+ `/billing/payment-methods/${id}/set-default`,
1519
+ void 0,
1520
+ options
1521
+ );
1522
+ return response.data;
1523
+ }
1524
+ };
1525
+ var Billing = class {
1526
+ plans;
1527
+ settings;
1528
+ subscription;
1529
+ usage;
1530
+ invoices;
1531
+ paymentMethods;
1532
+ constructor(client) {
1533
+ this.plans = new BillingPlans(client);
1534
+ this.settings = new BillingSettingsResource(client);
1535
+ this.subscription = new BillingSubscription(client);
1536
+ this.usage = new BillingUsageResource(client);
1537
+ this.invoices = new BillingInvoices(client);
1538
+ this.paymentMethods = new BillingPaymentMethods(client);
1539
+ }
1540
+ };
1541
+
1542
+ // src/resources/inbox-embed.ts
1543
+ var InboxEmbed = class {
1544
+ client;
1545
+ constructor(client) {
1546
+ this.client = client;
1547
+ }
1548
+ /**
1549
+ * Obtém as configurações do inbox embed.
1550
+ */
1551
+ async getSettings(options) {
1552
+ return this.client.getOne("/inbox-embed/settings", options);
1553
+ }
1554
+ /**
1555
+ * Atualiza as configurações do inbox embed.
1556
+ */
1557
+ async updateSettings(params, options) {
1558
+ const response = await this.client.put(
1559
+ "/inbox-embed/settings",
1560
+ params,
1561
+ options
1562
+ );
1563
+ return response.data;
1564
+ }
1565
+ /**
1566
+ * Rotaciona a chave de embed.
1567
+ * A chave antiga continua funcionando por um período de grace period.
1568
+ */
1569
+ async rotateKey(options) {
1570
+ const response = await this.client.post(
1571
+ "/inbox-embed/keys/rotate",
1572
+ void 0,
1573
+ options
1574
+ );
1575
+ return response.data;
1576
+ }
1577
+ };
1578
+
1579
+ // src/resources/inbox.ts
1580
+ var Inbox = class {
1581
+ client;
1582
+ constructor(client) {
1583
+ this.client = client;
1584
+ }
1585
+ /**
1586
+ * Lista notificações do inbox.
1587
+ * Requer subscriber_id ou external_id como parâmetro de query.
1588
+ */
1589
+ async listNotifications(subscriberId, params, options) {
1590
+ return this.client.list(
1591
+ "/inbox/notifications",
1592
+ { subscriber_id: subscriberId, ...params },
1593
+ options
1594
+ );
1595
+ }
1596
+ /**
1597
+ * Obtém a contagem de notificações não lidas.
1598
+ */
1599
+ async getUnreadCount(subscriberId, options) {
1600
+ const response = await this.client.get(
1601
+ "/inbox/notifications/unread-count",
1602
+ { subscriber_id: subscriberId },
1603
+ options
1604
+ );
1605
+ return response.data.count;
1606
+ }
1607
+ /**
1608
+ * Marca uma notificação como lida.
1609
+ */
1610
+ async markRead(notificationId, options) {
1611
+ const response = await this.client.post(
1612
+ `/inbox/notifications/${notificationId}/read`,
1613
+ void 0,
1614
+ options
1615
+ );
1616
+ return response.data;
1617
+ }
1618
+ /**
1619
+ * Marca todas as notificações como lidas.
1620
+ * Requer subscriber_id como parâmetro de query.
1621
+ */
1622
+ async markAllRead(subscriberId, options) {
1623
+ const response = await this.client.post(
1624
+ "/inbox/notifications/read-all",
1625
+ { subscriber_id: subscriberId },
1626
+ options
1627
+ );
1628
+ return response.data;
1629
+ }
1630
+ };
1631
+
1632
+ // src/index.ts
1633
+ var Notifica = class {
1634
+ notifications;
1635
+ templates;
1636
+ workflows;
1637
+ subscribers;
1638
+ channels;
1639
+ domains;
1640
+ webhooks;
1641
+ apiKeys;
1642
+ analytics;
1643
+ sms;
1644
+ billing;
1645
+ inboxEmbed;
1646
+ inbox;
1647
+ /**
1648
+ * Cria uma nova instância do cliente Notifica.
1649
+ *
1650
+ * @param apiKeyOrConfig — API key (string) ou objeto de configuração completo
1651
+ *
1652
+ * @example
1653
+ * ```ts
1654
+ * // Simples — apenas API key
1655
+ * const notifica = new Notifica('nk_live_...');
1656
+ *
1657
+ * // Configuração completa
1658
+ * const notifica = new Notifica({
1659
+ * apiKey: 'nk_live_...',
1660
+ * baseUrl: 'https://app.usenotifica.com.br/v1',
1661
+ * timeout: 15000,
1662
+ * maxRetries: 5,
1663
+ * });
1664
+ * ```
1665
+ */
1666
+ constructor(apiKeyOrConfig) {
1667
+ const config = typeof apiKeyOrConfig === "string" ? { apiKey: apiKeyOrConfig } : apiKeyOrConfig;
1668
+ const client = new NotificaClient(config);
1669
+ this.notifications = new Notifications(client);
1670
+ this.templates = new Templates(client);
1671
+ this.workflows = new Workflows(client);
1672
+ this.subscribers = new Subscribers(client);
1673
+ this.channels = new Channels(client);
1674
+ this.domains = new Domains(client);
1675
+ this.webhooks = new Webhooks(client);
1676
+ this.apiKeys = new ApiKeys(client);
1677
+ this.analytics = new Analytics(client);
1678
+ this.sms = new Sms(client);
1679
+ this.billing = new Billing(client);
1680
+ this.inboxEmbed = new InboxEmbed(client);
1681
+ this.inbox = new Inbox(client);
1682
+ }
1683
+ };
1684
+ export {
1685
+ Analytics,
1686
+ ApiError,
1687
+ ApiKeys,
1688
+ Billing,
1689
+ Channels,
1690
+ Domains,
1691
+ Inbox,
1692
+ InboxEmbed,
1693
+ Notifica,
1694
+ NotificaClient,
1695
+ NotificaError,
1696
+ Notifications,
1697
+ RateLimitError,
1698
+ Sms,
1699
+ Subscribers,
1700
+ Templates,
1701
+ TimeoutError,
1702
+ ValidationError,
1703
+ Webhooks,
1704
+ Workflows
1705
+ };