Skip to content

Commit 533633a

Browse files
committed
chore: update prettier, sort imports
1 parent 1a8f1b3 commit 533633a

File tree

32 files changed

+335
-1682
lines changed

32 files changed

+335
-1682
lines changed

.prettierrc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@
33
"printWidth": 100,
44
"singleQuote": true,
55
"trailingComma": "none",
6-
"plugins": ["prettier-plugin-package"]
6+
"plugins": ["prettier-plugin-package", "@trivago/prettier-plugin-sort-imports"],
7+
"importOrder": ["^node:(.*)$", "<THIRD_PARTY_MODULES>", "^@jsx-email/(.*)$", "^(../)+(.*)$", "^[./]"],
8+
"importOrderSeparation": true,
9+
"importOrderSortSpecifiers": true
710
}

apps/preview/app/src/templates.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { parseName } from './helpers';
2-
import type { PreviewImportContent, TemplatePart, TemplateData } from './types.ts';
2+
import type { PreviewImportContent, TemplateData, TemplatePart } from './types.ts';
33

44
export const gather = async () => {
55
const imports = import.meta.glob<PreviewImportContent>(`@jsxemailbuild/**/*.js`, {

moon.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,11 @@ tasks:
5959
options:
6060
cache: false
6161

62+
lint.format:
63+
command: prettier --write **/*.{js,ts,cjs}
64+
options:
65+
cache: false
66+
6267
lint.json:
6368
command: 'prettier --write .github/**/*.yml **/tsconfig.json **/tsconfig.*.json pnpm-workspace.yaml .moon/*.yml **/moon.yml'
6469
options:

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,15 @@
1111
"@moonrepo/cli": "1.35.0",
1212
"@swc/core": "^1.3.91",
1313
"@swc/helpers": "^0.5.2",
14+
"@trivago/prettier-plugin-sort-imports": "^5.2.2",
1415
"@types/node": "22.14.1",
1516
"@types/react": "19.1.2",
1617
"@types/react-dom": "19.1.2",
1718
"create-mail": "workspace:^",
1819
"gh-pages": "^6.0.0",
1920
"happy-dom": "^17.4.4",
2021
"husky": "^9.1.7",
21-
"jsx-email": "*",
22+
"jsx-email": "workspace:^",
2223
"lint-staged": "15.5.1",
2324
"oxlint": "^0.16.6",
2425
"prettier": "^3.5.3",
@@ -39,7 +40,7 @@
3940
"prettier --write"
4041
],
4142
"*package.json": [
42-
"prettier --write --plugin=prettier-plugin-package"
43+
"prettier --write"
4344
],
4445
"((.github/**/*)|(docs/**/*)|(web/**/*.md)|(README|CHANGELOG)|(**/(README|CHANGELOG))).md": [
4546
"prettier --write"

packages/create-mail/src/index.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
/* eslint-disable no-await-in-loop, no-underscore-dangle */
2-
3-
import { existsSync, readdirSync, rmSync } from 'fs';
4-
import { mkdir, readFile, writeFile } from 'fs/promises';
5-
import { basename, dirname, join, relative, resolve, win32, posix } from 'path';
62
import { fileURLToPath } from 'node:url';
73

84
import chalk from 'chalk-template';
9-
import { detect } from 'package-manager-detector/detect';
5+
import { existsSync, readdirSync, rmSync } from 'fs';
106
import { globby } from 'globby';
117
import mustache from 'mustache';
8+
import { detect } from 'package-manager-detector/detect';
9+
import { basename, dirname, join, posix, relative, resolve, win32 } from 'path';
1210
import prompts from 'prompts';
1311
import yargs from 'yargs-parser';
1412

13+
import { mkdir, readFile, writeFile } from 'fs/promises';
14+
1515
import * as pkg from './package-info.cjs';
1616

1717
interface CreateEmailArgs {

packages/jsx-email/cli.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Please upgrade Node.js to a supported version: ${engines}\n`);
2525
await checkEngine();
2626
const { run } = await import('./dist/cli/index.js');
2727
return run();
28-
})
28+
})()
2929
.then(() => process.exit(0))
3030
.catch((error) => {
3131
danger(error);

packages/jsx-email/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,6 @@
5454
},
5555
"dependencies": {
5656
"@dot/log": "^0.2.0",
57-
"@jsx-email/doiuse-email": "^1.0.1",
5857
"@parcel/watcher": "^2.4.1",
5958
"@radix-ui/colors": "3.0.0",
6059
"@radix-ui/react-collapsible": "1.1.4",
@@ -72,6 +71,7 @@
7271
"@unocss/transformer-variant-group": "^66.0.0",
7372
"@vitejs/plugin-react": "^4.3.0",
7473
"autoprefixer": "^10.4.16",
74+
"caniemail": "0.1.0-beta3",
7575
"chalk": "5.4.1",
7676
"chalk-template": "^1.1.0",
7777
"classnames": "2.5.1",
@@ -98,6 +98,7 @@
9898
"shiki": "^3.2.2",
9999
"source-map-support": "^0.5.21",
100100
"std-env": "^3.6.0",
101+
"strip-ansi": "^7.1.0",
101102
"tailwindcss": "4.1.4",
102103
"titleize": "^4.0.0",
103104
"unist-util-visit": "^5.0.0",

packages/jsx-email/src/cli/commands/build.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
import { existsSync } from 'node:fs';
22
import { mkdir, realpath, writeFile } from 'node:fs/promises';
33
import os from 'node:os';
4-
import { dirname, basename, extname, join, resolve, win32, posix } from 'path';
5-
import { pathToFileURL } from 'url';
64

75
import chalkTmpl from 'chalk-template';
86
import { globby } from 'globby';
97
import micromatch from 'micromatch';
8+
import { basename, dirname, extname, join, posix, resolve, win32 } from 'path';
109
import { isWindows } from 'std-env';
10+
import { pathToFileURL } from 'url';
1111
import type { InferOutput as Infer } from 'valibot';
1212
import { parse as assert, boolean, object, optional, string } from 'valibot';
1313

1414
import { log } from '../../log.js';
15-
import { formatBytes, gmailByteLimit } from '../helpers.js';
1615
import { compile } from '../../renderer/compile.js';
1716
import { render } from '../../renderer/render.js';
17+
import { formatBytes, gmailByteLimit } from '../helpers.js';
1818

1919
import type { CommandFn, TemplateFn } from './types.js';
2020

packages/jsx-email/src/cli/commands/check.ts

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { lstat } from 'node:fs/promises';
22

3-
import { doIUseEmail } from '@jsx-email/doiuse-email';
3+
import { type IssueGroup, caniemail, groupIssues, sortIssues } from 'caniemail';
44
import chalk from 'chalk';
55
import chalkTmpl from 'chalk-template';
6-
import { parse as assert, object, type InferOutput as Infer } from 'valibot';
6+
import stripAnsi from 'strip-ansi';
7+
import { type InferOutput as Infer, parse as assert, object } from 'valibot';
78

89
import { formatBytes, gmailByteLimit, gmailBytesSafe } from '../helpers.js';
910

@@ -25,28 +26,6 @@ const emailClients = [
2526
'fastmail.*'
2627
];
2728

28-
const formatSubject = (what: string) =>
29-
what.replace(/`([\s\w<>.-]+)`/g, (_, bit) => chalkTmpl`{bold ${bit}}`).trim();
30-
31-
const combine = (lines: string[]) => {
32-
const rePreamble = /(`([\s\w<>.-]+)`[\s\w]+)/;
33-
34-
const result = lines.reduce<Record<string, string[]>>((prev, curr) => {
35-
const matches = curr.match(rePreamble);
36-
const [preamble] = matches!;
37-
38-
prev[preamble] = (prev[preamble] || []).concat(curr.replace(rePreamble, '').replace(/`/g, ''));
39-
40-
return prev;
41-
}, {});
42-
43-
for (const key of Object.keys(result)) {
44-
result[key] = Array.from(new Set(result[key]));
45-
}
46-
47-
return result;
48-
};
49-
5029
export const help = chalkTmpl`
5130
{blue email check}
5231
@@ -59,59 +38,76 @@ Check jsx-email templates for client compatibility
5938
$ email check ./emails/Batman.tsx
6039
`;
6140

