80 lines
6.5 KiB
Markdown
80 lines
6.5 KiB
Markdown
# @suaveplan/suppression - Email suppression list management: in-memory store, bulk import/export (CSV/JSON), domain-level suppression, and OTel instrumentation
|
|
|
|
## Summary
|
|
|
|
Email suppression list management for Suaveplan. Stores and checks email addresses that should not receive outgoing mail — unsubscribes, hard/soft bounces, complaints, manual suppressions, and invalid addresses. Supports domain-level blocking, bulk CSV/JSON import and export, OTel instrumentation, and full serialisation round-trips.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [csv-exporter](./src/core/exporter/csv-exporter.md) — `exportToCsv` converts an array of `SuppressionEntry` objects into a properly-formatted CSV string suitable for downloa…
|
|
- [json-exporter](./src/core/exporter/json-exporter.md) — `exportToJson` and `importFromJson` provide full-store persistence for `SuppressionStore` instances. They wrap the stor…
|
|
- [importer](./src/core/importer/csv-importer.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [csv-importer](./src/core/importer/csv-importer.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [suppression-store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [errors](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [suppression-error](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
- [email-utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_ <!-- end:auto-docs -->
|
|
<!-- end:auto-docs --> - [csv-importer](./src/core/importer/csv-importer.md) — <!-- begin:auto-docs --> _(no submodules)_- [store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_- [suppression-store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [suppression-error](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [email-utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [csv-importer](./src/core/importer/csv-importer.md) — <!-- begin:auto-docs --> _(no submodules)_- [store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_- [suppression-store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [suppression-error](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [email-utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [csv-importer](./src/core/importer/csv-importer.md) — <!-- begin:auto-docs --> _(no submodules)_- [store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_- [suppression-store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [suppression-error](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [email-utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_- [csv-importer](./src/core/importer/csv-importer.md) — <!-- begin:auto-docs --> _(no submodules)_- [store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_ - [suppression-store](./src/core/store/suppression-store.md) — <!-- begin:auto-docs --> _(no submodules)_- [errors](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_ - [suppression-error](./src/errors/suppression-error.md) — <!-- begin:auto-docs --> _(no submodules)_- [utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_ - [email-utils](./src/utils/email-utils.md) — <!-- begin:auto-docs --> _(no submodules)_
|
|
## Packages
|
|
|
|
| Module | Description |
|
|
|---|---|
|
|
| [`src/core/store/suppression-store.ts`](src/core/store/suppression-store.md) | In-memory suppression store with CRUD, domain blocking, stats, and serialisation |
|
|
| [`src/core/importer/csv-importer.ts`](src/core/importer/csv-importer.md) | Bulk import from CSV with header-driven column mapping |
|
|
| [`src/core/exporter/csv-exporter.ts`](src/core/exporter/csv-exporter.md) | Export entries to RFC 4180-compliant CSV |
|
|
| [`src/core/exporter/json-exporter.ts`](src/core/exporter/json-exporter.md) | Full-store JSON serialisation and deserialisation |
|
|
| [`src/utils/email-utils.ts`](src/utils/email-utils.md) | Email normalisation, domain extraction, and validation helpers |
|
|
| [`src/errors/suppression-error.ts`](src/errors/suppression-error.md) | Typed error class with stable code registry |
|
|
|
|
## Quick Start
|
|
|
|
```ts
|
|
import { createSuppressionStore } from "@suaveplan/suppression/store";
|
|
import { importFromCsv } from "@suaveplan/suppression/importer";
|
|
import { exportToCsv, exportToJson } from "@suaveplan/suppression/exporter";
|
|
|
|
// Create a store
|
|
const store = createSuppressionStore({ domainSuppressionEnabled: true });
|
|
|
|
// Add individual entries
|
|
store.add("user@example.com", "unsubscribe", "newsletter-june");
|
|
store.addDomain("spam.example", "bounce-hard");
|
|
|
|
// Check before sending
|
|
if (!store.isSuppressed(recipient)) {
|
|
await sendEmail(recipient);
|
|
}
|
|
|
|
// Bulk import from ESP export
|
|
const entries = importFromCsv(csvString);
|
|
store.fromJSON({ entries, domains: [] });
|
|
|
|
// Persist
|
|
const json = exportToJson(store);
|
|
await db.set("suppression_snapshot", json);
|
|
```
|
|
|
|
## Installation
|
|
|
|
```bash
|
|
bun add @suaveplan/suppression
|
|
```
|
|
|
|
## Suppression Reasons
|
|
|
|
| Reason | Description |
|
|
|---|---|
|
|
| `unsubscribe` | User explicitly opted out |
|
|
| `bounce-hard` | Permanent delivery failure |
|
|
| `bounce-soft` | Temporary delivery failure |
|
|
| `complaint` | Spam complaint recorded |
|
|
| `manual` | Manually added by operator |
|
|
| `invalid` | Structurally invalid address |
|
|
|
|
## License
|
|
|
|
MIT
|