notiformer 1.0.3 → 1.0.5

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/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # notiformer
2
2
 
3
- Real-time alerts and feature gates for your backend code.
3
+ Real-time push notifications and feature gates for your code.
4
4
 
5
- Get notified instantly via push, email and more whenever something important happens in your app.
5
+ Know the moment something important happens in your app — a new sale, an error, a spike in costs. Get notified on your phone via the **Notiformer app** (iOS & Android), or in your inbox.
6
6
 
7
- > ⚠️ **Server-side only.** Do not use in browser/frontend code — your API key would be exposed publicly. Use in Node.js, Express, Next.js API routes, serverless functions, etc.
7
+ > **Works everywhere.** Use in Node.js, Express, Next.js API routes, serverless functions, Python, Go, or any HTTP client.
8
8
 
9
9
  ---
10
10
 
@@ -21,69 +21,142 @@ npm install notiformer
21
21
  ```ts
22
22
  import { Notiformer } from 'notiformer';
23
23
 
24
- // Get your API key at https://app.notiformer.com/projects
25
24
  const n = new Notiformer({
26
- apiKey: 'ntf_live_test', // replace this with your real key
25
+ apiKey: 'ntf_live_...', // from app.notiformer.com/projects
27
26
  });
28
27
 
29
28
  await n.event({
30
- channel: 'payments',
31
- event: 'payment_success',
32
- description: '$49.00 — john@example.com',
33
- icon: '💳',
34
- notify: true,
29
+ channel: 'payments', // groups related events — auto-created on first use
30
+ event: 'payment_success', // machine-readable event name
31
+ description: '$49.00 — john@example.com', // optional human-readable detail
32
+ icon: '💳', // optional emoji shown in the feed and notification
33
+ tags: { userId: 'usr_123', plan: 'pro' }, // optional key-value metadata
34
+ value: '$49.00', // optional value highlighted in the feed
35
+ notify: true, // true → push notification | false → silent log only
36
+ recipients: ['you@company.com'], // optional — notify specific people only (see below)
35
37
  });
36
38
  ```
37
39
 
38
- > Running with `apiKey: 'ntf_live_test'` will print a setup message in your console explaining how to get your real key. No events will be sent until you replace it.
40
+ > **Tip:** Use `apiKey: 'ntf_live_test'` to get started without a real key. The SDK will print setup instructions in your console and skip all API calls.
39
41
 
40
42
  ---
41
43
 
42
44
  ## Get your API key
43
45
 
