@gravito/signal 3.0.3 → 3.1.0

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.
Files changed (131) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +99 -59
  3. package/README.zh-TW.md +140 -9
  4. package/build.ts +133 -0
  5. package/dist/Mailable.d.ts +453 -0
  6. package/dist/OrbitSignal.d.ts +267 -0
  7. package/dist/Queueable.d.ts +9 -0
  8. package/dist/TypedMailable.d.ts +95 -0
  9. package/dist/dev/DevMailbox.d.ts +79 -0
  10. package/dist/dev/DevServer.d.ts +39 -0
  11. package/dist/dev/storage/FileMailboxStorage.d.ts +16 -0
  12. package/dist/dev/storage/MailboxStorage.d.ts +14 -0
  13. package/dist/dev/storage/MemoryMailboxStorage.d.ts +13 -0
  14. package/dist/dev/ui/mailbox.d.ts +11 -0
  15. package/dist/dev/ui/preview.d.ts +11 -0
  16. package/dist/dev/ui/shared.d.ts +15 -0
  17. package/dist/errors.d.ts +58 -0
  18. package/dist/events.d.ts +63 -0
  19. package/dist/index.cjs +88291 -0
  20. package/dist/index.cjs.map +712 -0
  21. package/dist/index.d.ts +31 -643
  22. package/dist/index.mjs +87748 -335
  23. package/dist/index.mjs.map +710 -0
  24. package/dist/renderers/HtmlRenderer.d.ts +34 -0
  25. package/dist/renderers/MjmlRenderer.d.ts +41 -0
  26. package/dist/renderers/ReactMjmlRenderer.d.ts +38 -0
  27. package/dist/renderers/ReactRenderer.d.ts +46 -0
  28. package/dist/renderers/Renderer.d.ts +66 -0
  29. package/dist/renderers/TemplateRenderer.d.ts +55 -0
  30. package/dist/renderers/VueMjmlRenderer.d.ts +39 -0
  31. package/dist/renderers/VueRenderer.d.ts +47 -0
  32. package/dist/renderers/mjml-templates.d.ts +11 -0
  33. package/dist/transports/BaseTransport.d.ts +111 -0
  34. package/dist/transports/LogTransport.d.ts +42 -0
  35. package/dist/transports/MemoryTransport.d.ts +51 -0
  36. package/dist/transports/SesTransport.d.ts +79 -0
  37. package/dist/transports/SmtpTransport.d.ts +124 -0
  38. package/dist/transports/Transport.d.ts +44 -0
  39. package/dist/types.d.ts +294 -0
  40. package/dist/utils/html.d.ts +29 -0
  41. package/dist/webhooks/SendGridWebhookDriver.d.ts +45 -0
  42. package/dist/webhooks/SesWebhookDriver.d.ts +23 -0
  43. package/doc/ADVANCED_RENDERING.md +71 -0
  44. package/doc/DISTRIBUTED_MESSAGING.md +79 -0
  45. package/doc/OPTIMIZATION_PLAN.md +496 -0
  46. package/package.json +14 -11
  47. package/package.json.bak +75 -0
  48. package/scripts/check-coverage.ts +64 -0
  49. package/src/Mailable.ts +340 -44
  50. package/src/OrbitSignal.ts +350 -50
  51. package/src/TypedMailable.ts +96 -0
  52. package/src/dev/DevMailbox.ts +89 -33
  53. package/src/dev/DevServer.ts +14 -14
  54. package/src/dev/storage/FileMailboxStorage.ts +66 -0
  55. package/src/dev/storage/MailboxStorage.ts +15 -0
  56. package/src/dev/storage/MemoryMailboxStorage.ts +36 -0
  57. package/src/dev/ui/mailbox.ts +1 -1
  58. package/src/dev/ui/preview.ts +4 -4
  59. package/src/errors.ts +69 -0
  60. package/src/events.ts +72 -0
  61. package/src/index.ts +20 -1
  62. package/src/renderers/HtmlRenderer.ts +20 -18
  63. package/src/renderers/MjmlRenderer.ts +73 -0
  64. package/src/renderers/ReactMjmlRenderer.ts +94 -0
  65. package/src/renderers/ReactRenderer.ts +26 -21
  66. package/src/renderers/Renderer.ts +43 -3
  67. package/src/renderers/TemplateRenderer.ts +48 -15
  68. package/src/renderers/VueMjmlRenderer.ts +99 -0
  69. package/src/renderers/VueRenderer.ts +26 -21
  70. package/src/renderers/mjml-templates.ts +50 -0
  71. package/src/transports/BaseTransport.ts +148 -0
  72. package/src/transports/LogTransport.ts +28 -6
  73. package/src/transports/MemoryTransport.ts +34 -6
  74. package/src/transports/SesTransport.ts +62 -17
  75. package/src/transports/SmtpTransport.ts +123 -27
  76. package/src/transports/Transport.ts +33 -4
  77. package/src/types.ts +172 -3
  78. package/src/utils/html.ts +43 -0
  79. package/src/webhooks/SendGridWebhookDriver.ts +80 -0
  80. package/src/webhooks/SesWebhookDriver.ts +44 -0
  81. package/tests/DevMailbox.test.ts +54 -0
  82. package/tests/FileMailboxStorage.test.ts +56 -0
  83. package/tests/MjmlLayout.test.ts +28 -0
  84. package/tests/MjmlRenderer.test.ts +53 -0
  85. package/tests/OrbitSignalWebhook.test.ts +56 -0
  86. package/tests/ReactMjmlRenderer.test.ts +33 -0
  87. package/tests/SendGridWebhookDriver.test.ts +69 -0
  88. package/tests/SesWebhookDriver.test.ts +46 -0
  89. package/tests/VueMjmlRenderer.test.ts +35 -0
  90. package/tests/dev-server.test.ts +1 -1
  91. package/tests/transports.test.ts +3 -3
  92. package/tsconfig.build.json +24 -0
  93. package/tsconfig.json +8 -25
  94. package/dist/OrbitMail-2Z7ZTKYA.mjs +0 -7
  95. package/dist/OrbitMail-BGV32HWN.mjs +0 -7
  96. package/dist/OrbitMail-FUYZQSAV.mjs +0 -7
  97. package/dist/OrbitMail-NAPCRK7B.mjs +0 -7
  98. package/dist/OrbitMail-REGJ276B.mjs +0 -7
  99. package/dist/OrbitMail-TCFBJWDT.mjs +0 -7
  100. package/dist/OrbitMail-XZZW6U4N.mjs +0 -7
  101. package/dist/OrbitSignal-IPSA2CDO.mjs +0 -7
  102. package/dist/OrbitSignal-MABW4DDW.mjs +0 -7
  103. package/dist/OrbitSignal-QSW5VQ5M.mjs +0 -7
  104. package/dist/OrbitSignal-R22QHWAA.mjs +0 -7
  105. package/dist/OrbitSignal-ZKKMEC27.mjs +0 -7
  106. package/dist/ReactRenderer-24SQ4KRU.mjs +0 -27
  107. package/dist/ReactRenderer-CMCAOEPH.mjs +0 -28
  108. package/dist/ReactRenderer-KYNA4WKE.mjs +0 -28
  109. package/dist/ReactRenderer-L5INVYKT.mjs +0 -27
  110. package/dist/VueRenderer-DWTCD2RF.mjs +0 -31
  111. package/dist/VueRenderer-IIR5SYTM.mjs +0 -31
  112. package/dist/VueRenderer-S65ZARRI.mjs +0 -37129
  113. package/dist/VueRenderer-SUP66ISX.mjs +0 -29
  114. package/dist/VueRenderer-Z5PRVBNH.mjs +0 -37298
  115. package/dist/chunk-3U2CYJO5.mjs +0 -367
  116. package/dist/chunk-3XFC4T6M.mjs +0 -392
  117. package/dist/chunk-456QRYFW.mjs +0 -401
  118. package/dist/chunk-6DZX6EAA.mjs +0 -37
  119. package/dist/chunk-DT3R2TNV.mjs +0 -367
  120. package/dist/chunk-EBO3CZXG.mjs +0 -15
  121. package/dist/chunk-F6MVTUCT.mjs +0 -421
  122. package/dist/chunk-GADWIVC4.mjs +0 -400
  123. package/dist/chunk-HHKFAMSE.mjs +0 -380
  124. package/dist/chunk-NEQCQSZI.mjs +0 -406
  125. package/dist/chunk-OKRNL6PN.mjs +0 -400
  126. package/dist/chunk-ULN3GMY2.mjs +0 -367
  127. package/dist/chunk-XAWO7RSP.mjs +0 -398
  128. package/dist/chunk-YLVDJSED.mjs +0 -431
  129. package/dist/index.d.mts +0 -644
  130. package/dist/index.js +0 -38251
  131. package/dist/server-renderer-4W4FI7YG.mjs +0 -37269
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # @gravito/signal
2
2
 
