jamdesk 1.0.8 → 1.0.9
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/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +23 -0
- package/dist/commands/update.js.map +1 -1
- package/package.json +1 -1
- package/vendored/lib/email-notifier.ts +12 -40
- package/vendored/lib/email-templates/build-failure.tsx +27 -8
- package/vendored/lib/email-templates/components/base-layout.tsx +30 -15
- package/vendored/lib/email-templates/components/error-box.tsx +10 -13
- package/vendored/lib/email-templates/components/info-row.tsx +7 -10
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,MAAM,WAAW,aAAa;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AA8BD,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwDvE"}
|
package/dist/commands/update.js
CHANGED
|
@@ -9,6 +9,25 @@ import { spinner } from '../lib/spinner.js';
|
|
|
9
9
|
import { createRequire } from 'module';
|
|
10
10
|
import { checkForUpdates, clearUpdateCache } from '../utils/update-checker.js';
|
|
11
11
|
const require = createRequire(import.meta.url);
|
|
12
|
+
/**
|
|
13
|
+
* Check if the deprecated @jamdesk/cli package is globally installed.
|
|
14
|
+
* If so, it shadows the jamdesk binary and must be removed first.
|
|
15
|
+
*/
|
|
16
|
+
function hasLegacyPackage() {
|
|
17
|
+
try {
|
|
18
|
+
const result = execFileSync('npm', ['list', '-g', '@jamdesk/cli', '--depth=0', '--json'], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'pipe'] });
|
|
19
|
+
const data = JSON.parse(result);
|
|
20
|
+
return !!data.dependencies?.['@jamdesk/cli'];
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function removeLegacyPackage(spin) {
|
|
27
|
+
spin.text = 'Removing deprecated @jamdesk/cli package...';
|
|
28
|
+
execFileSync('npm', ['uninstall', '-g', '@jamdesk/cli'], { stdio: 'pipe' });
|
|
29
|
+
output.info('Removed @jamdesk/cli (migrating to jamdesk)');
|
|
30
|
+
}
|
|
12
31
|
export async function update(options = {}) {
|
|
13
32
|
const pkg = require('../../package.json');
|
|
14
33
|
const currentVersion = pkg.version;
|
|
@@ -32,6 +51,10 @@ export async function update(options = {}) {
|
|
|
32
51
|
// Full update mode
|
|
33
52
|
const spin = spinner('Checking for updates...');
|
|
34
53
|
try {
|
|
54
|
+
// Remove legacy @jamdesk/cli if present — it shadows the jamdesk binary
|
|
55
|
+
if (hasLegacyPackage()) {
|
|
56
|
+
removeLegacyPackage(spin);
|
|
57
|
+
}
|
|
35
58
|
// Check latest version using execFileSync (safer than execSync)
|
|
36
59
|
const latestVersion = execFileSync('npm', ['view', 'jamdesk', 'version'], {
|
|
37
60
|
encoding: 'utf-8'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAE/E,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAM/C,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,UAAyB,EAAE;IACtD,MAAM,GAAG,GAAG,OAAO,CAAC,oBAAoB,CAAwB,CAAC;IACjE,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,CAAC;IAEnC,yCAAyC;IACzC,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,CAAC,IAAI,CAAC,oBAAoB,cAAc,EAAE,CAAC,CAAC;QAClD,gBAAgB,EAAE,CAAC,CAAC,oBAAoB;QAExC,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,MAAM,eAAe,CAAC,cAAc,EAAE;YACzE,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;SACb,CAAC,CAAC;QAEH,IAAI,SAAS,IAAI,aAAa,EAAE,CAAC;YAC/B,MAAM,CAAC,IAAI,CAAC,qBAAqB,cAAc,MAAM,aAAa,EAAE,CAAC,CAAC;YACtE,MAAM,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC;QAClD,CAAC;QACD,OAAO;IACT,CAAC;IAED,mBAAmB;IACnB,MAAM,IAAI,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;IAEhD,IAAI,CAAC;QACH,gEAAgE;QAChE,MAAM,aAAa,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE;YACxE,QAAQ,EAAE,OAAO;SAClB,CAAC,CAAC,IAAI,EAAE,CAAC;QAEV,IAAI,cAAc,KAAK,aAAa,EAAE,CAAC;YACrC,IAAI,CAAC,OAAO,CAAC,8BAA8B,cAAc,GAAG,CAAC,CAAC;YAC9D,OAAO;QACT,CAAC;QAED,IAAI,CAAC,IAAI,GAAG,oBAAoB,cAAc,MAAM,aAAa,KAAK,CAAC;QAEvE,gEAAgE;QAChE,YAAY,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,gBAAgB,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,OAAO,CAAC,sBAAsB,aAAa,EAAE,CAAC,CAAC;QAEpD,6CAA6C;QAC7C,gBAAgB,EAAE,CAAC;IACrB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC3B,MAAM,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC;QACvE,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jamdesk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
4
|
"description": "CLI for Jamdesk — build, preview, and deploy documentation sites from MDX. Dev server with hot reload, 50+ components, OpenAPI support, AI search, and Mintlify migration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"jamdesk",
|
|
@@ -1,56 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Email Notifier
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Currently supports internal build failure notifications.
|
|
6
|
-
*
|
|
7
|
-
* Environment variables:
|
|
8
|
-
* - RESEND_API_KEY: Resend API key for sending emails
|
|
9
|
-
* - JAMDESK_REPORT_EMAIL: Email address for internal notifications
|
|
2
|
+
* Email Notifier — sends internal build failure notifications via Resend.
|
|
3
|
+
*
|
|
4
|
+
* Env: BUILDER_RESEND_API_KEY, JAMDESK_REPORT_EMAIL
|
|
10
5
|
*/
|
|
11
6
|
|
|
12
7
|
import { render } from '@react-email/render';
|
|
13
8
|
import { Resend } from 'resend';
|
|
14
9
|
import { BuildFailureEmail, type BuildFailureEmailProps } from './email-templates/index.js';
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
* Build failure email info
|
|
18
|
-
* Contains all data needed to render and send a build failure notification
|
|
19
|
-
*/
|
|
20
|
-
export interface BuildFailureEmailInfo extends BuildFailureEmailProps {
|
|
21
|
-
// All fields inherited from BuildFailureEmailProps
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Re-export for convenience
|
|
25
|
-
export type { BuildFailureEmailProps };
|
|
11
|
+
export type BuildFailureEmailInfo = BuildFailureEmailProps;
|
|
26
12
|
|
|
27
13
|
/**
|
|
28
|
-
* Send an internal build failure notification
|
|
29
|
-
*
|
|
30
|
-
* This is an internal-only notification sent to the JAMDESK_REPORT_EMAIL address.
|
|
14
|
+
* Send an internal build failure notification to JAMDESK_REPORT_EMAIL.
|
|
31
15
|
* Gracefully skips if environment variables are not configured.
|
|
32
|
-
*
|
|
33
|
-
* @param info - Build failure information
|
|
34
16
|
*/
|
|
35
17
|
export async function sendInternalBuildFailureEmail(info: BuildFailureEmailInfo): Promise<void> {
|
|
36
18
|
const apiKey = process.env.BUILDER_RESEND_API_KEY;
|
|
37
19
|
const reportEmail = process.env.JAMDESK_REPORT_EMAIL;
|
|
38
20
|
|
|
39
|
-
|
|
40
|
-
if (!apiKey) {
|
|
41
|
-
console.log(JSON.stringify({
|
|
42
|
-
severity: 'WARNING',
|
|
43
|
-
message: 'Email notification skipped - BUILDER_RESEND_API_KEY not configured',
|
|
44
|
-
projectId: info.projectId,
|
|
45
|
-
buildId: info.buildId,
|
|
46
|
-
}));
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
if (!reportEmail) {
|
|
21
|
+
if (!apiKey || !reportEmail) {
|
|
51
22
|
console.log(JSON.stringify({
|
|
52
23
|
severity: 'WARNING',
|
|
53
|
-
message:
|
|
24
|
+
message: `Email notification skipped - ${!apiKey ? 'BUILDER_RESEND_API_KEY' : 'JAMDESK_REPORT_EMAIL'} not configured`,
|
|
54
25
|
projectId: info.projectId,
|
|
55
26
|
buildId: info.buildId,
|
|
56
27
|
}));
|
|
@@ -60,15 +31,16 @@ export async function sendInternalBuildFailureEmail(info: BuildFailureEmailInfo)
|
|
|
60
31
|
try {
|
|
61
32
|
const resend = new Resend(apiKey);
|
|
62
33
|
|
|
63
|
-
|
|
64
|
-
const html = await render(
|
|
65
|
-
|
|
66
|
-
|
|
34
|
+
const template = BuildFailureEmail(info);
|
|
35
|
+
const html = await render(template);
|
|
36
|
+
const text = await render(template, {plainText: true});
|
|
37
|
+
|
|
67
38
|
const result = await resend.emails.send({
|
|
68
39
|
from: 'Jamdesk <no-reply@mail.jamdesk.com>',
|
|
69
40
|
to: reportEmail,
|
|
70
41
|
subject: `[Jamdesk] Build Failed: ${info.projectName || info.projectId}`,
|
|
71
42
|
html,
|
|
43
|
+
text,
|
|
72
44
|
});
|
|
73
45
|
|
|
74
46
|
if (result.error) {
|
|
@@ -135,16 +135,17 @@ export function BuildFailureEmail(props: BuildFailureEmailProps) {
|
|
|
135
135
|
: undefined;
|
|
136
136
|
|
|
137
137
|
return (
|
|
138
|
-
<BaseLayout
|
|
139
|
-
{
|
|
140
|
-
|
|
138
|
+
<BaseLayout
|
|
139
|
+
title={`Build Failed: ${projectName || projectId}`}
|
|
140
|
+
preview={`Build failed for ${projectName || projectId}${errorRef ? ` (${errorRef})` : ''}`}
|
|
141
|
+
>
|
|
142
|
+
<ErrorBox
|
|
141
143
|
error={error}
|
|
142
144
|
errorRef={errorRef}
|
|
143
145
|
errorType={errorType}
|
|
144
146
|
errorSuggestion={errorSuggestion}
|
|
145
147
|
/>
|
|
146
148
|
|
|
147
|
-
{/* User Information */}
|
|
148
149
|
<Text style={styles.sectionTitle}>User Information</Text>
|
|
149
150
|
<Section style={styles.infoGrid}>
|
|
150
151
|
<InfoRow label="User ID" value={triggeredByUserId} monospace />
|
|
@@ -153,7 +154,6 @@ export function BuildFailureEmail(props: BuildFailureEmailProps) {
|
|
|
153
154
|
<InfoRow label="Trigger Method" value={formatTriggerMethod(triggeredBy)} />
|
|
154
155
|
</Section>
|
|
155
156
|
|
|
156
|
-
{/* Project Details */}
|
|
157
157
|
<Text style={styles.sectionTitle}>Project Details</Text>
|
|
158
158
|
<Section style={styles.infoGrid}>
|
|
159
159
|
<InfoRow label="Project Name" value={projectName} />
|
|
@@ -163,7 +163,6 @@ export function BuildFailureEmail(props: BuildFailureEmailProps) {
|
|
|
163
163
|
<InfoRow label="Branch" value={branch} />
|
|
164
164
|
</Section>
|
|
165
165
|
|
|
166
|
-
{/* Build Details */}
|
|
167
166
|
<Text style={styles.sectionTitle}>Build Details</Text>
|
|
168
167
|
<Section style={styles.infoGrid}>
|
|
169
168
|
<InfoRow label="Build ID" value={buildId} monospace />
|
|
@@ -173,7 +172,6 @@ export function BuildFailureEmail(props: BuildFailureEmailProps) {
|
|
|
173
172
|
<InfoRow label="Duration" value={formatDuration(duration)} />
|
|
174
173
|
</Section>
|
|
175
174
|
|
|
176
|
-
{/* CTA Button */}
|
|
177
175
|
<Section style={styles.buttonContainer}>
|
|
178
176
|
<Button href={superadminUrl} style={styles.button}>
|
|
179
177
|
View in Superadmin
|
|
@@ -189,5 +187,26 @@ export function BuildFailureEmail(props: BuildFailureEmailProps) {
|
|
|
189
187
|
);
|
|
190
188
|
}
|
|
191
189
|
|
|
192
|
-
//
|
|
190
|
+
// Preview props for React Email dev server
|
|
191
|
+
BuildFailureEmail.PreviewProps = {
|
|
192
|
+
projectId: 'proj_abc123',
|
|
193
|
+
buildId: 'build_xyz789',
|
|
194
|
+
projectName: 'Acme Docs',
|
|
195
|
+
slug: 'acme',
|
|
196
|
+
error: 'Module not found: Cannot find package \'@acme/custom-component\'',
|
|
197
|
+
errorType: 'module_not_found',
|
|
198
|
+
errorRef: 'ERR-ABC12345',
|
|
199
|
+
errorSuggestion: 'Check that all required packages are listed in your package.json dependencies.',
|
|
200
|
+
failedPhase: 'nextjs_build',
|
|
201
|
+
triggeredByUserId: 'user_123',
|
|
202
|
+
triggeredByUserEmail: 'dev@acme.com',
|
|
203
|
+
triggeredByGitHubUsername: 'acme-dev',
|
|
204
|
+
triggeredBy: 'push',
|
|
205
|
+
repoFullName: 'acme/docs',
|
|
206
|
+
branch: 'main',
|
|
207
|
+
commitSha: 'abc1234567890def',
|
|
208
|
+
commitMessage: 'feat: add custom hero component to getting started page',
|
|
209
|
+
duration: 42.7,
|
|
210
|
+
} as BuildFailureEmailProps;
|
|
211
|
+
|
|
193
212
|
export default BuildFailureEmail;
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Base Layout Component
|
|
3
3
|
*
|
|
4
|
-
* Shared layout wrapper for all
|
|
5
|
-
* Uses muted dashboard style guide colors with the Jamdesk logo.
|
|
6
|
-
*
|
|
4
|
+
* Shared layout wrapper for all builder emails (internal notifications).
|
|
7
5
|
* Keep in sync with: dashboard/functions/src/lib/email-templates/components/base-layout.tsx
|
|
8
6
|
*/
|
|
9
7
|
|
|
10
8
|
import {
|
|
11
9
|
Html,
|
|
12
10
|
Head,
|
|
11
|
+
Preview,
|
|
13
12
|
Body,
|
|
14
13
|
Container,
|
|
15
14
|
Img,
|
|
@@ -28,17 +27,27 @@ const darkModeStyles = `
|
|
|
28
27
|
.email-body { background-color: #0A1628 !important; }
|
|
29
28
|
.email-container { background-color: #111827 !important; }
|
|
30
29
|
.email-content { background-color: #111827 !important; }
|
|
31
|
-
.email-footer { background-color: #111827 !important; border-color: #374151 !important; }
|
|
30
|
+
.email-footer { background-color: #111827 !important; border-color: #374151 !important; }
|
|
32
31
|
.email-title { color: #F9FAFB !important; }
|
|
33
32
|
.email-paragraph { color: #E5E7EB !important; }
|
|
34
33
|
.email-footer-text { color: #9CA3AF !important; }
|
|
34
|
+
|
|
35
|
+
/* Prevent white text inversion on indigo elements */
|
|
36
|
+
.email-button { color: #ffffff !important; background-color: #635BFF !important; }
|
|
37
|
+
|
|
38
|
+
/* Error box */
|
|
39
|
+
.email-error-box { background-color: #450a0a !important; border-color: #dc2626 !important; }
|
|
40
|
+
.email-error-title { color: #fecaca !important; }
|
|
41
|
+
.email-error-text { color: #fecaca !important; }
|
|
42
|
+
.email-error-ref { background-color: #92400e !important; color: #fecaca !important; }
|
|
35
43
|
}
|
|
36
44
|
`;
|
|
37
45
|
|
|
38
46
|
export interface BaseLayoutProps {
|
|
39
47
|
title: string;
|
|
40
48
|
children: React.ReactNode;
|
|
41
|
-
|
|
49
|
+
footerText?: string;
|
|
50
|
+
preview?: string;
|
|
42
51
|
}
|
|
43
52
|
|
|
44
53
|
// Muted dashboard style guide colors
|
|
@@ -97,9 +106,14 @@ const styles = {
|
|
|
97
106
|
},
|
|
98
107
|
};
|
|
99
108
|
|
|
100
|
-
export function BaseLayout({
|
|
109
|
+
export function BaseLayout({
|
|
110
|
+
title,
|
|
111
|
+
children,
|
|
112
|
+
footerText = 'This is an internal Jamdesk notification. Do not reply to this email.',
|
|
113
|
+
preview,
|
|
114
|
+
}: BaseLayoutProps) {
|
|
101
115
|
return (
|
|
102
|
-
<Html>
|
|
116
|
+
<Html lang="en">
|
|
103
117
|
<Head>
|
|
104
118
|
<title>{title}</title>
|
|
105
119
|
<meta content="light dark" name="color-scheme" />
|
|
@@ -107,10 +121,11 @@ export function BaseLayout({ title, children, showFooterDisclaimer = true }: Bas
|
|
|
107
121
|
<style dangerouslySetInnerHTML={{ __html: darkModeStyles }} />
|
|
108
122
|
</Head>
|
|
109
123
|
<Body style={styles.body} className="email-body">
|
|
124
|
+
{preview && <Preview>{preview}</Preview>}
|
|
110
125
|
{/* Logo above the white card, in the grey background */}
|
|
111
126
|
<Section style={styles.logoSection}>
|
|
112
127
|
<Img
|
|
113
|
-
src="https://dashboard.jamdesk.com/logo-light.png"
|
|
128
|
+
src="https://dashboard.jamdesk.com/static/logo-light.png"
|
|
114
129
|
alt="Jamdesk"
|
|
115
130
|
width="140"
|
|
116
131
|
height="auto"
|
|
@@ -118,7 +133,7 @@ export function BaseLayout({ title, children, showFooterDisclaimer = true }: Bas
|
|
|
118
133
|
style={{ margin: '0 auto', display: 'block' }}
|
|
119
134
|
/>
|
|
120
135
|
<Img
|
|
121
|
-
src="https://dashboard.jamdesk.com/logo-dark.png"
|
|
136
|
+
src="https://dashboard.jamdesk.com/static/logo-dark.png"
|
|
122
137
|
alt="Jamdesk"
|
|
123
138
|
width="140"
|
|
124
139
|
height="auto"
|
|
@@ -134,11 +149,12 @@ export function BaseLayout({ title, children, showFooterDisclaimer = true }: Bas
|
|
|
134
149
|
</Section>
|
|
135
150
|
|
|
136
151
|
<Section style={styles.footer} className="email-footer">
|
|
137
|
-
{
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
152
|
+
<Text style={styles.footerText} className="email-footer-text">
|
|
153
|
+
{footerText}
|
|
154
|
+
</Text>
|
|
155
|
+
<Text style={{...styles.footerText, marginTop: '8px'}} className="email-footer-text">
|
|
156
|
+
Jamdesk · New York, NY
|
|
157
|
+
</Text>
|
|
142
158
|
</Section>
|
|
143
159
|
</Container>
|
|
144
160
|
</Body>
|
|
@@ -146,5 +162,4 @@ export function BaseLayout({ title, children, showFooterDisclaimer = true }: Bas
|
|
|
146
162
|
);
|
|
147
163
|
}
|
|
148
164
|
|
|
149
|
-
// Export colors and common styles for use in other templates
|
|
150
165
|
export { styles as baseStyles };
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Error Box Component
|
|
3
|
-
*
|
|
4
|
-
* Displays error information in a prominent red-accented box.
|
|
5
|
-
* Used for showing build failure details.
|
|
2
|
+
* Error Box Component — red-accented box for build failure details.
|
|
6
3
|
*/
|
|
7
4
|
|
|
8
5
|
import { Section, Text } from '@react-email/components';
|
|
@@ -66,20 +63,20 @@ const styles = {
|
|
|
66
63
|
|
|
67
64
|
export function ErrorBox({ error, errorRef, errorType, errorSuggestion }: ErrorBoxProps) {
|
|
68
65
|
return (
|
|
69
|
-
<Section style={styles.container}>
|
|
70
|
-
<Text style={styles.errorLabel}>Error</Text>
|
|
71
|
-
<Text style={styles.errorMessage}>{error}</Text>
|
|
72
|
-
|
|
66
|
+
<Section style={styles.container} className="email-error-box">
|
|
67
|
+
<Text style={styles.errorLabel} className="email-error-title">Error</Text>
|
|
68
|
+
<Text style={styles.errorMessage} className="email-error-text">{error}</Text>
|
|
69
|
+
|
|
73
70
|
{errorRef && (
|
|
74
|
-
<Text style={styles.errorRef}>{errorRef}</Text>
|
|
71
|
+
<Text style={styles.errorRef} className="email-error-ref">{errorRef}</Text>
|
|
75
72
|
)}
|
|
76
|
-
|
|
73
|
+
|
|
77
74
|
{errorType && (
|
|
78
|
-
<Text style={styles.errorType}>Type: {errorType}</Text>
|
|
75
|
+
<Text style={styles.errorType} className="email-paragraph">Type: {errorType}</Text>
|
|
79
76
|
)}
|
|
80
|
-
|
|
77
|
+
|
|
81
78
|
{errorSuggestion && (
|
|
82
|
-
<Text style={styles.suggestion}>
|
|
79
|
+
<Text style={styles.suggestion} className="email-paragraph">
|
|
83
80
|
💡 {errorSuggestion}
|
|
84
81
|
</Text>
|
|
85
82
|
)}
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Info Row Component
|
|
3
|
-
*
|
|
4
|
-
* Displays a key-value pair in a consistent format.
|
|
5
|
-
* Used for showing build details, user info, etc.
|
|
2
|
+
* Info Row Component — key-value pair for build details and user info.
|
|
6
3
|
*/
|
|
7
4
|
|
|
8
|
-
import { Text } from '@react-email/components';
|
|
5
|
+
import { Section, Text } from '@react-email/components';
|
|
9
6
|
import * as React from 'react';
|
|
10
7
|
import { colors } from './base-layout.js';
|
|
11
8
|
|
|
@@ -49,15 +46,15 @@ export function InfoRow({ label, value, monospace = false }: InfoRowProps) {
|
|
|
49
46
|
: null;
|
|
50
47
|
|
|
51
48
|
return (
|
|
52
|
-
<
|
|
53
|
-
<Text style={styles.label}>{label}</Text>
|
|
49
|
+
<Section style={styles.row}>
|
|
50
|
+
<Text style={styles.label} className="email-footer-text">{label}</Text>
|
|
54
51
|
{displayValue ? (
|
|
55
|
-
<Text style={monospace ? styles.valueMonospace : styles.value}>
|
|
52
|
+
<Text style={monospace ? styles.valueMonospace : styles.value} className="email-paragraph">
|
|
56
53
|
{displayValue}
|
|
57
54
|
</Text>
|
|
58
55
|
) : (
|
|
59
|
-
<Text style={styles.notAvailable}>Not available</Text>
|
|
56
|
+
<Text style={styles.notAvailable} className="email-footer-text">Not available</Text>
|
|
60
57
|
)}
|
|
61
|
-
</
|
|
58
|
+
</Section>
|
|
62
59
|
);
|
|
63
60
|
}
|