{"_id":"@bernierllc/email-subscription","_rev":"6-52b37f3b11b64275bd217a3378695dd0","name":"@bernierllc/email-subscription","dist-tags":{"latest":"0.4.0"},"versions":{"0.0.1":{"name":"@bernierllc/email-subscription","version":"0.0.1","keywords":["oidc","trusted-publishing","setup"],"_id":"@bernierllc/email-subscription@0.0.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"dist":{"shasum":"f9d611556cd984178d5cb28104c7ea4e1efaea41","tarball":"https://registry.npmjs.org/@bernierllc/email-subscription/-/email-subscription-0.0.1.tgz","fileCount":2,"integrity":"sha512-0ZEo7x/DkXqDUZy4GGLcA+NZJASUFfOiQlHXRX1NG3xXGAiFL3L1hACvR4Vj7Nmkh2jV8HwXNfn1qXyYbLYomw==","signatures":[{"sig":"MEYCIQCJBN9/SVgz1uqliLgnHUHczJ6cPPhOUQdzaPVxgXMuGwIhAJw0m0LrhkI655JdkBptVllLKVKaXlgDJj+d7kBfrzvM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2083},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_npmVersion":"11.6.2","description":"OIDC trusted publishing setup package for @bernierllc/email-subscription","directories":{},"_nodeVersion":"25.2.1","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/email-subscription_0.0.1_1771733762760_0.009649535663536435","host":"s3://npm-registry-packages-npm-production"}},"0.1.0":{"name":"@bernierllc/email-subscription","version":"0.1.0","keywords":["email","subscription","unsubscribe","suppression","mailing-list","email-list","opt-out","bernierllc","typescript"],"author":{"name":"Bernier LLC"},"license":"PROPRIETARY","_id":"@bernierllc/email-subscription@0.1.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernier-llc/tools#readme","bugs":{"url":"https://github.com/bernier-llc/tools/issues"},"dist":{"shasum":"b3cf9bd4842eaad97837987e9404096eca2ec25c","tarball":"https://registry.npmjs.org/@bernierllc/email-subscription/-/email-subscription-0.1.0.tgz","fileCount":39,"integrity":"sha512-tJuiqMCAjJM17gdGrfV+HbmufK6WXGEQYqctsQib/VDMrF6JTNK6BEWb2/3NFLhrULGesKTNxgx0uCDoM68doA==","signatures":[{"sig":"MEUCIQCAigDvHIuSe7tYqeQHScvaqfZrweHaZIakr3Ooljv22AIgPPJ0FyrHjhG8ZQUNoqz/c/DVN+Brk/hLXSV1gx2Kv+o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97912},"main":"dist/index.js","_from":"file:bernierllc-email-subscription-0.1.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean","test:run":"jest --watchAll=false --forceExit","test:coverage":"jest --coverage"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_resolved":"/Users/mattbernier/projects/tools/packages/service/email-subscription/bernierllc-email-subscription-0.1.0.tgz","_integrity":"sha512-tJuiqMCAjJM17gdGrfV+HbmufK6WXGEQYqctsQib/VDMrF6JTNK6BEWb2/3NFLhrULGesKTNxgx0uCDoM68doA==","repository":{"url":"git+https://github.com/bernier-llc/tools.git","type":"git"},"_npmVersion":"11.6.2","description":"Email subscription management service with list management, unsubscribe handling, and suppression list support","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/email-subscription_0.1.0_1772560233668_0.3346675398145402","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@bernierllc/email-subscription","version":"0.2.0","keywords":["email","subscription","unsubscribe","suppression","mailing-list","email-list","opt-out","bernierllc","typescript"],"author":{"name":"Bernier LLC"},"license":"PROPRIETARY","_id":"@bernierllc/email-subscription@0.2.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernier-llc/tools#readme","bugs":{"url":"https://github.com/bernier-llc/tools/issues"},"dist":{"shasum":"c098b047f4d987510a8afb01f061ad395c0d3380","tarball":"https://registry.npmjs.org/@bernierllc/email-subscription/-/email-subscription-0.2.0.tgz","fileCount":39,"integrity":"sha512-aJsnFjZKQXBMCNqx3D07vn1oGsVJ2RoMxa39kTku257SJPtYUuGm2Lktwktm6F1/ZvYIO2pO7NPYC0WcJXErpg==","signatures":[{"sig":"MEUCIQCLoxCaSP98oLCfDHU6e4j/M7muEvTPZYw19/ZYN3z6bAIgQvrcrr//Z7x1FrYBQv/GnxX9QqKZjCy2kzzFtMw1MSc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97912},"main":"dist/index.js","_from":"file:bernierllc-email-subscription-0.2.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean","test:run":"jest --watchAll=false --forceExit","test:coverage":"jest --coverage"},"_npmUser":{"name":"mkbernier","email":"mkbernier@gmail.com"},"_resolved":"/Users/mattbernier/projects/tools/packages/service/email-subscription/bernierllc-email-subscription-0.2.0.tgz","_integrity":"sha512-aJsnFjZKQXBMCNqx3D07vn1oGsVJ2RoMxa39kTku257SJPtYUuGm2Lktwktm6F1/ZvYIO2pO7NPYC0WcJXErpg==","repository":{"url":"git+https://github.com/bernier-llc/tools.git","type":"git"},"_npmVersion":"11.6.2","description":"Email subscription management service with list management, unsubscribe handling, and suppression list support","directories":{},"_nodeVersion":"25.2.1","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/email-subscription_0.2.0_1772569224027_0.9420179337581052","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@bernierllc/email-subscription","version":"0.2.1","keywords":["email","subscription","unsubscribe","suppression","mailing-list","email-list","opt-out","bernierllc","typescript"],"author":{"name":"Bernier LLC"},"license":"PROPRIETARY","_id":"@bernierllc/email-subscription@0.2.1","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernier-llc/tools#readme","bugs":{"url":"https://github.com/bernier-llc/tools/issues"},"dist":{"shasum":"4ba13816144215dc133340941a91772aa8686ac3","tarball":"https://registry.npmjs.org/@bernierllc/email-subscription/-/email-subscription-0.2.1.tgz","fileCount":39,"integrity":"sha512-pJOWBH0kETZky75I6lcB7UgaTTXNW+pumx0aMDfE662cGJTdRDc9seReW9Xoslo8/IAHo+69b+BnVpLtuQAMwQ==","signatures":[{"sig":"MEUCIQDnodJQFnw6NnkTr9yYi/45Tw9s97+1Kc9Ij5cvV9iF4wIgX8f6Bb2S4SOVmfIDd5QH/5y4rj4jo9CFgijVIOtlqKU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97912},"main":"dist/index.js","_from":"file:bernierllc-email-subscription-0.2.1.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean","test:run":"jest --watchAll=false --forceExit","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:33cf4fa9-da64-49da-96d0-15ccad388642"}},"_resolved":"/home/runner/work/tools/tools/packages/service/email-subscription/bernierllc-email-subscription-0.2.1.tgz","_integrity":"sha512-pJOWBH0kETZky75I6lcB7UgaTTXNW+pumx0aMDfE662cGJTdRDc9seReW9Xoslo8/IAHo+69b+BnVpLtuQAMwQ==","repository":{"url":"git+https://github.com/bernier-llc/tools.git","type":"git"},"_npmVersion":"11.11.0","description":"Email subscription management service with list management, unsubscribe handling, and suppression list support","directories":{},"_nodeVersion":"20.20.0","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/email-subscription_0.2.1_1773161079173_0.3232492801072002","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@bernierllc/email-subscription","version":"0.3.0","keywords":["email","subscription","unsubscribe","suppression","mailing-list","email-list","opt-out","bernierllc","typescript"],"author":{"name":"Bernier LLC"},"license":"PROPRIETARY","_id":"@bernierllc/email-subscription@0.3.0","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"homepage":"https://github.com/bernier-llc/tools#readme","bugs":{"url":"https://github.com/bernier-llc/tools/issues"},"dist":{"shasum":"08a9e25a42fe589f74ee87980b733d976a381af9","tarball":"https://registry.npmjs.org/@bernierllc/email-subscription/-/email-subscription-0.3.0.tgz","fileCount":39,"integrity":"sha512-L79NtvkNKK58fEY/202wcnjG7Zi7okFoDhJWQ3+Y0XRHlPAL4tMX9fcdrTblorelozJmXNoABP2xkjMWAu82OA==","signatures":[{"sig":"MEYCIQDORjWPVWpYAmbYJ9bhT10Od3JdE0dcdzkIsb+NwOF+0QIhAKTIiOyc4K3tc65BfWMZYKbaZenffsr/l2VW/s2/yoN4","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":97912},"main":"dist/index.js","_from":"file:bernierllc-email-subscription-0.3.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"lint":"eslint src --ext .ts","test":"jest","build":"tsc","clean":"rm -rf dist","lint:fix":"eslint src --ext .ts --fix","prebuild":"npm run clean","test:run":"jest --watchAll=false --forceExit","test:coverage":"jest --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:33cf4fa9-da64-49da-96d0-15ccad388642"}},"_resolved":"/home/runner/work/tools/tools/packages/service/email-subscription/bernierllc-email-subscription-0.3.0.tgz","_integrity":"sha512-L79NtvkNKK58fEY/202wcnjG7Zi7okFoDhJWQ3+Y0XRHlPAL4tMX9fcdrTblorelozJmXNoABP2xkjMWAu82OA==","repository":{"url":"git+https://github.com/bernier-llc/tools.git","type":"git"},"_npmVersion":"11.14.1","description":"Email subscription management service with list management, unsubscribe handling, and suppression list support","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0","@types/jest":"^29.5.0","@types/node":"^20.0.0"},"_npmOperationalInternal":{"tmp":"tmp/email-subscription_0.3.0_1779241677705_0.06974812758470272","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bernierllc/email-subscription","version":"0.4.0","description":"Email subscription management service with list management, unsubscribe handling, and suppression list support","main":"dist/index.js","types":"dist/index.d.ts","keywords":["email","subscription","unsubscribe","suppression","mailing-list","email-list","opt-out","bernierllc","typescript"],"author":{"name":"Bernier LLC"},"license":"PROPRIETARY","repository":{"type":"git","url":"git+https://github.com/bernier-llc/tools.git"},"devDependencies":{"@types/jest":"^29.5.0","@types/node":"^20.0.0","jest":"^29.5.0","ts-jest":"^29.1.0","typescript":"^5.0.0"},"engines":{"node":">=18.0.0"},"publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"scripts":{"build":"tsc","test":"jest","test:run":"jest --watchAll=false --forceExit","test:coverage":"jest --coverage","lint":"eslint src --ext .ts","lint:fix":"eslint src --ext .ts --fix","clean":"rm -rf dist","prebuild":"npm run clean"},"_id":"@bernierllc/email-subscription@0.4.0","bugs":{"url":"https://github.com/bernier-llc/tools/issues"},"homepage":"https://github.com/bernier-llc/tools#readme","_integrity":"sha512-69zEqYX0dZJhB94cQVcNiUVPRfuQTRJ09B54+YD5UXdIa6HpvubyBDrI1LqKWI0Tf8HOUIOzv5r9qriVLULvrg==","_resolved":"/home/runner/work/tools/tools/packages/service/email-subscription/bernierllc-email-subscription-0.4.0.tgz","_from":"file:bernierllc-email-subscription-0.4.0.tgz","_nodeVersion":"20.20.2","_npmVersion":"11.14.1","dist":{"integrity":"sha512-69zEqYX0dZJhB94cQVcNiUVPRfuQTRJ09B54+YD5UXdIa6HpvubyBDrI1LqKWI0Tf8HOUIOzv5r9qriVLULvrg==","shasum":"06ad69d0335aa424cf631774da2704dd11cc6ae2","tarball":"https://registry.npmjs.org/@bernierllc/email-subscription/-/email-subscription-0.4.0.tgz","fileCount":39,"unpackedSize":97912,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIBpcWqTAPbWA9Vc1xbzafE+oMLiodwZQ65bc41xGbGdHAiArIXVKplqoV9yqtpFkpQaRN7+GJ7VOcGjXSFID34dGOg=="}]},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:33cf4fa9-da64-49da-96d0-15ccad388642"}},"directories":{},"maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/email-subscription_0.4.0_1779250424061_0.822715778209274"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-22T04:16:02.570Z","modified":"2026-05-20T04:13:44.329Z","0.0.1":"2026-02-22T04:16:02.901Z","0.1.0":"2026-03-03T17:50:33.807Z","0.2.0":"2026-03-03T20:20:24.226Z","0.2.1":"2026-03-10T16:44:39.314Z","0.3.0":"2026-05-20T01:47:57.926Z","0.4.0":"2026-05-20T04:13:44.200Z"},"bugs":{"url":"https://github.com/bernier-llc/tools/issues"},"author":{"name":"Bernier LLC"},"license":"PROPRIETARY","homepage":"https://github.com/bernier-llc/tools#readme","keywords":["email","subscription","unsubscribe","suppression","mailing-list","email-list","opt-out","bernierllc","typescript"],"repository":{"type":"git","url":"git+https://github.com/bernier-llc/tools.git"},"description":"Email subscription management service with list management, unsubscribe handling, and suppression list support","maintainers":[{"name":"alikhan410","email":"mczeyo@gmail.com"},{"name":"mkbernier","email":"mkbernier@gmail.com"}],"readme":"# @bernierllc/email-subscription\n\nEmail subscription management service with list management, unsubscribe handling, preference centers, suppression list support, and provider synchronization. Works independently of the underlying email provider.\n\n## Installation\n\n```bash\nnpm install @bernierllc/email-subscription\n```\n\n## Usage\n\n```typescript\nimport {\n  SubscriptionListManager,\n  UnsubscribeManager,\n  SuppressionManager,\n  PreferenceCenterManager,\n  InMemorySubscriptionStore,\n} from '@bernierllc/email-subscription';\n\nconst store = new InMemorySubscriptionStore();\nconst listManager = new SubscriptionListManager(store);\n\n// Create a mailing list\nconst list = await listManager.createList({\n  name: 'Weekly Newsletter',\n  description: 'Our weekly product updates',\n});\n\n// Add subscribers\nawait listManager.addSubscriber(list.id, {\n  email: 'user@example.com',\n  name: 'Jane Doe',\n});\n\n// Manage unsubscribes\nconst unsubscribeManager = new UnsubscribeManager(store);\nawait unsubscribeManager.unsubscribe('user@example.com', list.id);\n\n// Manage suppression lists\nconst suppressionManager = new SuppressionManager(store);\nawait suppressionManager.addSuppression({\n  email: 'bounced@example.com',\n  reason: 'hard_bounce',\n});\n\n// Preference center\nconst preferenceManager = new PreferenceCenterManager(store);\nconst preferences = await preferenceManager.getPreferences('user@example.com');\n```\n\n## Exports\n\n- `SubscriptionListManager` -- manage subscriber lists (create, add/remove subscribers, bulk operations)\n- `UnsubscribeManager` -- handle opt-out requests and one-click unsubscribe\n- `SuppressionManager` -- maintain suppression lists (bounces, complaints)\n- `PreferenceCenterManager` -- subscriber preference centers and URL generation\n- `ProviderSyncManager` -- synchronize subscription data with provider-level systems\n- `InMemorySubscriptionStore` -- in-memory store for development and testing\n- `SubscriptionError` -- custom error class with error codes\n- Types: `SubscriberList`, `Subscriber`, `Suppression`, `SubscriptionPreference`, `ProviderSyncAdapter`, and more\n\n## Provider Capability Support\n\nThis section documents how subscription management behaves across email providers, based on the canonical `CAPABILITY_MATRIX` in `@bernierllc/email-manager`.\n\n### Capability Levels by Provider\n\n| Provider | Capability Level | Notes |\n|----------|-----------------|-------|\n| SendGrid | **enhanced** | Platform subscription management enhanced with SendGrid Contacts API for list sync |\n| Mailgun | **enhanced** | Platform subscription management enhanced with Mailgun mailing list sync |\n| Postmark | **platform** | Fully platform-managed; Postmark has no native list management |\n| SES | **platform** | Fully platform-managed; SES has no native list management |\n| SMTP | **platform** | Fully platform-managed; SMTP has no native capabilities |\n\n### How It Works\n\n- **Enhanced** (SendGrid, Mailgun): This package provides the full subscription management layer (lists, preferences, unsubscribe handling, suppression). Additionally, the `ProviderSyncManager` synchronizes subscriber data with the provider's native contact/list APIs. Unsubscribes and suppressions flow both directions -- provider-side events (e.g., a bounce processed by SendGrid) are pulled into the platform, and platform-side unsubscribes are pushed to the provider.\n\n- **Platform-level** (Postmark, SES, SMTP): This package handles all subscription management entirely at the platform level. There is no provider-side list to synchronize with. The platform maintains its own subscriber store, preference center, and suppression lists.\n\n### Degradation Behavior\n\nThere is no degradation in the traditional sense. This package always provides full subscription management functionality regardless of provider. The only difference is whether provider sync is available:\n\n- **With provider sync** (SendGrid, Mailgun): Two-way synchronization keeps platform and provider lists in alignment\n- **Without provider sync** (Postmark, SES, SMTP): The platform is the single source of truth; no sync is needed or attempted\n- **Strategy**: `platform-managed` for providers without native list management\n\n### Override Options\n\nThe subscription management capability is marked `overridable: true` at the platform level, allowing you to replace or extend the built-in subscription store with a custom implementation:\n\n```typescript\nimport { SubscriptionStore } from '@bernierllc/email-subscription';\n\nclass PostgresSubscriptionStore implements SubscriptionStore {\n  // Custom implementation backed by PostgreSQL\n}\n\nconst store = new PostgresSubscriptionStore();\nconst listManager = new SubscriptionListManager(store);\n```\n\n### Provider Independence\n\nThis package is designed to work identically across all providers. You can switch email providers without losing subscription data, preference settings, or suppression history. The `ProviderSyncManager` is an optional enhancement -- the core subscription system functions without it.\n\n## License\n\nCopyright (c) 2025 Bernier LLC. All rights reserved.\n\nThis package is licensed to the client under a limited-use license. The client may use and modify this code only within the scope of the project it was delivered for. Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.\n","readmeFilename":"README.md"}