3
+ ## 3.0.4
4
+
5
+ ### Patch Changes
6
+
7
+ - Convert all workspace:\* dependencies to version numbers for npm publishing
8
+
9
+ - Fixed 144 workspace:\* dependencies across 58 packages
10
+ - Ensures all packages work properly when installed from npm
11
+ - Resolves issues with bunx and npm installation of CLI tools
12
+ - All internal dependencies now use explicit version constraints
13
+
14
+ - Updated dependencies
15
+ - @gravito/core@1.6.1
16
+ - @gravito/prism@3.1.1
17
+ - @gravito/stream@2.0.2
18
+
3
19
  ## 3.0.3
4
20
 
5
21
  ### Patch Changes
package/README.md CHANGED
@@ -1,42 +1,69 @@
1
+ # @gravito/signal 🛰️
1
2
 
2
- # Orbit Mail
3
+ `@gravito/signal` is the powerful, multi-driver email framework for the Gravito ecosystem. It provides a clean, fluent API for building and sending emails with support for multiple rendering engines and transport drivers.
3
4
 
4
- A powerful, multi-driver email framework for Gravito applications. Supports HTML, Template, React, and Vue renderers, with built-in development tools.
5
+ ## Features
5
6
 
6
- ## Features
7
+ - 🚀 **Fluent API**: Expressive `Mailable` classes for building complex email messages with zero friction.
8
+ - 🌌 **Galaxy-Ready**: A native Gravito Orbit that integrates seamlessly into the IoC container and context.
9
+ - 🔌 **Multi-Driver Transport**: Support for SMTP, AWS SES, SendGrid, Log, and Memory drivers.
10
+ - 🎨 **Modern Rendering**: Design emails using **React**, **Vue**, **MJML**, or **Prism** templates.
11
+ - 📬 **Dev Mailbox UI**: Built-in visual interface at `/__mail` for local email inspection and debugging.
12
+ - ⚙️ **Distributed Queueing**: Automatic offloading to `@gravito/stream` for background delivery.
13
+ - 🛡️ **Webhook Processing**: Handle inbound delivery events (bounces, clicks) with ease.
7
14
 
