@gravito/flare 4.0.0 → 4.0.2
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 +34 -12
- package/dist/index.cjs +63 -7
- package/dist/index.d.cts +21 -4
- package/dist/index.d.ts +21 -4
- package/dist/index.js +63 -7
- package/package.json +8 -6
package/README.md
CHANGED
|
@@ -4,18 +4,32 @@
|
|
|
4
4
|
|
|
5
5
|
**Status**: v3.4.0 - Production ready with advanced features (Retries, Metrics, Batching, Timeout, Rate Limiting, Preference Driver).
|
|
6
6
|
|
|
7
|
-
## Features
|
|
8
|
-
|
|
9
|
-
- **
|
|
10
|
-
- **Multi-
|
|
11
|
-
- **
|
|
12
|
-
- **Reliability**: Built-in
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
7
|
+
## ✨ Key Features
|
|
8
|
+
|
|
9
|
+
- 🪐 **Galaxy-Ready Notifications**: Native integration with PlanetCore for universal user notification across all Satellites.
|
|
10
|
+
- 📡 **Multi-Channel Delivery**: Seamlessly broadcast via **Mail**, **SMS**, **Slack**, **Discord**, and **Push Notifications**.
|
|
11
|
+
- 🛠️ **Distributed Preference Management**: User-level notification settings that persist across the entire Galaxy.
|
|
12
|
+
- 🛡️ **Reliability Stack**: Built-in exponential backoff, timeout protection, and automatic retries.
|
|
13
|
+
- 🚀 **High Performance**: Parallel channel execution and batch sending optimized for Bun.
|
|
14
|
+
- ⚙️ **Queue Integration**: Offload notification delivery to `@gravito/stream` with zero configuration.
|
|
15
|
+
|
|
16
|
+
## 🌌 Role in Galaxy Architecture
|
|
17
|
+
|
|
18
|
+
In the **Gravito Galaxy Architecture**, Flare acts as the **Communication Flux (Nervous System Extension)**.
|
|
19
|
+
|
|
20
|
+
- **Outbound Feedback**: Provides the primary mechanism for Satellites to communicate directly with users (e.g., "Your order has shipped" from the `Shop` Satellite).
|
|
21
|
+
- **Preference Guard**: Ensures that user privacy and communication preferences are respected globally, regardless of which Satellite initiates the notification.
|
|
22
|
+
- **Micro-Infrastructure Bridge**: Connects internal domain events to external communication providers (Twilio, AWS, SendGrid) without bloating Satellite logic.
|
|
23
|
+
|
|
24
|
+
```mermaid
|
|
25
|
+
graph LR
|
|
26
|
+
S[Satellite: Order] -- "Notify" --> Flare{Flare Orbit}
|
|
27
|
+
Flare -->|Check| Pref[User Preferences]
|
|
28
|
+
Flare -->|Route| C1[Mail: SES]
|
|
29
|
+
Flare -->|Route| C2[SMS: Twilio]
|
|
30
|
+
Flare -->|Route| C3[Social: Slack]
|
|
31
|
+
Flare -.->|Queue| Stream[Stream Orbit]
|
|
32
|
+
```
|
|
19
33
|
|
|
20
34
|
## Installation
|
|
21
35
|
|
|
@@ -276,6 +290,14 @@ OrbitFlare.configure({
|
|
|
276
290
|
})
|
|
277
291
|
```
|
|
278
292
|
|
|
293
|
+
## 📚 Documentation
|
|
294
|
+
|
|
295
|
+
Detailed guides and references for the Galaxy Architecture:
|
|
296
|
+
|
|
297
|
+
- [🏗️ **Architecture Overview**](./README.md) — Multi-channel notification core.
|
|
298
|
+
- [📡 **Notification Strategies**](./doc/NOTIFICATION_STRATEGIES.md) — **NEW**: Multi-channel routing, preferences, and queuing.
|
|
299
|
+
- [⚙️ **Queue Support**](#-queue-support) — Asynchronous delivery with `@gravito/stream`.
|
|
300
|
+
|
|
279
301
|
## API Reference
|
|
280
302
|
|
|
281
303
|
### NotificationManager
|
package/dist/index.cjs
CHANGED
|
@@ -262,16 +262,23 @@ var TimeoutChannel = class {
|
|
|
262
262
|
}
|
|
263
263
|
const controller = new AbortController();
|
|
264
264
|
const { signal } = controller;
|
|
265
|
+
let timeoutId;
|
|
266
|
+
let settled = false;
|
|
267
|
+
let handleExternalAbort;
|
|
265
268
|
if (options?.signal) {
|
|
266
269
|
if (options.signal.aborted) {
|
|
267
270
|
throw new AbortError("Request was aborted before sending");
|
|
268
271
|
}
|
|
269
|
-
|
|
272
|
+
handleExternalAbort = () => {
|
|
270
273
|
controller.abort();
|
|
271
|
-
}
|
|
274
|
+
};
|
|
275
|
+
options.signal.addEventListener("abort", handleExternalAbort, { once: true });
|
|
272
276
|
}
|
|
273
277
|
const timeoutPromise = new Promise((_, reject) => {
|
|
274
|
-
setTimeout(() => {
|
|
278
|
+
timeoutId = setTimeout(() => {
|
|
279
|
+
if (settled) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
275
282
|
if (this.config.onTimeout) {
|
|
276
283
|
this.config.onTimeout(this.inner.constructor.name, notification);
|
|
277
284
|
}
|
|
@@ -292,7 +299,17 @@ var TimeoutChannel = class {
|
|
|
292
299
|
}
|
|
293
300
|
throw error;
|
|
294
301
|
});
|
|
295
|
-
|
|
302
|
+
try {
|
|
303
|
+
return await Promise.race([sendPromise, timeoutPromise]);
|
|
304
|
+
} finally {
|
|
305
|
+
settled = true;
|
|
306
|
+
if (timeoutId) {
|
|
307
|
+
clearTimeout(timeoutId);
|
|
308
|
+
}
|
|
309
|
+
if (options?.signal && handleExternalAbort) {
|
|
310
|
+
options.signal.removeEventListener("abort", handleExternalAbort);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
296
313
|
}
|
|
297
314
|
};
|
|
298
315
|
|
|
@@ -797,7 +814,7 @@ var RateLimitMiddleware = class {
|
|
|
797
814
|
* Create a new RateLimitMiddleware instance.
|
|
798
815
|
*
|
|
799
816
|
* @param config - Rate limit configuration for each channel
|
|
800
|
-
* @param store - Optional cache store for distributed rate limiting
|
|
817
|
+
* @param store - Optional cache store for distributed rate limiting (future use)
|
|
801
818
|
*
|
|
802
819
|
* @example
|
|
803
820
|
* ```typescript
|
|
@@ -814,7 +831,7 @@ var RateLimitMiddleware = class {
|
|
|
814
831
|
*/
|
|
815
832
|
constructor(config, store) {
|
|
816
833
|
this.config = config;
|
|
817
|
-
this.store = store
|
|
834
|
+
this.store = store || new MemoryStore();
|
|
818
835
|
this.initializeBuckets();
|
|
819
836
|
}
|
|
820
837
|
/**
|
|
@@ -832,7 +849,7 @@ var RateLimitMiddleware = class {
|
|
|
832
849
|
*/
|
|
833
850
|
buckets = /* @__PURE__ */ new Map();
|
|
834
851
|
/**
|
|
835
|
-
* Cache store for rate
|
|
852
|
+
* Cache store for distributed rate limiting.
|
|
836
853
|
*/
|
|
837
854
|
store;
|
|
838
855
|
/**
|
|
@@ -1852,6 +1869,7 @@ var OrbitFlare = class _OrbitFlare {
|
|
|
1852
1869
|
};
|
|
1853
1870
|
|
|
1854
1871
|
// src/templates/NotificationTemplate.ts
|
|
1872
|
+
var import_core = require("@gravito/core");
|
|
1855
1873
|
var TemplatedNotification = class extends Notification {
|
|
1856
1874
|
data = {};
|
|
1857
1875
|
with(data) {
|
|
@@ -1880,6 +1898,33 @@ var TemplatedNotification = class extends Notification {
|
|
|
1880
1898
|
attachments: template.attachments
|
|
1881
1899
|
};
|
|
1882
1900
|
}
|
|
1901
|
+
/**
|
|
1902
|
+
* 將 Markdown 模板渲染為 HTML。
|
|
1903
|
+
* 先執行變數插值(`{{var}}`),再將 Markdown 轉為 HTML。
|
|
1904
|
+
* 內建 XSS 防護:過濾 script、iframe、event handler 等危險 HTML。
|
|
1905
|
+
*
|
|
1906
|
+
* 適用於郵件、Slack 等富文本通知頻道。
|
|
1907
|
+
*
|
|
1908
|
+
* @param template - Markdown 格式的模板字串
|
|
1909
|
+
* @returns 安全的 HTML 字串
|
|
1910
|
+
*
|
|
1911
|
+
* @example
|
|
1912
|
+
* ```typescript
|
|
1913
|
+
* const html = this.renderMarkdown('# Hello {{name}}')
|
|
1914
|
+
* await sendEmail({ htmlBody: html })
|
|
1915
|
+
* ```
|
|
1916
|
+
*/
|
|
1917
|
+
renderMarkdown(template) {
|
|
1918
|
+
if (!template) {
|
|
1919
|
+
return "";
|
|
1920
|
+
}
|
|
1921
|
+
const interpolated = this.interpolate(template);
|
|
1922
|
+
const md = (0, import_core.getMarkdownAdapter)();
|
|
1923
|
+
const sanitizeCallbacks = (0, import_core.createHtmlRenderCallbacks)({
|
|
1924
|
+
html: (rawHtml) => sanitizeHtml(rawHtml)
|
|
1925
|
+
});
|
|
1926
|
+
return md.render(interpolated, sanitizeCallbacks);
|
|
1927
|
+
}
|
|
1883
1928
|
interpolate(text) {
|
|
1884
1929
|
return text.replace(/\{\{(\w+)\}\}/g, (_, key) => String(this.data[key] ?? `{{${key}}}`));
|
|
1885
1930
|
}
|
|
@@ -1890,6 +1935,17 @@ var TemplatedNotification = class extends Notification {
|
|
|
1890
1935
|
throw new Error("Notifiable does not have an email property");
|
|
1891
1936
|
}
|
|
1892
1937
|
};
|
|
1938
|
+
var DANGEROUS_TAGS = /^<\/?(?:script|iframe|object|embed|form|input|textarea|button|select|style|link|meta|base)\b[^>]*>$/i;
|
|
1939
|
+
var EVENT_HANDLER_ATTRS = /\s+on\w+\s*=/i;
|
|
1940
|
+
function sanitizeHtml(rawHtml) {
|
|
1941
|
+
if (DANGEROUS_TAGS.test(rawHtml.trim())) {
|
|
1942
|
+
return "";
|
|
1943
|
+
}
|
|
1944
|
+
if (EVENT_HANDLER_ATTRS.test(rawHtml)) {
|
|
1945
|
+
return "";
|
|
1946
|
+
}
|
|
1947
|
+
return rawHtml;
|
|
1948
|
+
}
|
|
1893
1949
|
|
|
1894
1950
|
// src/index.ts
|
|
1895
1951
|
init_middleware();
|
package/dist/index.d.cts
CHANGED
|
@@ -1038,14 +1038,14 @@ declare class RateLimitMiddleware implements ChannelMiddleware {
|
|
|
1038
1038
|
*/
|
|
1039
1039
|
private buckets;
|
|
1040
1040
|
/**
|
|
1041
|
-
* Cache store for rate
|
|
1041
|
+
* Cache store for distributed rate limiting.
|
|
1042
1042
|
*/
|
|
1043
|
-
|
|
1043
|
+
store: CacheStore;
|
|
1044
1044
|
/**
|
|
1045
1045
|
* Create a new RateLimitMiddleware instance.
|
|
1046
1046
|
*
|
|
1047
1047
|
* @param config - Rate limit configuration for each channel
|
|
1048
|
-
* @param store - Optional cache store for distributed rate limiting
|
|
1048
|
+
* @param store - Optional cache store for distributed rate limiting (future use)
|
|
1049
1049
|
*
|
|
1050
1050
|
* @example
|
|
1051
1051
|
* ```typescript
|
|
@@ -1378,7 +1378,24 @@ declare abstract class TemplatedNotification extends Notification {
|
|
|
1378
1378
|
protected slackTemplate?(): SlackTemplate;
|
|
1379
1379
|
toMail(notifiable: Notifiable): MailMessage;
|
|
1380
1380
|
toSlack(_notifiable: Notifiable): SlackMessage;
|
|
1381
|
-
|
|
1381
|
+
/**
|
|
1382
|
+
* 將 Markdown 模板渲染為 HTML。
|
|
1383
|
+
* 先執行變數插值(`{{var}}`),再將 Markdown 轉為 HTML。
|
|
1384
|
+
* 內建 XSS 防護:過濾 script、iframe、event handler 等危險 HTML。
|
|
1385
|
+
*
|
|
1386
|
+
* 適用於郵件、Slack 等富文本通知頻道。
|
|
1387
|
+
*
|
|
1388
|
+
* @param template - Markdown 格式的模板字串
|
|
1389
|
+
* @returns 安全的 HTML 字串
|
|
1390
|
+
*
|
|
1391
|
+
* @example
|
|
1392
|
+
* ```typescript
|
|
1393
|
+
* const html = this.renderMarkdown('# Hello {{name}}')
|
|
1394
|
+
* await sendEmail({ htmlBody: html })
|
|
1395
|
+
* ```
|
|
1396
|
+
*/
|
|
1397
|
+
protected renderMarkdown(template: string): string;
|
|
1398
|
+
protected interpolate(text: string): string;
|
|
1382
1399
|
private getRecipientEmail;
|
|
1383
1400
|
}
|
|
1384
1401
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1038,14 +1038,14 @@ declare class RateLimitMiddleware implements ChannelMiddleware {
|
|
|
1038
1038
|
*/
|
|
1039
1039
|
private buckets;
|
|
1040
1040
|
/**
|
|
1041
|
-
* Cache store for rate
|
|
1041
|
+
* Cache store for distributed rate limiting.
|
|
1042
1042
|
*/
|
|
1043
|
-
|
|
1043
|
+
store: CacheStore;
|
|
1044
1044
|
/**
|
|
1045
1045
|
* Create a new RateLimitMiddleware instance.
|
|
1046
1046
|
*
|
|
1047
1047
|
* @param config - Rate limit configuration for each channel
|
|
1048
|
-
* @param store - Optional cache store for distributed rate limiting
|
|
1048
|
+
* @param store - Optional cache store for distributed rate limiting (future use)
|
|
1049
1049
|
*
|
|
1050
1050
|
* @example
|
|
1051
1051
|
* ```typescript
|
|
@@ -1378,7 +1378,24 @@ declare abstract class TemplatedNotification extends Notification {
|
|
|
1378
1378
|
protected slackTemplate?(): SlackTemplate;
|
|
1379
1379
|
toMail(notifiable: Notifiable): MailMessage;
|
|
1380
1380
|
toSlack(_notifiable: Notifiable): SlackMessage;
|
|
1381
|
-
|
|
1381
|
+
/**
|
|
1382
|
+
* 將 Markdown 模板渲染為 HTML。
|
|
1383
|
+
* 先執行變數插值(`{{var}}`),再將 Markdown 轉為 HTML。
|
|
1384
|
+
* 內建 XSS 防護:過濾 script、iframe、event handler 等危險 HTML。
|
|
1385
|
+
*
|
|
1386
|
+
* 適用於郵件、Slack 等富文本通知頻道。
|
|
1387
|
+
*
|
|
1388
|
+
* @param template - Markdown 格式的模板字串
|
|
1389
|
+
* @returns 安全的 HTML 字串
|
|
1390
|
+
*
|
|
1391
|
+
* @example
|
|
1392
|
+
* ```typescript
|
|
1393
|
+
* const html = this.renderMarkdown('# Hello {{name}}')
|
|
1394
|
+
* await sendEmail({ htmlBody: html })
|
|
1395
|
+
* ```
|
|
1396
|
+
*/
|
|
1397
|
+
protected renderMarkdown(template: string): string;
|
|
1398
|
+
protected interpolate(text: string): string;
|
|
1382
1399
|
private getRecipientEmail;
|
|
1383
1400
|
}
|
|
1384
1401
|
|
package/dist/index.js
CHANGED
|
@@ -220,16 +220,23 @@ var TimeoutChannel = class {
|
|
|
220
220
|
}
|
|
221
221
|
const controller = new AbortController();
|
|
222
222
|
const { signal } = controller;
|
|
223
|
+
let timeoutId;
|
|
224
|
+
let settled = false;
|
|
225
|
+
let handleExternalAbort;
|
|
223
226
|
if (options?.signal) {
|
|
224
227
|
if (options.signal.aborted) {
|
|
225
228
|
throw new AbortError("Request was aborted before sending");
|
|
226
229
|
}
|
|
227
|
-
|
|
230
|
+
handleExternalAbort = () => {
|
|
228
231
|
controller.abort();
|
|
229
|
-
}
|
|
232
|
+
};
|
|
233
|
+
options.signal.addEventListener("abort", handleExternalAbort, { once: true });
|
|
230
234
|
}
|
|
231
235
|
const timeoutPromise = new Promise((_, reject) => {
|
|
232
|
-
setTimeout(() => {
|
|
236
|
+
timeoutId = setTimeout(() => {
|
|
237
|
+
if (settled) {
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
233
240
|
if (this.config.onTimeout) {
|
|
234
241
|
this.config.onTimeout(this.inner.constructor.name, notification);
|
|
235
242
|
}
|
|
@@ -250,7 +257,17 @@ var TimeoutChannel = class {
|
|
|
250
257
|
}
|
|
251
258
|
throw error;
|
|
252
259
|
});
|
|
253
|
-
|
|
260
|
+
try {
|
|
261
|
+
return await Promise.race([sendPromise, timeoutPromise]);
|
|
262
|
+
} finally {
|
|
263
|
+
settled = true;
|
|
264
|
+
if (timeoutId) {
|
|
265
|
+
clearTimeout(timeoutId);
|
|
266
|
+
}
|
|
267
|
+
if (options?.signal && handleExternalAbort) {
|
|
268
|
+
options.signal.removeEventListener("abort", handleExternalAbort);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
254
271
|
}
|
|
255
272
|
};
|
|
256
273
|
|
|
@@ -755,7 +772,7 @@ var RateLimitMiddleware = class {
|
|
|
755
772
|
* Create a new RateLimitMiddleware instance.
|
|
756
773
|
*
|
|
757
774
|
* @param config - Rate limit configuration for each channel
|
|
758
|
-
* @param store - Optional cache store for distributed rate limiting
|
|
775
|
+
* @param store - Optional cache store for distributed rate limiting (future use)
|
|
759
776
|
*
|
|
760
777
|
* @example
|
|
761
778
|
* ```typescript
|
|
@@ -772,7 +789,7 @@ var RateLimitMiddleware = class {
|
|
|
772
789
|
*/
|
|
773
790
|
constructor(config, store) {
|
|
774
791
|
this.config = config;
|
|
775
|
-
this.store = store
|
|
792
|
+
this.store = store || new MemoryStore();
|
|
776
793
|
this.initializeBuckets();
|
|
777
794
|
}
|
|
778
795
|
/**
|
|
@@ -790,7 +807,7 @@ var RateLimitMiddleware = class {
|
|
|
790
807
|
*/
|
|
791
808
|
buckets = /* @__PURE__ */ new Map();
|
|
792
809
|
/**
|
|
793
|
-
* Cache store for rate
|
|
810
|
+
* Cache store for distributed rate limiting.
|
|
794
811
|
*/
|
|
795
812
|
store;
|
|
796
813
|
/**
|
|
@@ -1810,6 +1827,7 @@ var OrbitFlare = class _OrbitFlare {
|
|
|
1810
1827
|
};
|
|
1811
1828
|
|
|
1812
1829
|
// src/templates/NotificationTemplate.ts
|
|
1830
|
+
import { createHtmlRenderCallbacks, getMarkdownAdapter } from "@gravito/core";
|
|
1813
1831
|
var TemplatedNotification = class extends Notification {
|
|
1814
1832
|
data = {};
|
|
1815
1833
|
with(data) {
|
|
@@ -1838,6 +1856,33 @@ var TemplatedNotification = class extends Notification {
|
|
|
1838
1856
|
attachments: template.attachments
|
|
1839
1857
|
};
|
|
1840
1858
|
}
|
|
1859
|
+
/**
|
|
1860
|
+
* 將 Markdown 模板渲染為 HTML。
|
|
1861
|
+
* 先執行變數插值(`{{var}}`),再將 Markdown 轉為 HTML。
|
|
1862
|
+
* 內建 XSS 防護:過濾 script、iframe、event handler 等危險 HTML。
|
|
1863
|
+
*
|
|
1864
|
+
* 適用於郵件、Slack 等富文本通知頻道。
|
|
1865
|
+
*
|
|
1866
|
+
* @param template - Markdown 格式的模板字串
|
|
1867
|
+
* @returns 安全的 HTML 字串
|
|
1868
|
+
*
|
|
1869
|
+
* @example
|
|
1870
|
+
* ```typescript
|
|
1871
|
+
* const html = this.renderMarkdown('# Hello {{name}}')
|
|
1872
|
+
* await sendEmail({ htmlBody: html })
|
|
1873
|
+
* ```
|
|
1874
|
+
*/
|
|
1875
|
+
renderMarkdown(template) {
|
|
1876
|
+
if (!template) {
|
|
1877
|
+
return "";
|
|
1878
|
+
}
|
|
1879
|
+
const interpolated = this.interpolate(template);
|
|
1880
|
+
const md = getMarkdownAdapter();
|
|
1881
|
+
const sanitizeCallbacks = createHtmlRenderCallbacks({
|
|
1882
|
+
html: (rawHtml) => sanitizeHtml(rawHtml)
|
|
1883
|
+
});
|
|
1884
|
+
return md.render(interpolated, sanitizeCallbacks);
|
|
1885
|
+
}
|
|
1841
1886
|
interpolate(text) {
|
|
1842
1887
|
return text.replace(/\{\{(\w+)\}\}/g, (_, key) => String(this.data[key] ?? `{{${key}}}`));
|
|
1843
1888
|
}
|
|
@@ -1848,6 +1893,17 @@ var TemplatedNotification = class extends Notification {
|
|
|
1848
1893
|
throw new Error("Notifiable does not have an email property");
|
|
1849
1894
|
}
|
|
1850
1895
|
};
|
|
1896
|
+
var DANGEROUS_TAGS = /^<\/?(?:script|iframe|object|embed|form|input|textarea|button|select|style|link|meta|base)\b[^>]*>$/i;
|
|
1897
|
+
var EVENT_HANDLER_ATTRS = /\s+on\w+\s*=/i;
|
|
1898
|
+
function sanitizeHtml(rawHtml) {
|
|
1899
|
+
if (DANGEROUS_TAGS.test(rawHtml.trim())) {
|
|
1900
|
+
return "";
|
|
1901
|
+
}
|
|
1902
|
+
if (EVENT_HANDLER_ATTRS.test(rawHtml)) {
|
|
1903
|
+
return "";
|
|
1904
|
+
}
|
|
1905
|
+
return rawHtml;
|
|
1906
|
+
}
|
|
1851
1907
|
|
|
1852
1908
|
// src/index.ts
|
|
1853
1909
|
init_middleware();
|
package/package.json
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gravito/flare",
|
|
3
|
-
"
|
|
3
|
+
"sideEffects": false,
|
|
4
|
+
"version": "4.0.2",
|
|
4
5
|
"publishConfig": {
|
|
5
6
|
"access": "public"
|
|
6
7
|
},
|
|
@@ -23,11 +24,12 @@
|
|
|
23
24
|
],
|
|
24
25
|
"scripts": {
|
|
25
26
|
"build": "bun run build.ts",
|
|
27
|
+
"build:dts": "bun run build.ts --dts-only",
|
|
26
28
|
"test": "bun test --timeout=10000",
|
|
27
29
|
"typecheck": "bun tsc -p tsconfig.json --noEmit --skipLibCheck",
|
|
28
30
|
"test:coverage": "bun test --timeout=10000 --coverage --coverage-reporter=lcov --coverage-dir coverage && bun run --bun scripts/check-coverage.ts",
|
|
29
31
|
"test:ci": "bun test --timeout=10000 --coverage --coverage-reporter=lcov --coverage-dir coverage && bun run --bun scripts/check-coverage.ts",
|
|
30
|
-
"test:unit": "bun test tests/ --timeout=10000",
|
|
32
|
+
"test:unit": "bun test $(find tests -name '*.test.ts' ! -name '*.integration.test.ts' 2>/dev/null | tr '\\n' ' ') --timeout=10000",
|
|
31
33
|
"test:integration": "test $(find tests -name '*.integration.test.ts' 2>/dev/null | wc -l) -gt 0 && find tests -name '*.integration.test.ts' -print0 | xargs -0 bun test --timeout=10000 || echo 'No integration tests found'"
|
|
32
34
|
},
|
|
33
35
|
"keywords": [
|
|
@@ -42,13 +44,13 @@
|
|
|
42
44
|
"author": "Carl Lee <carllee0520@gmail.com>",
|
|
43
45
|
"license": "MIT",
|
|
44
46
|
"dependencies": {
|
|
45
|
-
"@gravito/core": "
|
|
47
|
+
"@gravito/core": "^2.0.6",
|
|
46
48
|
"@aws-sdk/client-sns": "^3.734.0"
|
|
47
49
|
},
|
|
48
50
|
"peerDependencies": {
|
|
49
|
-
"@gravito/stream": "
|
|
50
|
-
"@gravito/signal": "
|
|
51
|
-
"@gravito/radiance": "
|
|
51
|
+
"@gravito/stream": "^2.1.0",
|
|
52
|
+
"@gravito/signal": "^3.1.0",
|
|
53
|
+
"@gravito/radiance": "^1.0.4"
|
|
52
54
|
},
|
|
53
55
|
"devDependencies": {
|
|
54
56
|
"bun-types": "latest",
|