{"_id":"@alis-kit/mailer","name":"@alis-kit/mailer","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@alis-kit/mailer","version":"0.1.0","description":"Email delivery abstraction with template engine and TC39 native decorators","type":"module","main":"dist/index.js","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"engines":{"node":">=18.0.0"},"dependencies":{"nodemailer":"^6.9.0"},"devDependencies":{"@types/node":"^20.0.0","@types/nodemailer":"^6.4.0","typescript":"^5.5.0","vitest":"^3.0.0"},"peerDependencies":{"typescript":">=5.5.0"},"scripts":{"build":"tsc","test":"vitest run","test:watch":"vitest","lint":"tsc --noEmit"},"_id":"@alis-kit/mailer@0.1.0","_integrity":"sha512-BOC64dBZwCyhlqpXj7qhQhSa6HsvdlCaH+cwnzaxDNbSt/fiwSjzzoUN2Ky8L2K2rceO2DPHCrxdSgR3nqAQXw==","_resolved":"C:\\Users\\ibnu-pc\\AppData\\Local\\Temp\\19cf8c8bc05df80fa9ca674479e17129\\alis-kit-mailer-0.1.0.tgz","_from":"file:alis-kit-mailer-0.1.0.tgz","_nodeVersion":"24.18.0","_npmVersion":"11.16.0","dist":{"integrity":"sha512-BOC64dBZwCyhlqpXj7qhQhSa6HsvdlCaH+cwnzaxDNbSt/fiwSjzzoUN2Ky8L2K2rceO2DPHCrxdSgR3nqAQXw==","shasum":"437832119422e69ddc8bd05a8c00444915e961bf","tarball":"https://registry.npmjs.org/@alis-kit/mailer/-/mailer-0.1.0.tgz","fileCount":38,"unpackedSize":38455,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIH9T3+VavsUs/FEZjxYZLZAp8WfGx1NQlKPFLQB7O+XmAiEA1HLdeD4LKZpo3SqWuCPDWSlw9RKUp2qFkQAsJV7dkkk="}]},"_npmUser":{"name":"alisdev","email":"ibnu.ali56@gmail.com"},"directories":{},"maintainers":[{"name":"alisdev","email":"ibnu.ali56@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mailer_0.1.0_1784436390099_0.5433660529831896"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-19T04:46:29.879Z","0.1.0":"2026-07-19T04:46:30.232Z","modified":"2026-07-19T04:46:30.482Z"},"maintainers":[{"name":"alisdev","email":"ibnu.ali56@gmail.com"}],"description":"Email delivery abstraction with template engine and TC39 native decorators","readme":"# Mailer Kit\n\nEmail delivery abstraction with a template engine and TC39 native decorators (Stage 3).\n\n## Features\n\n- **TC39 Native Decorators** — Uses stage 3 decorators with `Symbol.metadata`, no `reflect-metadata` needed\n- **Template Engine** — Dynamic `${variable}` and `${nested.variable}` interpolation\n- **Provider Agnostic** — Switch between Nodemailer, Resend, or custom providers\n- **Async Queues** — Send emails synchronously or queue them for background delivery\n- **Type Safe** — Full TypeScript support with strict mode\n\n## Requirements\n\n- **Node.js** >= 18.0.0\n- **TypeScript** >= 5.5.0\n\n## Installation\n\n```bash\nnpm install @alis-kit/mailer\n```\n\n## Quick Start\n\n### 1. Setup\n\n```typescript\nimport { MailerKit } from \"@alis-kit/mailer\"\n\nMailerKit.setup({\n  provider: \"nodemailer\",\n  config: {\n    host: \"smtp.gmail.com\",\n    port: 587,\n    auth: {\n      user: process.env.SMTP_USER,\n      pass: process.env.SMTP_PASS\n    }\n  },\n  from: \"noreply@example.com\"\n})\n```\n\n### 2. Define a Template\n\n```typescript\nimport { EmailTemplate } from \"@alis-kit/mailer\"\n\n/**\n * Welcome email sent to new users after registration.\n *\n * @example\n * ```ts\n * await MailerKit.send(WelcomeEmail, {\n *   to: \"user@example.com\",\n *   name: \"John\"\n * })\n * ```\n */\n@EmailTemplate(\"welcome\", {\n  template: \"./templates/welcome.html\",\n  subject: \"Welcome to Our Platform!\"\n})\nexport class WelcomeEmail {\n  to!: string\n  name!: string\n}\n```\n\n### 3. Create the HTML Template\n\n```html\n<!-- templates/welcome.html -->\n<h1>Welcome, ${name}!</h1>\n<p>We're excited to have you on board.</p>\n```\n\n### 4. Send\n\n```typescript\nawait MailerKit.send(WelcomeEmail, {\n  to: \"user@example.com\",\n  name: \"John\"\n})\n```\n\n## API Reference\n\n### `MailerKit.setup(config)`\n\nInitialize the mailer service. Must be called before sending.\n\n```typescript\nMailerKit.setup({\n  provider: \"nodemailer\",\n  config: {\n    host: \"smtp.example.com\",\n    port: 587,\n    auth: { user: \"...\", pass: \"...\" }\n  },\n  from: \"sender@example.com\",\n  queue: {\n    engine: \"memory\"          // or \"bullmq\"\n  }\n})\n```\n\n| Option | Type | Required | Description |\n|--------|------|----------|-------------|\n| `provider` | `\"nodemailer\"` | Yes | Email provider to use |\n| `config` | `object` | Yes | Provider-specific configuration |\n| `from` | `string` | Yes | Default sender email address |\n| `queue.engine` | `\"memory\" \\| \"bullmq\"` | No | Queue engine for async delivery |\n\n---\n\n### `@EmailTemplate(name, options)`\n\nClass decorator that links a class to an HTML template file. Uses TC39 stage 3 native decorators.\n\n```typescript\n@EmailTemplate(\"notification\", {\n  template: \"./templates/notification.html\",\n  subject: \"You have a new notification\"\n})\nexport class NotificationEmail {\n  to!: string\n  title!: string\n  message!: string\n}\n```\n\n| Parameter | Type | Required | Description |\n|-----------|------|----------|-------------|\n| `name` | `string` | Yes | Unique identifier for the template |\n| `options.template` | `string` | Yes | Path to the HTML template file |\n| `options.subject` | `string` | No | Default subject line |\n\n---\n\n### `MailerKit.send(TemplateClass, data)`\n\nSend an email immediately.\n\n```typescript\nawait MailerKit.send(NotificationEmail, {\n  to: \"user@example.com\",\n  title: \"New Message\",\n  message: \"You have a new notification!\"\n})\n```\n\n| Parameter | Type | Description |\n|-----------|------|-------------|\n| `TemplateClass` | `Class` | A class decorated with `@EmailTemplate` |\n| `data` | `object` | Email data including `to`, template variables, and optional overrides |\n\n**Data properties:**\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `to` | `string \\| string[]` | Recipient(s) — **required** |\n| `subject` | `string` | Override default subject |\n| `cc` | `string \\| string[]` | CC recipients |\n| `bcc` | `string \\| string[]` | BCC recipients |\n| `replyTo` | `string` | Reply-to address |\n| `attachments` | `Attachment[]` | File attachments (pdf, doc, docx, xls, xlsx, jpg, jpeg, png, zip) |\n\n---\n\n### `MailerKit.queue(TemplateClass, data, options?)`\n\nQueue an email for asynchronous delivery.\n\n```typescript\nawait MailerKit.queue(WelcomeEmail, {\n  to: \"user@example.com\",\n  name: \"John\"\n}, { delay: \"5s\" })\n```\n\n| Option | Type | Description |\n|--------|------|-------------|\n| `delay` | `string` | Delay before sending (e.g., `\"5s\"`, `\"2m\"`, `\"1h\"`) |\n| `priority` | `number` | Priority level (for BullMQ) |\n\n---\n\n### `TemplateEngine.render(templatePath, variables)`\n\nRender an HTML template with variable interpolation.\n\n```typescript\nimport { TemplateEngine } from \"@alis-kit/mailer\"\n\nconst html = await TemplateEngine.render(\"./template.html\", {\n  name: \"John\",\n  user: { email: \"john@example.com\" }\n})\n```\n\n**Supported syntax:**\n\n| Syntax | Example | Description |\n|--------|---------|-------------|\n| `${var}` | `${name}` | Simple variable |\n| `${nested}` | `${user.email}` | Dot-notation for nested objects |\n| `${array}` | `${items}` | Arrays are JSON-stringified |\n\n---\n\n### `MailerKit.getTemplateMetadata(TemplateClass)`\n\nRetrieve the metadata attached to a decorated class.\n\n```typescript\nconst metadata = MailerKit.getTemplateMetadata(WelcomeEmail)\n// { name: \"welcome\", template: \"./templates/welcome.html\", subject: \"Welcome!\" }\n```\n\n## Template Variables\n\nProperties defined in your decorated class act as template variables:\n\n```typescript\n@EmailTemplate(\"invoice\", {\n  template: \"./templates/invoice.html\",\n  subject: \"Your Invoice\"\n})\nexport class InvoiceEmail {\n  to!: string\n  invoiceNumber!: string\n  total!: number\n  items!: Array<{ name: string; price: number }>\n}\n```\n\n```html\n<!-- templates/invoice.html -->\n<h1>Invoice #${invoiceNumber}</h1>\n<p>Total: $${total}</p>\n<ul>\n  ${items}\n</ul>\n```\n\n## Error Handling\n\n| Error | Cause |\n|-------|-------|\n| `MailerKit not initialized. Call setup() first.` | `send()` or `queue()` called before `setup()` |\n| `Unsupported mail provider: <name>` | Invalid provider in `setup()` config |\n| `Class <Name> is not a valid @EmailTemplate` | Class not decorated with `@EmailTemplate` |\n| `Class <Name> is already decorated with @EmailTemplate` | Duplicate `@EmailTemplate` on same class |\n| `Unsupported attachment type: .<ext>` | Attachment file extension not in allowed list |\n| `Template file not found at: <path>` | HTML template file does not exist |\n| `Queue not configured` | `queue()` called without `queue` in config |\n| `BullMQ integration not implemented` | Using `\"bullmq\"` engine (not yet supported) |\n\n## Testing\n\n```bash\n# Run all tests\nnpm test\n\n# Run tests in watch mode\nnpm run test:watch\n```\n\n## Architecture\n\nThis project follows the **Functional Core + Decorator Sugar** pattern:\n\n- **`core/`** — Pure functions and classes with all business logic\n- **`decorators/`** — Thin wrappers that store metadata via `Symbol.metadata`\n- **`providers/`** — Email provider adapters (Nodemailer, Resend, etc.)\n- **`template/`** — Template engine and path resolution\n\nDecorators never contain business logic — they only attach metadata that `core/` reads.\n\n## License\n\nISC\n","readmeFilename":"README.md","_rev":"1-df724299f4bdf9451ccbdec6cc041bbb"}