8
- - **Multi-Driver Transport**: SMTP, AWS SES, Log, Memory.
9
- - **Content Renderers**:
10
- - Raw HTML
11
- - OrbitPrism Templates
12
- - React Components (lazy-loaded)
13
- - Vue Components (lazy-loaded)
14
- - **Development Mode**: Intercept emails and view them in a built-in UI (`/__mail`).
15
- - **Flexible API**: Fluent interface for building emails.
16
- - **Queue Support**: Built-in `Queueable` interface for async sending.
15
+ ## 🌌 Role in Galaxy Architecture
17
16
 
18
- ## Installation
17
+ In the **Gravito Galaxy Architecture**, Signal serves as the **Communication Nervous System**.
18
+
19
+ - **Outbound Signal**: Satellites (domain plugins) trigger `Signal` to communicate with the outside world (users, other systems).
20
+ - **Inbound Feedback**: Signal processes Webhooks from providers to update the state of the Galaxy (e.g., marking an email as invalid in the `Membership` Satellite).
21
+ - **Event-Driven**: Leverages `@gravito/core`'s lifecycle to ensure emails are sent only after transactions are committed.
22
+
23
+ ```mermaid
24
+ graph LR
25
+ S[Satellite] -->|Trigger| Signal[Signal Orbit]
26
+ Signal -->|Render| MW[MJML/React/Vue]
27
+ MW -->|Send| Provider[SES/SMTP]
28
+ Provider -.->|Webhook| Signal
29
+ Signal -.->|Event| S
30
+ ```
31
+
32
+ ## 📦 Installation
19
33
 