44
- 1. Go to [app.notiformer.com/projects](https://app.notiformer.com/projects)
45
- 2. Create or open a project
46
- 3. Copy the API key
47
- 4. Replace `'ntf_live_test'` in your code
46
+ 1. Go to [app.notiformer.com](https://app.notiformer.com) and create an account (free)
47
+ 2. Create a project
48
+ 3. Copy the API key from the project overview
49
+ 4. Replace `'ntf_live_test'` in your code with your real key
48
50
 
49
51
  ---
50
52
 
51
- ## Events
53
+ ## `event()` — Send an event
52
54
 
53
55
  ```ts
54
56
  await n.event({
55
- channel: 'auth', // groups related events (auto-created on first use)
56
- event: 'user_signup', // machine-readable name
57
- description: 'New signup via Google',
58
- icon: '🎉',
57
+ channel: 'payments', // required string, lowercase, a-z 0-9 - _
58
+ event: 'payment_success', // required — machine-readable event name
59
+
60
+ description: '$49.00 — john@example.com', // optional
61
+ icon: '💳', // optional — emoji
62
+ tags: { plan: 'pro', userId: '123' }, // optional — displayed in the event feed
63
+ value: '$49.00', // optional — highlighted value in the feed
64
+ notify: true, // optional — default: true
65
+ recipients: ['alice@company.com'], // optional — see "Targeting specific people"
66
+ });
67
+ ```
68
+
69
+ ### `notify`
70
+
71
+ | Value | Behaviour |
72
+ |---|---|
73
+ | `true` (default) | Sends push notification to subscribed members |
74
+ | `false` | Stores the event silently for analytics — no notification sent |
75
+
76
+ ### Return value
59
77
 
60
- tags: { method: 'google', plan: 'free' }, // optional metadata
61
- value: '42nd user', // optional value shown in the feed
78
+ ```ts
79
+ const result = await n.event({ ... });
80
+ // result is null if the call failed (never throws by default)
81
+ // result.rateLimited === true if you exceeded 60 events/minute (event is stored, notification skipped)
82
+ ```
83
+
84
+ `event()` **never throws by default.** A failed notification will never crash your app. If you prefer it to throw, pass `throwOnError: true` in the config.
85
+
86
+ ---
62
87
 
63
- notify: true, // true → triggers push/email notifications
64
- // false → silent log for analytics only
88
+ ## Targeting specific people `recipients`
89
+
90
+ By default, when `notify: true`, all members of the project who are subscribed to that channel receive a notification.
91
+
92
+ You can override this and target specific people by email:
93
+
94
+ ```ts
95
+ await n.event({
96
+ channel: 'payments',
97
+ event: 'large_order',
98
+ description: '$2,400 — enterprise@client.com',
99
+ notify: true,
100
+ recipients: ['cto@company.com', 'billing@company.com'], // only these two are notified
65
101
  });
66
102
  ```
67
103
 
68
- `event()` **never throws** by default. If something goes wrong it logs a warning and returns `null` — a failed notification should never crash your app.
104
+ **How it works:**
105
+ - If a recipient has a Notiformer account linked to that email and has installed the app, they receive a **push notification**
106
+ - Email notifications are **coming soon** — recipients will receive emails once this feature launches
107
+ - If you don't specify `recipients`, all project members subscribed to the channel are notified
108
+
109
+ **Plan limits for `recipients`:**
110
+
111
+ | Plan | Max recipients per event |
112
+ |---|---|
113
+ | Free | 1 |
114
+ | Starter | 3 |
115
+ | Pro | 10 |
116
+ | Business | 30 |
117
+
118
+ > Members are managed from the project dashboard at [app.notiformer.com](https://app.notiformer.com/projects).
69
119
 
70
120
  ---
71
121
 
72
- ## Feature Gates
122
+ ## `gate()` — Feature gates
73
123
 
74
- Toggle features remotely from your Notiformer dashboard without redeploying.
124
+ Toggle features in your code remotely from the Notiformer dashboard no redeploy needed.
75
125
 
76
126
  ```ts
77
127
  const isEnabled = await n.gate('new-checkout-flow');
78
128
 
79
129
  if (isEnabled) {
80
- // run new feature
130
+ // new behaviour
81
131
  } else {
82
- // run old feature
132
+ // old behaviour
83
133
  }
84
134
  ```
85
135
 
86
- Gates are cached for 30 seconds by default to minimise API calls.
136
+ Gates are **cached locally for 30 seconds** by default to avoid hammering the API on every request.
137
+
138
+ ### Options
139
+
140
+ ```ts
141
+ const isEnabled = await n.gate('my-gate', {
142
+ fallback: false, // optional — returned if the gate can't be fetched (default: false)
143
+ cacheTtl: 60, // optional — cache duration in seconds (default: 30)
144
+ });
145
+ ```
146
+
147
+ ### Full gate result
148
+
149
+ ```ts
150
+ const result = await n.gateDetails('my-gate');
151
+ // { key: 'my-gate', enabled: true, cached: false, fetchedAt: '2025-...' }
152
+ ```
153
+
154
+ ### Clear the cache
155
+
156
+ ```ts
157
+ n.clearGateCache('my-gate'); // clear a specific gate
158
+ n.clearGateCache(); // clear all gates
159
+ ```
87
160
 
88
161
  ---
89
162
 
@@ -91,12 +164,11 @@ Gates are cached for 30 seconds by default to minimise API calls.
91
164
 
92
165
  ```ts
93
166
  const n = new Notiformer({
94
- apiKey: 'ntf_live_...', // required — from app.notiformer.com/projects
95
-
96
- silent: false, // true = no calls made (useful for local dev)
97
- throwOnError: false, // true = throws instead of returning null
98
- onError: (err) => { // called on any failed call
99
- console.error(err.message);
167
+ apiKey: 'ntf_live_...', // required — from app.notiformer.com/projects
168
+ silent: false, // optional — true = no API calls (great for local dev)
169
+ throwOnError: false, // optional — true = throws instead of returning null
170
+ onError: (err) => { // optional called when any call fails
171
+ Sentry.captureException(err);
100
172
  },
101
173
  });
102
174
  ```
@@ -106,65 +178,165 @@ const n = new Notiformer({
106
178
  ```ts
107
179
  const n = new Notiformer({
108
180
  apiKey: process.env.NOTIFORMER_API_KEY!,
109
- silent: process.env.NODE_ENV !== 'production',
181
+ silent: process.env.NODE_ENV !== 'production', // no calls in dev/test
110
182
  });
111
183
  ```
112
184
 
113
185
  ---
114
186
 
187
+ ## Rate limits & quotas
188
+
189
+ | Limit | Value |
190
+ |---|---|
191
+ | Events per minute (per project) | 60 |
192
+ | Events per month (Free plan) | 500 |
193
+ | Events per month (Starter) | 20,000 |
194
+ | Events per month (Pro) | 75,000 |
195
+ | Events per month (Business) | 300,000 |
196
+
197
+ If you exceed **60 events/minute**: the event is stored and visible in your feed, but no notification is sent. The API response includes `rateLimited: true`.
198
+
199
+ If you exceed your **monthly quota**: the event is rejected with HTTP 429. Upgrade your plan at [app.notiformer.com/settings](https://app.notiformer.com/settings).
200
+
201
+ ---
202
+
115
203
  ## Common patterns
116
204
 
205
+ ### Alert on payment success
206
+
207
+ ```ts
208
+ await n.event({
209
+ channel: 'payments',
210
+ event: 'payment_success',
211
+ description: `${amount} — ${user.email}`,
212
+ icon: '💳',
213
+ value: amount,
214
+ notify: true,
215
+ });
216
+ ```
217
+
117
218
  ### Alert on unhandled errors
118
219
 
119
220
  ```ts
221
+ // Express error middleware
120
222
  app.use(async (err, req, res, next) => {
121
223
  await n.event({
122
- channel: 'errors',
123
- event: 'unhandled_error',
224
+ channel: 'errors',
225
+ event: 'unhandled_error',
124
226
  description: err.message,
125
- icon: '🔴',
126
- tags: { path: req.path, status: 500 },
127
- notify: true,
227
+ icon: '🔴',
228
+ tags: { path: req.path, method: req.method },
229
+ notify: true,
128
230
  });
129
231
  res.status(500).json({ error: 'Internal server error' });
130
232
  });
131
233
  ```
132
234
 
133
- ### Track a payment
235
+ ### Silent analytics (no notification)
134
236
 
135
237
  ```ts
136
238
  await n.event({
137
- channel: 'payments',
138
- event: 'payment_success',
139
- description: `${amount} ${user.email}`,
140
- icon: '💳',
141
- value: amount,
142
- notify: true,
239
+ channel: 'analytics',
240
+ event: 'page_view',
241
+ tags: { path: req.path, userId: session.userId },
242
+ notify: false, // stored in feed, no push notification sent
143
243
  });
144
244
  ```
145
245
 
146
- ### Feature gate
246
+ ### Feature gate in an API route
147
247
 
148
248
  ```ts
149
- app.post('/checkout', async (req, res) => {
249
+ // Next.js API route
250
+ export async function POST(req: Request) {
150
251
  const useNewFlow = await n.gate('new-checkout-flow');
151
- return useNewFlow
152
- ? newCheckoutHandler(req, res)
153
- : legacyCheckoutHandler(req, res);
154
- });
252
+
253
+ if (useNewFlow) {
254
+ return newCheckoutHandler(req);
255
+ }
256
+ return legacyCheckoutHandler(req);
257
+ }
155
258
  ```
156
259
 
157
- ### Silent analytics (no notification)
260
+ ### Notify a specific person
158
261
 
159
262
  ```ts
263
+ // Only notify the CTO for large orders
160
264
  await n.event({
161
- channel: 'monitoring',
162
- event: 'page_view',
163
- tags: { path: req.path },
164
- notify: false, // ← no notification, just logged
265
+ channel: 'sales',
266
+ event: 'enterprise_signup',
267
+ description: `${company} ${mrr}/mo`,
268
+ icon: '🏢',
269
+ value: mrr,
270
+ notify: true,
271
+ recipients: ['cto@yourcompany.com'], // only they get the push
165
272
  });
166
273
  ```
167
274
 
275
+ ### Using with Python (REST API)
276
+
277
+ Notiformer works from any language via the REST API:
278
+
279
+ ```python
280
+ import requests
281
+
282
+ requests.post(
283
+ 'https://api.notiformer.com/v1/events',
284
+ headers={ 'Authorization': f'Bearer {NF_KEY}' },
285
+ json={
286
+ 'channel': 'ai-costs',
287
+ 'event': 'cost_spike',
288
+ 'description': '🤖 $180 spent in 10 min',
289
+ 'notify': True,
290
+ 'recipients': ['cto@company.com'], # optional
291
+ }
292
+ )
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Receiving notifications
298
+
299
+ Push notifications are delivered via the **Notiformer app**, available for iOS and Android.
300
+
301
+ 1. Download the Notiformer app from the App Store or Google Play
302
+ 2. Sign in with your Notiformer account
303
+ 3. You'll automatically receive push notifications for projects you own or are a member of
304
+ 4. Manage which channels you're subscribed to from the app settings
305
+
306
+ > **Email notifications** are in development and coming soon. Sign up at [notiformer.com](https://notiformer.com) to be notified when they launch.
307
+
308
+ ---
309
+
310
+ ## REST API
311
+
312
+ The same `event()` call maps to this endpoint:
313
+
314
+ ```
315
+ POST https://api.notiformer.com/v1/events
316
+ Authorization: Bearer ntf_live_...
317
+ Content-Type: application/json
318
+
319
+ {
320
+ "channel": "payments",
321
+ "event": "payment_success",
322
+ "description": "$49.00 — john@example.com",
323
+ "icon": "💳",
324
+ "tags": { "plan": "pro" },
325
+ "value": "$49.00",
326
+ "notify": true,
327
+ "recipients": ["you@company.com"]
328
+ }
329
+ ```
330
+
331
+ Response:
332
+ ```json
333
+ {
334
+ "id": "evt_abc123",
335
+ "createdAt": "2025-01-15T10:30:00.000Z",
336
+ "rateLimited": false
337
+ }
338
+ ```
339
+
168
340
  ---
169
341
 
170
342
  ## Requirements
@@ -176,5 +348,7 @@ await n.event({
176
348
 
177
349
  ## Links
178
350
 
179
- - Dashboard: [app.notiformer.com](https://app.notiformer.com)
180
- - Docs: [docs.notiformer.com](https://docs.notiformer.com)
351
+ - **Dashboard:** [app.notiformer.com](https://app.notiformer.com)
352
+ - **Docs:** [docs.notiformer.com](https://docs.notiformer.com)
353
+ - **Status:** [status.notiformer.com](https://status.notiformer.com)
354
+ - **Pricing:** [notiformer.com/#pricing](https://notiformer.com/#pricing)
package/dist/index.d.ts CHANGED
@@ -1,19 +1,22 @@
1
1
  /**
2
2
  * Notiformer — Real-time alerts and feature gates for your code.
3
3
  *
4
+ * Works in Node.js (backend) and the browser (frontend).
5
+ *
4
6
  * @example
5
7
  * import { Notiformer } from 'notiformer';
6
8
  *
7
- * const n = new Notiformer({
8
- * apiKey: 'ntf_live_xxxxxxxxxxxxxxxx', // from app.notiformer.com/projects
9
- * });
9
+ * const n = new Notiformer({ apiKey: 'ntf_live_...' });
10
+ *
11
+ * // Notify everyone subscribed to the 'payments' channel
12
+ * await n.event({ channel: 'payments', event: 'new_sale', notify: true });
10
13
  *
14
+ * // Notify specific people only
11
15
  * await n.event({
12
16
  * channel: 'payments',
13
- * event: 'payment_success',
14
- * description: '$49.00 — john@example.com',
15
- * icon: '💳',
17
+ * event: 'refund_requested',
16
18
  * notify: true,
19
+ * recipients: ['admin@company.com', 'billing@company.com'],
17
20
  * });
18
21
  */
19
22
  import type { NotiformerConfig, EventPayload, EventResponse, GateOptions, GateResult } from "./types";
@@ -30,22 +33,23 @@ export declare class Notiformer {
30
33
  private readonly isPlaceholder;
31
34
  constructor(config: NotiformerConfig);
32
35
  /**
33
- * Send an event and optionally trigger a notification.
36
+ * Send an event and optionally notify recipients.
34
37
  *
35
- * Safe to use anywhere in your code never throws by default.
36
- * Returns null if the call fails (and calls onError if configured).
38
+ * - Without `recipients`: notifies the project owner + all members
39
+ * subscribed to the event's channel.
40
+ * - With `recipients`: notifies only the specified email addresses
41
+ * (must be project members). Overrides the default behaviour.
42
+ *
43
+ * Never throws by default — returns null if the call fails.
37
44
  */
38
45
  event(payload: EventPayload): Promise<EventResponse | null>;
39
46
  /**
40
47
  * Check whether a feature gate is enabled.
41
- * Cached locally for 30 seconds by default.
42
- *
43
- * Returns fallback (false) if the call fails.
48
+ * Results are cached locally for 30 seconds by default.
49
+ * Returns false if the call fails.
44
50
  */
45
51
  gate(key: string, options?: GateOptions): Promise<boolean>;
46
- /** Full gate result with metadata */
47
52
  gateDetails(key: string, options?: GateOptions): Promise<GateResult>;
48
- /** Clear cached gate values */
49
53
  clearGateCache(key?: string): void;
50
54
  private post;
51
55
  private get;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,EACX,MAAM,SAAS,CAAC;AAIjB,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,GACX,CAAC;AAQF,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;gBAE5B,MAAM,EAAE,gBAAgB;IAwCpC;;;;;OAKG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAkDjE;;;;;OAKG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAsBpE,qCAAqC;IAC/B,WAAW,CACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC;IAKtB,+BAA+B;IAC/B,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;YAQpB,IAAI;YAOJ,GAAG;YAIH,OAAO;IAmBrB,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,oBAAoB;CAuB7B;AAED,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,EACX,MAAM,SAAS,CAAC;AAIjB,YAAY,EACV,gBAAgB,EAChB,YAAY,EACZ,aAAa,EACb,WAAW,EACX,UAAU,GACX,CAAC;AAOF,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAU;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAU;IACvC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAA8B;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAU;gBAE5B,MAAM,EAAE,gBAAgB;IAoCpC;;;;;;;;;OASG;IACG,KAAK,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAiDjE;;;;OAIG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAsB9D,WAAW,CACf,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,UAAU,CAAC;IAKtB,cAAc,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI;YAIpB,IAAI;YAIJ,GAAG;YAIH,OAAO;IAmBrB,OAAO,CAAC,IAAI;IAOZ,OAAO,CAAC,oBAAoB;CAmB7B;AAED,eAAe,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -2,26 +2,28 @@
2
2
  /**
3
3
  * Notiformer — Real-time alerts and feature gates for your code.
4
4
  *
5
+ * Works in Node.js (backend) and the browser (frontend).
6
+ *
5
7
  * @example
6
8
  * import { Notiformer } from 'notiformer';
7
9
  *
8
- * const n = new Notiformer({
9
- * apiKey: 'ntf_live_xxxxxxxxxxxxxxxx', // from app.notiformer.com/projects
10
- * });
10
+ * const n = new Notiformer({ apiKey: 'ntf_live_...' });
11
11
  *
12
+ * // Notify everyone subscribed to the 'payments' channel
13
+ * await n.event({ channel: 'payments', event: 'new_sale', notify: true });
14
+ *
15
+ * // Notify specific people only
12
16
  * await n.event({
13
17
  * channel: 'payments',
14
- * event: 'payment_success',
15
- * description: '$49.00 — john@example.com',
16
- * icon: '💳',
18
+ * event: 'refund_requested',
17
19
  * notify: true,
20
+ * recipients: ['admin@company.com', 'billing@company.com'],
18
21
  * });
19
22
  */
20
23
  Object.defineProperty(exports, "__esModule", { value: true });
21
24
  exports.Notiformer = void 0;
22
25
  const logger_1 = require("./logger");
23
26
  const cache_1 = require("./cache");
24
- // The placeholder key shown in docs — triggers a friendly setup message
25
27
  const PLACEHOLDER_KEY = "ntf_live_test";
26
28
  const API_URL = "https://api.notiformer.com";
27
29
  const DEFAULT_TIMEOUT = 8000;
@@ -47,7 +49,7 @@ class Notiformer {
47
49
  "┌─────────────────────────────────────────────────────┐\n" +
48
50
  "│ notiformer — setup required │\n" +
49
51
  "├─────────────────────────────────────────────────────┤\n" +
50
- '│ You are using the example API key "ntf_live_test". │\n' +
52
+ '│ You are using the example key "ntf_live_test". │\n' +
51
53
  "│ Events will not be sent until you use a real key. │\n" +
52
54
  "│ │\n" +
53
55
  "│ 1. Go to https://app.notiformer.com/projects │\n" +
@@ -57,14 +59,15 @@ class Notiformer {
57
59
  "└─────────────────────────────────────────────────────┘\n");
58
60
  }
59
61
  }
60
- // ─────────────────────────────────────────────────────────────
61
- // event()
62
- // ─────────────────────────────────────────────────────────────
63
62
  /**
64
- * Send an event and optionally trigger a notification.
63
+ * Send an event and optionally notify recipients.
64
+ *
65
+ * - Without `recipients`: notifies the project owner + all members
66
+ * subscribed to the event's channel.
67
+ * - With `recipients`: notifies only the specified email addresses
68
+ * (must be project members). Overrides the default behaviour.
65
69
  *
66
- * Safe to use anywhere in your code never throws by default.
67
- * Returns null if the call fails (and calls onError if configured).
70
+ * Never throws by default returns null if the call fails.
68
71
  */
69
72
  async event(payload) {
70
73
  var _a, _b;
@@ -72,31 +75,36 @@ class Notiformer {
72
75
  throw new Error("[notiformer] event.channel is required.");
73
76
  if (!payload.event)
74
77
  throw new Error("[notiformer] event.event is required.");
75
- // Placeholder key — log a clear message, do not attempt the call
76
78
  if (this.isPlaceholder) {
77
- console.warn('[notiformer] Event not sent — you are using the example key "ntf_live_test".\n' +
78
- "→ Replace it with your real API key from https://app.notiformer.com/projects");
79
+ console.warn('[notiformer] Event not sent — using example key "ntf_live_test".\n' +
80
+ "→ Replace it with your real key from https://app.notiformer.com/projects");
79
81
  return null;
80
82
  }
81
- if (this.silent) {
82
- this.logger.info("Silent mode: event suppressed.");
83
+ if (this.silent)
83
84
  return null;
84
- }
85
85
  try {
86
- const res = await this.post("/v1/events", {
86
+ const body = {
87
87
  channel: payload.channel,
88
88
  event: payload.event,
89
- description: payload.description,
90
- icon: payload.icon,
91
- tags: payload.tags,
92
- value: payload.value,
93
89
  notify: (_a = payload.notify) !== null && _a !== void 0 ? _a : true,
94
- });
90
+ };
91
+ if (payload.description !== undefined)
92
+ body.description = payload.description;
93
+ if (payload.icon !== undefined)
94
+ body.icon = payload.icon;
95
+ if (payload.tags !== undefined)
96
+ body.tags = payload.tags;
97
+ if (payload.value !== undefined)
98
+ body.value = payload.value;
99
+ if (payload.recipients !== undefined && payload.recipients.length > 0) {
100
+ body.recipients = payload.recipients;
101
+ }
102
+ const res = await this.post("/v1/events", body);
95
103
  if (!res.ok) {
96
- const body = await res
104
+ const data = await res
97
105
  .json()
98
106
  .catch(() => ({ error: `HTTP ${res.status}` }));
99
- return this.fail(new Error(`[notiformer] ${(_b = body.error) !== null && _b !== void 0 ? _b : res.statusText}`));
107
+ return this.fail(new Error(`[notiformer] ${(_b = data.error) !== null && _b !== void 0 ? _b : res.statusText}`));
100
108
  }
101
109
  return (await res.json());
102
110
  }
@@ -104,14 +112,10 @@ class Notiformer {
104
112
  return this.fail(this.friendlyNetworkError(err));
105
113
  }
106
114
  }
107
- // ─────────────────────────────────────────────────────────────
108
- // gate()
109
- // ─────────────────────────────────────────────────────────────
110
115
  /**
111
116
  * Check whether a feature gate is enabled.
112
- * Cached locally for 30 seconds by default.
113
- *
114
- * Returns fallback (false) if the call fails.
117
+ * Results are cached locally for 30 seconds by default.
118
+ * Returns false if the call fails.
115
119
  */
116
120
  async gate(key, options = {}) {
117
121
  var _a, _b;
@@ -136,23 +140,15 @@ class Notiformer {
136
140
  return fallback;
137
141
  }
138
142
  }
139
- /** Full gate result with metadata */
140
143
  async gateDetails(key, options = {}) {
141
144
  const enabled = await this.gate(key, options);
142
145
  return { key, enabled, cached: false, fetchedAt: new Date().toISOString() };
143
146
  }
144
- /** Clear cached gate values */
145
147
  clearGateCache(key) {
146
148
  key ? this.gateCache.delete(key) : this.gateCache.clear();
147
149
  }
148
- // ─────────────────────────────────────────────────────────────
149
- // Private
150
- // ─────────────────────────────────────────────────────────────
151
150
  async post(path, body) {
152
- return this.request(path, {
153
- method: "POST",
154
- body: JSON.stringify(body),
155
- });
151
+ return this.request(path, { method: "POST", body: JSON.stringify(body) });
156
152
  }
157
153
  async get(path) {
158
154
  return this.request(path, { method: "GET" });
@@ -168,7 +164,7 @@ class Notiformer {
168
164
  headers: {
169
165
  "Content-Type": "application/json",
170
166
  Authorization: `Bearer ${this.apiKey}`,
171
- "X-SDK-Version": "1.0.3",
167
+ "X-SDK-Version": "1.0.5",
172
168
  ...((_a = init.headers) !== null && _a !== void 0 ? _a : {}),
173
169
  },
174
170
  });
@@ -188,14 +184,13 @@ class Notiformer {
188
184
  friendlyNetworkError(err) {
189
185
  const msg = err instanceof Error ? err.message.toLowerCase() : "";
190
186
  if (msg.includes("aborted") || msg.includes("timeout")) {
191
- return new Error(`[notiformer] Request timed out after ${this.timeout / 1000}s.\n` +
192
- "Check your internet connection or try again later.");
187
+ return new Error(`[notiformer] Request timed out after ${this.timeout / 1000}s.`);
193
188
  }
194
189
  if (msg.includes("failed to fetch") ||
195
190
  msg.includes("enotfound") ||
196
191
  msg.includes("network")) {
197
192
  return new Error("[notiformer] Cannot reach the Notiformer API.\n" +
198
- "Check your internet connection. If the problem persists, visit https://status.notiformer.com");
193
+ "Check your connection. If the issue persists: https://status.notiformer.com");
199
194
  }
200
195
  return err instanceof Error ? err : new Error(String(err));
201
196
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/logger.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { LogLevel } from './types';
1
+ import type { LogLevel } from "./types";
2
2
  export declare class Logger {
3
3
  private level;
4
4
  constructor(level?: LogLevel);
@@ -1 +1 @@
1
- {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAUxC,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,GAAE,QAAkB;IAIrC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI5C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAG7C"}
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAWxC,qBAAa,MAAM;IACjB,OAAO,CAAC,KAAK,CAAS;gBAEV,KAAK,GAAE,QAAkB;IAIrC,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAK5C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3C,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;IAI3C,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI;CAI7C"}
package/dist/logger.js CHANGED
@@ -7,9 +7,10 @@ const LEVELS = {
7
7
  warn: 2,
8
8
  error: 3,
9
9
  none: 4,
10
+ silent: 4,
10
11
  };
11
12
  class Logger {
12
- constructor(level = 'error') {
13
+ constructor(level = "error") {
13
14
  this.level = LEVELS[level];
14
15
  }
15
16
  debug(msg, ...args) {
@@ -1 +1 @@
1
- {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;AAEA,MAAM,MAAM,GAA6B;IACvC,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;CACR,CAAC;AAEF,MAAa,MAAM;IAGjB,YAAY,QAAkB,OAAO;QACnC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAChF,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;YAAE,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAChF,CAAC;CACF;AAtBD,wBAsBC"}
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":";;;AAEA,MAAM,MAAM,GAA6B;IACvC,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,IAAI,EAAE,CAAC;IACP,KAAK,EAAE,CAAC;IACR,IAAI,EAAE,CAAC;IACP,MAAM,EAAE,CAAC;CACV,CAAC;AAEF,MAAa,MAAM;IAGjB,YAAY,QAAkB,OAAO;QACnC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;YAC5B,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAClD,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,CAAC,GAAW,EAAE,GAAG,IAAe;QAClC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI;YAAE,OAAO,CAAC,IAAI,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAC9E,CAAC;IAED,KAAK,CAAC,GAAW,EAAE,GAAG,IAAe;QACnC,IAAI,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,KAAK;YAC5B,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,EAAE,EAAE,GAAG,IAAI,CAAC,CAAC;IAClD,CAAC;CACF;AAxBD,wBAwBC"}
package/dist/types.d.ts CHANGED
@@ -1,67 +1,47 @@
1
1
  export interface NotiformerConfig {
2
- /**
3
- * Your Notiformer API key.
4
- * Find it at: https://app.notiformer.com/projects
5
- *
6
- * @example
7
- * const n = new Notiformer({ apiKey: 'ntf_live_xxxxxxxxxxxxxxxx' })
8
- */
9
2
  apiKey: string;
10
- /**
11
- * Silence all SDK calls. Useful for local development.
12
- * No events will be sent, no network calls made.
13
- *
14
- * @example
15
- * const n = new Notiformer({
16
- * apiKey: process.env.NOTIFORMER_API_KEY,
17
- * silent: process.env.NODE_ENV !== 'production',
18
- * })
19
- */
20
3
  silent?: boolean;
21
- /**
22
- * Called when an event() or gate() call fails.
23
- * Use this to forward errors to your own logging system.
24
- *
25
- * @example
26
- * onError: (err) => console.error('[notiformer]', err.message)
27
- */
28
- onError?: (error: Error) => void;
29
- /**
30
- * If true, throws on failure instead of returning null silently.
31
- * Default: false — a failed notification should never crash your app.
32
- */
33
4
  throwOnError?: boolean;
34
- /** @internal do not use in production */
5
+ onError?: (err: Error) => void;
35
6
  _baseUrl?: string;
36
7
  }
37
8
  export interface EventPayload {
38
- /** Channel name. Groups related events. Created automatically. e.g. 'payments', 'errors' */
9
+ /** Channel name (lowercase, letters, numbers, hyphens, underscores). */
39
10
  channel: string;
40
- /** Event name. e.g. 'user_signed_up', 'payment_failed' */
11
+ /** Short event name. */
41
12
  event: string;
42
- /** Human-readable description shown in the dashboard */
43
13
  description?: string;
44
- /** Emoji icon shown in the feed */
45
14
  icon?: string;
46
- /** Optional key/value metadata for filtering */
47
15
  tags?: Record<string, string | number | boolean>;
48
- /** A value to display alongside the event. e.g. '$49.00' */
49
16
  value?: string | number;
50
17
  /**
51
- * If true, triggers your configured notifications (push, email…).
52
- * If false, logs silently for analytics only.
53
- * @default true
18
+ * Whether to send push/email notifications.
19
+ * Defaults to true.
54
20
  */
55
21
  notify?: boolean;
22
+ /**
23
+ * Specific email addresses to notify.
24
+ *
25
+ * If set, **only** these emails receive notifications — the default
26
+ * (owner + channel subscribers) is ignored.
27
+ *
28
+ * Each email must belong to a member of your project
29
+ * (added from the Notiformer dashboard).
30
+ *
31
+ * Plan limits: Free=1, Starter=3, Pro=10, Business=30.
32
+ *
33
+ * @example
34
+ * recipients: ['alice@company.com', 'bob@company.com']
35
+ */
36
+ recipients?: string[];
56
37
  }
57
38
  export interface EventResponse {
58
39
  id: string;
59
40
  createdAt: string;
41
+ rateLimited?: boolean;
60
42
  }
61
43
  export interface GateOptions {
62
- /** Returned if the request fails. @default false */
63
44
  fallback?: boolean;
64
- /** Cache duration in seconds. 0 to disable. @default 30 */
65
45
  cacheTtl?: number;
66
46
  }
67
47
  export interface GateResult {
@@ -70,5 +50,5 @@ export interface GateResult {
70
50
  cached: boolean;
71
51
  fetchedAt: string;
72
52
  }
73
- export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
53
+ export type LogLevel = "debug" | "info" | "warn" | "error" | "none" | "silent";
74
54
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B;;;;;;OAMG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,4FAA4F;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,wDAAwD;IACxD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACjD,4DAA4D;IAC5D,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,WAAW;IAC1B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACjD,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;;;;;;OAaG;IACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,CAAC"}
package/dist/types.js CHANGED
@@ -1,6 +1,3 @@
1
1
  "use strict";
2
- // ─────────────────────────────────────────────
3
- // Notiformer SDK — Public Types
4
- // ─────────────────────────────────────────────
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  //# sourceMappingURL=types.js.map
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";AAAA,gDAAgD;AAChD,gCAAgC;AAChC,gDAAgD"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "notiformer",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "Real-time alerts, notifications and feature gates for your backend code",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",