41+
const formatNotes = (notes: string[], indent: string) => {
42+
if (!notes.length) return '';
43+
const noteLines = (notes as string[]).join(`\n${'.'.repeat(indent.length)}**`);
44+
console.log({ noteLines });
45+
return chalkTmpl`\n${indent}{cyan Notes}:\n${'.'.repeat(indent.length)}asshole\n`;
46+
};
47+
48+
const formatIssue = (group: IssueGroup): string => {
49+
const { issue, clients } = group;
50+
const { position, support, title } = issue;
51+
const positionTuple = chalkTmpl`{dim ${position!.start.line}:${position!.start.column}}`;
52+
const notes = issue.notes.length ? issue.notes.map((note, index) => `${index + 1}. ${note}`) : [];
53+
let lineType = '';
54+
55+
if (support === 'none') {
56+
lineType = chalkTmpl` {red error}`;
57+
} else {
58+
lineType = chalkTmpl` {yellow warn} `;
59+
}
60+
61+
const preamble = `${lineType} ${positionTuple} `;
62+
const indent = ' '.repeat(stripAnsi(preamble).length + 2);
63+
const footnotes = formatNotes(notes, indent);
64+
65+
return chalkTmpl`${preamble}${title}:${footnotes}\n${indent}{dim ${clients.join(`\n${indent}`)}}\n`;
66+
};
67+
6268
const runCheck = (fileName: string, html: string) => {
6369
const bytes = Buffer.byteLength(html, 'utf8');
64-
const counts = { errors: 0, notes: 0, warnings: 0 };
6570
const htmlSize = formatBytes(bytes);
66-
const result = doIUseEmail(html, { emailClients });
67-
const { success } = result;
71+
const result = caniemail({ clients: emailClients as any, html });
72+
const { issues, success } = result;
73+
const { errors, warnings } = issues;
74+
const counts = {
75+
errors: 0,
76+
notes: 0,
77+
warnings: 0
78+
};
6879

69-
if (success && !result.warnings) return;
80+
if (success && !issues.warnings) return;
7081

7182
log(chalkTmpl`{underline ${fileName}} → HTML: ${htmlSize}\n`);
7283

73-
if (!success && result.errors?.length) {
74-
const errors = combine(result.errors);
75-
const indent = ' ';
76-
for (const [preamble, clients] of Object.entries(errors)) {
77-
log(
78-
chalkTmpl` {red error} ${formatSubject(preamble)}:\n${indent}{dim ${clients.join(
79-
`\n${indent}`
80-
)}}\n`
81-
);
82-
83-
counts.errors += 1;
84-
}
85-
}
86-
8784
if (bytes >= gmailByteLimit) {
8885
log(chalkTmpl` {red error} HTML content is over the Gmail Clipping Limit: ${htmlSize}\n`);
8986
counts.errors += 1;
87+
} else if (bytes > gmailBytesSafe && bytes < gmailByteLimit) {
88+
log(chalkTmpl` {red warn} HTML content is near the Gmail Clipping Limit: ${htmlSize}\n`);
89+
counts.warnings += 1;
9090
}
9191

92-
if (result.warnings?.length) {
93-
const warnings = combine(result.warnings);
94-
const indent = ' ';
95-
for (const [preamble, clients] of Object.entries(warnings)) {
96-
log(
97-
chalkTmpl` {yellow warn} ${formatSubject(preamble)}:\n${indent}{dim ${clients.join(
98-
`\n${indent}`
99-
)}}\n`
100-
);
101-
counts.warnings += 1;
102-
}
103-
}
92+
if (errors?.size || warnings?.size) {
93+
const groupedErrors = groupIssues(errors);
94+
const groupedWarnings = groupIssues(warnings);
95+
const sorted = sortIssues([...groupedErrors, ...groupedWarnings]);
10496

105-
if (bytes > gmailBytesSafe && bytes < gmailByteLimit) {
106-
log(chalkTmpl` {red warn} HTML content is near the Gmail Clipping Limit: ${htmlSize}\n`);
107-
counts.warnings += 1;
97+
for (const group of sorted) {
98+
if (group.issue.support === 'none') counts.errors += 1;
99+
if (group.issue.support === 'partial') counts.warnings += 1;
100+
log(formatIssue(group));
101+
}
108102
}
109103

110-
const errors = counts.errors > 0 ? chalk.red(counts.errors) : chalk.green(counts.errors);
111-
const warnings =
104+
const errorCount = counts.errors > 0 ? chalk.red(counts.errors) : chalk.green(counts.errors);
105+
const warningCount =
112106
counts.warnings > 0 ? chalk.yellow(counts.warnings) : chalk.green(counts.warnings);
113107

114-
log(chalkTmpl`{green Check Complete:} ${errors} error(s), ${warnings} warning(s)`);
108+
log(
109+
chalkTmpl` {green {bold ✓}} {dim Check Complete}: ${errorCount} error(s), ${warningCount} warning(s)`
110+
);
115111
};
116112

117113
export const command: CommandFn = async (argv: CheckOptions, input) => {

packages/jsx-email/src/cli/commands/create.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@ import { fileURLToPath } from 'node:url';
55
import chalk from 'chalk-template';
66
import mustache from 'mustache';
77
import {
8+
type InferOutput as Infer,
89
parse as assert,
910
boolean,
1011
object,
1112
optional,
12-
string,
13-
type InferOutput as Infer
13+
string
1414
} from 'valibot';
1515

1616
import { type CommandFn } from './types.js';

0 commit comments

Comments
 (0)