20
34
  ```bash
21
35
  bun add @gravito/signal
22
36
  ```
23
37
 
24
- For AWS SES support:
38
+ ### Optional Dependencies
39
+
40
+ Depending on your transport or renderer choice, you may need additional packages:
41
+
25
42
  ```bash
43
+ # For AWS SES
26
44
  bun add @aws-sdk/client-ses
45
+
46
+ # For React components
47
+ bun add react react-dom
48
+
49
+ # For Vue components
50
+ bun add vue @vue/server-renderer
27
51
  ```
28
52
 
29
- ## Basic Usage
53
+ ## 🚀 Quick Start
30
54
 
31
- ### Configuration
55
+ ### 1. Configure the Orbit
32
56
 
33
- Configure OrbitSignal in your generic startup or creation logic:
57
+ Register `OrbitSignal` in your Gravito application:
34
58
 
35
59
  ```typescript
60
+ import { PlanetCore } from '@gravito/core';
36
61
  import { OrbitSignal, SmtpTransport } from '@gravito/signal';
37
62
 
38
- const mail = OrbitSignal.configure({
39
- from: { name: 'My App', address: 'noreply@myapp.com' },
63
+ const core = new PlanetCore();
64
+
65
+ const mail = new OrbitSignal({
66
+ from: { name: 'Gravito Support', address: 'support@example.com' },
40
67
  transport: new SmtpTransport({
41
68
  host: 'smtp.mailtrap.io',
42
69
  port: 2525,
@@ -45,19 +72,18 @@ const mail = OrbitSignal.configure({
45
72
  devMode: process.env.NODE_ENV === 'development',
46
73
  });
47
74
 
48
- // Install into PlanetCore
49
75
  mail.install(core);
50
76
  ```
51
77
 
52
- ### Creating Mailables
78
+ ### 2. Create a Mailable
53
79
 
54
- Extend the `Mailable` class to create email definitions.
80
+ Extend the `Mailable` class to define your email:
55
81
 
56
82
  ```typescript
57
83
  import { Mailable } from '@gravito/signal';
58
84
 
59
85
  export class WelcomeEmail extends Mailable {
60
- constructor(private user: User) {
86
+ constructor(private user: { name: string; email: string }) {
61
87
  super();
62
88
  }
63
89
 
@@ -70,60 +96,74 @@ export class WelcomeEmail extends Mailable {
70
96
  }
71
97
  ```
72
98
 
73
- ### Sending Email
99
+ ### 3. Send the Email
74
100
 
75
- ```typescript
76
- import { WelcomeEmail } from './mail/WelcomeEmail';
101
+ Access the mail service via the Gravito context:
77
102
 
78
- // In a controller/handler
79
- await new WelcomeEmail(user).renderContent(); // Validate content
80
- await context.get('mail').send(new WelcomeEmail(user));
103
+ ```typescript
104
+ // In your route handler
105
+ const mail = c.get('mail');
106
+ await mail.send(new WelcomeEmail(user));
81
107
  ```
82
108
 
83
- ### Queueing Email
109
+ ## 🛠️ Advanced Usage
84
110
 
85
- OrbitSignal supports queuing mail for background processing.
111
+ ### React & Vue Rendering
112
+
113
+ You can use modern frontend frameworks to design your emails:
86
114
 
87
115
  ```typescript
