@ossy/email 1.2.1 → 1.3.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 (3) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +209 -0
  3. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # 1.3.0 (2026-05-30)
7
+
8
+
9
+ ### Features
10
+
11
+ * **dependencies:** update Playwright to version 1.60.0 and enhance build task externalization ([b7787b7](https://github.com/ossy-se/ossy/commit/b7787b7c29e0f5edee85ab998db2f841097e4f88))
12
+
13
+
14
+
15
+
16
+
6
17
  ## 1.2.1 (2026-05-30)
7
18
 
8
19
  **Note:** Version bump only for package @ossy/email
package/README.md ADDED
@@ -0,0 +1,209 @@
1
+ # @ossy/email
2
+
3
+ React email rendering and AWS SES integration for the Ossy platform. Provides layout components, a server-side renderer, and the `email.integration.js` that the platform connects at startup.
4
+
5
+ ## Packages at a glance
6
+
7
+ | Export | Purpose |
8
+ |---|---|
9
+ | `EmailLayout` | Responsive email shell (600 px centered table layout) |
10
+ | `EmailButton` | Themed call-to-action button |
11
+ | `EmailText` | Body paragraph with sensible defaults |
12
+ | `EmailRenderer` | Renders a React component to `{ html, text }` |
13
+ | `emailIntegration` / `connect` | AWS SES integration factory |
14
+
15
+ ---
16
+
17
+ ## `*.email.jsx` — Transactional email template primitive
18
+
19
+ An email template is a React component discovered and bundled by `@ossy/app build`. You do not register it manually — the platform picks it up by filename.
20
+
21
+ **File naming:** `<name>.email.jsx` or `<name>.email.tsx`. Place it anywhere inside `src/`.
22
+
23
+ **Required exports:**
24
+
25
+ | Export | Type | Description |
26
+ |---|---|---|
27
+ | `id` | `string` | Unique template id, e.g. `'authentication/verify-sign-in'`. |
28
+ | `default` | `React.ComponentType` | The email component. |
29
+
30
+ **Optional exports:**
31
+
32
+ | Export | Type | Description |
33
+ |---|---|---|
34
+ | `subject` | `string` | Default subject line. |
35
+
36
+ **Minimal example:**
37
+
38
+ ```jsx
39
+ // src/auth/verify-sign-in.email.jsx
40
+ import { EmailLayout, EmailButton, EmailText } from '@ossy/email'
41
+
42
+ export const id = 'auth/verify-sign-in'
43
+ export const subject = 'Sign in'
44
+
45
+ export default function VerifySignInEmail({ token, baseUrl = 'https://app.example.com', theme }) {
46
+ const url = `${baseUrl}/verify?token=${token}`
47
+ return (
48
+ <EmailLayout theme={theme}>
49
+ <h1 style={{ color: '#111111', margin: '0 0 16px' }}>Sign in</h1>
50
+ <EmailText>Click the button below to sign in.</EmailText>
51
+ <EmailButton href={url} theme={theme}>Sign in</EmailButton>
52
+ </EmailLayout>
53
+ )
54
+ }
55
+ ```
56
+
57
+ See [PRIMITIVES.md](../platform/PRIMITIVES.md#email) for the full primitive specification.
58
+
59
+ ---
60
+
61
+ ## Components
62
+
63
+ ### `EmailLayout`
64
+
65
+ A responsive 600 px centered table layout. Wraps the email body.
66
+
67
+ ```jsx
68
+ import { EmailLayout } from '@ossy/email'
69
+
70
+ <EmailLayout theme={theme}>
71
+ {/* email content */}
72
+ </EmailLayout>
73
+ ```
74
+
75
+ **Props:**
76
+
77
+ | Prop | Type | Default | Description |
78
+ |---|---|---|---|
79
+ | `children` | `ReactNode` | — | Email body content. |
80
+ | `theme` | `{ primaryColor?, backgroundColor?, fontFamily? }` | `{}` | Colour/font overrides. |
81
+
82
+ **Theme defaults:**
83
+
84
+ | Key | Default |
85
+ |---|---|
86
+ | `primaryColor` | `'#111111'` |
87
+ | `backgroundColor` | `'#f5f5f5'` |
88
+ | `fontFamily` | `'sans-serif'` |
89
+
90
+ ### `EmailButton`
91
+
92
+ A styled call-to-action link rendered as an `<a>` tag (for maximum email client compatibility).
93
+
94
+ ```jsx
95
+ import { EmailButton } from '@ossy/email'
96
+
97
+ <EmailButton href="https://example.com/action" theme={theme}>
98
+ Click me
99
+ </EmailButton>
100
+ ```
101
+
102
+ **Props:**
103
+
104
+ | Prop | Type | Description |
105
+ |---|---|---|
106
+ | `href` | `string` | Link destination. |
107
+ | `children` | `ReactNode` | Button label. |
108
+ | `theme` | `object` | Same shape as `EmailLayout` theme. |
109
+
110
+ ### `EmailText`
111
+
112
+ A body paragraph with sensible line-height and colour defaults.
113
+
114
+ ```jsx
115
+ import { EmailText } from '@ossy/email'
116
+
117
+ <EmailText>You have requested to sign in.</EmailText>
118
+ ```
119
+
120
+ **Props:**
121
+
122
+ | Prop | Type | Description |
123
+ |---|---|---|
124
+ | `children` | `ReactNode` | Paragraph content. |
125
+ | `style` | `CSSProperties` | Additional inline styles (merged with defaults). |
126
+
127
+ ---
128
+
129
+ ## `EmailRenderer`
130
+
131
+ Server-side renderer. Converts a React email component to HTML and a plain-text fallback.
132
+
133
+ ```js
134
+ import { EmailRenderer } from '@ossy/email'
135
+
136
+ const { html, text } = EmailRenderer.render(VerifySignInEmail, { token: 'abc', baseUrl: 'https://app.example.com' })
137
+ ```
138
+
139
+ `render(Component, props)` calls `renderToStaticMarkup` (from `react-dom/server`) and strips HTML tags for the plain-text output. Both strings are suitable for passing directly to the AWS SES `SendEmailCommand`.
140
+
141
+ ---
142
+
143
+ ## `email.integration.js` — AWS SES integration
144
+
145
+ The `email` integration is an `*.integration.js` primitive that the platform connects at startup. It provides two methods: `send` (raw) and `sendTemplate` (React component).
146
+
147
+ **Required environment variables:**
148
+
149
+ | Variable | Description |
150
+ |---|---|
151
+ | `SES_REGION` | AWS region for SES (e.g. `eu-west-1`) |
152
+ | `AWS_ACCESS_KEY_ID` | AWS access key |
153
+ | `AWS_SECRET_ACCESS_KEY` | AWS secret key |
154
+
155
+ If any variable is missing the integration is skipped with a warning, and `integrations.get('email')` returns `null`.
156
+
157
+ **Using the email client in a task:**
158
+
159
+ ```js
160
+ // src/send-invite.task.js
161
+ import WorkspaceInvitationEmail from './workspace-invitation.email.jsx'
162
+
163
+ export const metadata = {
164
+ id: 'send-workspace-invitation',
165
+ triggers: [{ aggregateType: 'Workspace', event: 'UserInvited' }],
166
+ }
167
+
168
+ export async function run({ event, integrations }) {
169
+ const email = integrations.get('email')
170
+ if (!email) return
171
+
172
+ // Send a raw email
173
+ await email.send({
174
+ to: event.payload.email,
175
+ from: 'noreply@example.com',
176
+ subject: 'You have been invited',
177
+ html: '<p>Click <a href="...">here</a> to accept.</p>',
178
+ text: 'Click the link to accept the invitation.',
179
+ })
180
+
181
+ // Or send a React template
182
+ await email.sendTemplate(
183
+ WorkspaceInvitationEmail,
184
+ { inviteUrl: event.payload.inviteUrl, theme: {} },
185
+ { to: event.payload.email, from: 'noreply@example.com', subject: 'Invitation' },
186
+ )
187
+ }
188
+ ```
189
+
190
+ **Client API:**
191
+
192
+ | Method | Signature | Description |
193
+ |---|---|---|
194
+ | `send` | `({ to, from, subject, html, text }) => Promise` | Send a raw HTML/text email via SES. |
195
+ | `sendTemplate` | `(Component, props, { to, from, subject }) => Promise` | Render a React component with `EmailRenderer.render` and send via SES. |
196
+
197
+ ---
198
+
199
+ ## Using `emailIntegration` directly
200
+
201
+ If you need to connect the integration without the platform's auto-loader:
202
+
203
+ ```js
204
+ import { emailIntegration } from '@ossy/email'
205
+ import { IntegrationService } from '@ossy/platform'
206
+
207
+ await IntegrationService.load([emailIntegration], process.env)
208
+ const emailClient = IntegrationService.get('email')
209
+ ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@ossy/email",
3
3
  "private": false,
4
- "version": "1.2.1",
4
+ "version": "1.3.0",
5
5
  "type": "module",
6
6
  "main": "./src/index.js",
7
7
  "module": "./src/index.js",
@@ -19,5 +19,5 @@
19
19
  "react": "*",
20
20
  "react-dom": "*"
21
21
  },
22
- "gitHead": "a144d7767264d96bc6ae095784d4f884f03a89a0"
22
+ "gitHead": "6c7724dea1b5eda89e83319dce69703d622aadb1"
23
23
  }