88
- const email = new WelcomeEmail(user)
89
- .onQueue('high-priority')
90
- .delay(60);
116
+ // React example
117
+ export class MonthlyReport extends Mailable {
118
+ build() {
119
+ return this
120
+ .subject('Your Monthly Report')
121
+ .react(ReportComponent, { data: this.data });
122
+ }
123
+ }
91
124
 
92
- // Queue the email
93
- await email.queue();
125
+ // Vue example
126
+ export class InvoiceEmail extends Mailable {
127
+ build() {
128
+ return this
129
+ .subject('Invoice #12345')
130
+ .vue(InvoiceTemplate, { total: 100 });
131
+ }
132
+ }
94
133
  ```
95
134
 
96
- ## Transports
97
-
98
- ### SMTP
99
- Standard SMTP transport using `nodemailer`.
135
+ ### Queueing Emails
100
136
 
101
- ### AWS SES
102
- Send via Amazon SES API.
137
+ For better performance, send emails asynchronously:
103
138
 
104
139
  ```typescript
105
- import { SesTransport } from '@gravito/signal';
140
+ const email = new WelcomeEmail(user)
141
+ .onQueue('notifications')
142
+ .delay(60); // Send after 60 seconds
106
143
 
107
- const transport = new SesTransport({
108
- region: 'us-east-1',
109
- accessKeyId: '...', // Optional if using environment variables
110
- secretAccessKey: '...'
111
- });
144
+ await email.queue();
112
145
  ```
113
146
 
114
- ### Log
115
- Logs email content to the console (useful for debugging).
147
+ ### Development Mailbox
148
+
149
+ When `devMode` is enabled, `OrbitSignal` intercepts all outgoing emails and stores them in memory. You can view them by navigating to `/__mail` (or your configured `devUiPrefix`) in your browser. This UI provides:
150
+ - A list of all intercepted emails.
151
+ - Preview of HTML and Plain Text content.
152
+ - Metadata view (Subject, To, From, etc.).
116
153
 
117
- ### Memory
118
- Stores emails in memory (used by Dev Mode).
154
+ ## 🔧 Configuration Options
119
155
 
120
- ## Renderers
156
+ The `MailConfig` object supports the following options:
121
157
 
122
- - **html(string)**: Raw HTML string.
123
- - **view(template, data)**: Uses generic template engine.
124
- - **react(Component, props)**: Renders a React component to HTML.
125
- - **vue(Component, props)**: Renders a Vue component to HTML.
158
+ | Option | Type | Description |
159
+ |---|---|---|
160
+ | `from` | `Address` | Default sender address. |
161
+ | `transport` | `Transport` | The transport driver to use. |
162
+ | `devMode` | `boolean` | Enable/disable email interception. |
163
+ | `viewsDir` | `string` | Path to template directory. |
164
+ | `devUiPrefix`| `string` | URL prefix for Dev UI (default: `/__mail`). |
165
+ | `translator` | `Function` | I18n translation function. |
126
166
 
127
- ## License
167
+ ## 📄 License
128
168
 
129
- MIT
169
+ MIT © Carl Lee
package/README.zh-TW.md CHANGED
@@ -1,27 +1,158 @@
1
- # Orbit Mail
1
+ # @gravito/signal 🛰️
2
2
 
3
- > Gravito 的郵件模組,支援多種傳輸與 HTML/模板/React/Vue 渲染。
3
+ `@gravito/signal` Gravito 生態系統中功能強大且支援多種驅動程式的電子郵件框架。它提供了一個簡潔、流暢的 API 來構建和發送電子郵件,並支援多種渲染引擎和傳輸驅動程式。
4
4
 
5
- ## 安裝
5
+ ## 🌟 特性
6
+
7
+ - **流暢的 API**:使用具表現力的 `Mailable` 類別來構建電子郵件內容。
8
+ - **多驅動傳輸**:支援 SMTP (Nodemailer)、AWS SES、Log (控制台日誌) 和 Memory (記憶體)。
9
+ - **靈活的渲染引擎**:支援使用以下方式渲染郵件內容:
10
+ - 原生 HTML 字串
11
+ - **Prism** (Edge 優化的模板引擎)
12
+ - **React** 組件 (透過 `react-dom/server`)
13
+ - **Vue** 組件 (透過 `@vue/server-renderer`)
14
+ - **開發體驗優化**:
15
+ - **開發模式 (Dev Mode)**:在本地開發時攔截電子郵件,而不實際發送。
16
+ - **信箱 UI (Mailbox UI)**:在開發期間透過 `/__mail` 存取攔截到的郵件預覽界面。
17
+ - **隊列整合**:內建支援透過 `@gravito/stream` 進行異步郵件發送。
18
+ - **國際化 (I18n)**:整合多語系支援,輕鬆發送在地化郵件。
19
+ - **類型安全**:完全使用 TypeScript 編寫,提供完善的配置與使用類型定義。
20
+
21
+ ## 📦 安裝
6
22
 
7
23
  ```bash
8
24
  bun add @gravito/signal
9
25
  ```
10
26
 
11
- ## 快速開始
27
+ ### 選用依賴
28
+
29
+ 根據您選擇的傳輸方式或渲染引擎,您可能需要安裝額外的套件:
30
+
31
+ ```bash
32
+ # 若使用 AWS SES
33
+ bun add @aws-sdk/client-ses
34
+
35
+ # 若使用 React 組件
36
+ bun add react react-dom
37
+
38
+ # 若使用 Vue 組件
39
+ bun add vue @vue/server-renderer
40
+ ```
41
+
42
+ ## 🚀 快速上手
43
+
44
+ ### 1. 配置 Orbit
45
+
46
+ 在您的 Gravito 應用程式中註冊 `OrbitSignal`:
12
47
 
13
48
  ```typescript
14
- import { OrbitSignal, SmtpTransport } from '@gravito/signal'
49
+ import { PlanetCore } from '@gravito/core';
50
+ import { OrbitSignal, SmtpTransport } from '@gravito/signal';
15
51
 
16
- const mail = OrbitSignal.configure({
17
- from: { name: 'My App', address: 'noreply@myapp.com' },
52
+ const core = new PlanetCore();
53
+
54
+ const mail = new OrbitSignal({
55
+ from: { name: 'Gravito 支援團隊', address: 'support@example.com' },
18
56
  transport: new SmtpTransport({
19
57
  host: 'smtp.mailtrap.io',
20
58
  port: 2525,
21
59
  auth: { user: '...', pass: '...' }
22
60
  }),
23
61
  devMode: process.env.NODE_ENV === 'development',
24
- })
62
+ });
63
+
64
+ mail.install(core);
65
+ ```
66
+
67
+ ### 2. 建立 Mailable
68
+
69
+ 繼承 `Mailable` 類別來定義您的郵件內容:
70
+
71
+ ```typescript
72
+ import { Mailable } from '@gravito/signal';
73
+
74
+ export class WelcomeEmail extends Mailable {
75
+ constructor(private user: { name: string; email: string }) {
76
+ super();
77
+ }
78
+
79
+ build() {
80
+ return this
81
+ .to(this.user.email)
82
+ .subject('歡迎來到 Gravito!')
83
+ .view('emails/welcome', { name: this.user.name });
84
+ }
85
+ }
86
+ ```
87
+
88
+ ### 3. 發送郵件
25
89
 
26
- mail.install(core)
90
+ 透過 Gravito Context 存取郵件服務:
91
+
92
+ ```typescript
93
+ // 在路由處理器中
94
+ const mail = c.get('mail');
95
+ await mail.send(new WelcomeEmail(user));
96
+ ```
97
+
98
+ ## 🛠️ 進階用法
99
+
100
+ ### 使用 React 或 Vue 渲染
101
+
102
+ 您可以使用現代前端框架來設計您的郵件:
103
+
104
+ ```typescript
105
+ // React 範例
106
+ export class MonthlyReport extends Mailable {
107
+ build() {
108
+ return this
109
+ .subject('您的每月報表')
110
+ .react(ReportComponent, { data: this.data });
111
+ }
112
+ }
113
+
114
+ // Vue 範例
115
+ export class InvoiceEmail extends Mailable {
116
+ build() {
117
+ return this
118
+ .subject('發票單號 #12345')
119
+ .vue(InvoiceTemplate, { total: 100 });
120
+ }
121
+ }
122
+ ```
123
+
124
+ ### 隊列發送 (Queueing)
125
+
126
+ 為了提升應用程式效能,建議使用異步隊列發送郵件:
127
+
128
+ ```typescript
129
+ const email = new WelcomeEmail(user)
130
+ .onQueue('notifications')
131
+ .delay(60); // 60 秒後發送
132
+
133
+ await email.queue();
27
134
  ```
135
+
136
+ ### 開發者信箱 (Dev Mailbox)
137
+
138
+ 當啟用 `devMode` 時,`OrbitSignal` 會攔截所有外發郵件並將其存儲在記憶體中。您可以透過瀏覽器訪問 `/__mail` (或您配置的 `devUiPrefix`) 來查看。此界面提供:
139
+ - 所有已攔截郵件的列表。
140
+ - HTML 與純文字內容預覽。
141
+ - 中繼資料查看 (主旨、收件者、寄件者等)。
142
+
143
+ ## 🔧 配置選項
144
+
145
+ `MailConfig` 物件支援以下選項:
146
+
147
+ | 選項 | 類型 | 描述 |
148
+ |---|---|---|
149
+ | `from` | `Address` | 預設寄件者地址。 |
150
+ | `transport` | `Transport` | 使用的傳輸驅動程式。 |
151
+ | `devMode` | `boolean` | 是否啟用郵件攔截開發模式。 |
152
+ | `viewsDir` | `string` | 模板檔案存放目錄。 |
153
+ | `devUiPrefix`| `string` | 開發界面 URL 前綴 (預設: `/__mail`)。 |
154
+ | `translator` | `Function` | I18n 翻譯函數。 |
155
+
156
+ ## 📄 授權
157
+
158
+ MIT © Carl Lee
package/build.ts ADDED
@@ -0,0 +1,133 @@
1
+ import { cp, type Dirent, mkdir, readdir, rm } from 'node:fs/promises'
2
+ import { basename } from 'node:path'
3
+ import { build } from 'bun'
4
+
5
+ const isDtsOnly = process.argv.includes('--dts-only')
6
+ const pkgName = basename(import.meta.dirname) // "signal"
7
+
8
+ console.log(
9
+ isDtsOnly ? 'Building @gravito/signal DTS...' : 'Building @gravito/signal in parallel...'
10
+ )
11
+
12
+ // Clean dist
13
+ await rm('dist', { recursive: true, force: true })
14
+
15
+ // External dependencies(peer deps + framework 包)
16
+ const externalDeps = [
17
+ '@gravito/core',
18
+ '@gravito/stream',
19
+ '@gravito/prism',
20
+ 'react',
21
+ 'react-dom',
22
+ 'vue',
23
+ '@vue/server-renderer',
24
+ 'nodemailer',
25
+ '@aws-sdk/client-ses',
26
+ ]
27
+
28
+ async function buildInParallel() {
29
+ const tasks: Promise<number>[] = []
30
+ const tempDir = isDtsOnly ? 'dist' : '.tsc-temp'
31
+
32
+ if (!isDtsOnly) {
33
+ await rm(tempDir, { recursive: true, force: true })
34
+
35
+ // Task 1: bun build ESM
36
+ const esmPromise = (async () => {
37
+ const buildResult = await build({
38
+ entrypoints: ['src/index.ts'],
39
+ outdir: 'dist',
40
+ format: 'esm',
41
+ target: 'node',
42
+ splitting: false,
43
+ sourcemap: 'external',
44
+ external: externalDeps,
45
+ naming: '[dir]/[name].mjs',
46
+ })
47
+
48
+ if (!buildResult.success) {
49
+ console.error('❌ ESM build failed:', buildResult.logs)
50
+ return 1
51
+ }
52
+ return 0
53
+ })()
54
+ tasks.push(esmPromise)
55
+
56
+ // Task 2: bun build CJS
57
+ const cjsPromise = (async () => {
58
+ const cjsResult = await build({
59
+ entrypoints: ['src/index.ts'],
60
+ outdir: 'dist',
61
+ format: 'cjs',
62
+ target: 'node',
63
+ splitting: false,
64
+ sourcemap: 'external',
65
+ naming: '[dir]/[name].cjs',
66
+ external: externalDeps,
67
+ })
68
+
69
+ if (!cjsResult.success) {
70
+ console.error('❌ CJS build failed:', cjsResult.logs)
71
+ return 1
72
+ }
73
+ return 0
74
+ })()
75
+ tasks.push(cjsPromise)
76
+ }
77
+
78
+ // Task 3: tsc 生成型別宣告(使用 tsconfig.build.json + noCheck)
79
+ const tscPromise = (async () => {
80
+ const tsc = Bun.spawn(['bunx', 'tsc', '-p', 'tsconfig.build.json', '--outDir', tempDir], {
81
+ stdout: 'inherit',
82
+ stderr: 'inherit',
83
+ cwd: import.meta.dirname,
84
+ })
85
+ return await tsc.exited
86
+ })()
87
+ tasks.push(tscPromise)
88
+
89
+ const results = await Promise.all(tasks)
90
+ for (const result of results) {
91
+ if (result !== 0) {
92
+ process.exit(1)
93
+ }
94
+ }
95
+ }
96
+
97
+ // 遞迴複製 .d.ts 檔案
98
+ async function copyDtsFiles(src: string, dest: string) {
99
+ let entries: Dirent[]
100
+ try {
101
+ entries = await readdir(src, { withFileTypes: true })
102
+ } catch (_e) {
103
+ return
104
+ }
105
+
106
+ for (const entry of entries) {
107
+ const srcPath = `${src}/${entry.name}`
108
+ const destPath = `${dest}/${entry.name}`
109
+
110
+ if (entry.isDirectory()) {
111
+ await mkdir(destPath, { recursive: true }).catch(() => {})
112
+ await copyDtsFiles(srcPath, destPath)
113
+ } else if (entry.isFile() && entry.name.endsWith('.d.ts')) {
114
+ await cp(srcPath, destPath)
115
+ }
116
+ }
117
+ }
118
+
119
+ await buildInParallel()
120
+
121
+ // 後處理:tsc 輸出到 .tsc-temp/{pkgName}/src/,需要移到 dist/
122
+ const tempDir = isDtsOnly ? 'dist' : '.tsc-temp'
123
+ if (!isDtsOnly) {
124
+ try {
125
+ const dtsSourceDir = `${tempDir}/${pkgName}/src`
126
+ await copyDtsFiles(dtsSourceDir, 'dist')
127
+ await rm(tempDir, { recursive: true, force: true })
128
+ } catch (e) {
129
+ console.warn('⚠️ Warning: Failed to copy type declarations:', e)
130
+ }
131
+ }
132
+
133
+ console.log('✅ @gravito/signal build completed')