better-svelte-email 1.1.0-beta.0 → 1.2.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.
- package/README.md +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/preview/index.d.ts +13 -9
- package/dist/preview/index.js +13 -9
- package/dist/render/index.d.ts +35 -5
- package/dist/render/index.js +28 -8
- package/dist/render/utils/css/resolve-all-css-variables.d.ts +0 -1
- package/dist/render/utils/css/resolve-all-css-variables.js +98 -68
- package/dist/render/utils/tailwindcss/sanitize-custom-css.d.ts +1 -0
- package/dist/render/utils/tailwindcss/sanitize-custom-css.js +10 -0
- package/dist/render/utils/tailwindcss/setup-tailwind.d.ts +6 -1
- package/dist/render/utils/tailwindcss/setup-tailwind.js +9 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -61,6 +61,7 @@ For older versions, you can use [`svelte-email-tailwind`](https://github.com/ste
|
|
|
61
61
|
- Nested components
|
|
62
62
|
- All svelte features such as each blocks (`{#each}`) and if blocks (`{#if}`), and more
|
|
63
63
|
- Custom Tailwind configurations
|
|
64
|
+
- Custom CSS injection (for app theme integration)
|
|
64
65
|
|
|
65
66
|
## Author
|
|
66
67
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export * from './components/index.js';
|
|
2
|
-
export { default as Renderer, toPlainText, type TailwindConfig, type RenderOptions } from './render/index.js';
|
|
2
|
+
export { default as Renderer, toPlainText, type TailwindConfig, type RendererOptions, type RenderOptions } from './render/index.js';
|
package/dist/preview/index.d.ts
CHANGED
|
@@ -49,10 +49,12 @@ export declare const getEmailComponent: (emailPath: string, file: string) => Pro
|
|
|
49
49
|
* import Renderer from 'better-svelte-email/render';
|
|
50
50
|
*
|
|
51
51
|
* const renderer = new Renderer({
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
52
|
+
* tailwindConfig: {
|
|
53
|
+
* theme: {
|
|
54
|
+
* extend: {
|
|
55
|
+
* colors: {
|
|
56
|
+
* brand: '#FF3E00'
|
|
57
|
+
* }
|
|
56
58
|
* }
|
|
57
59
|
* }
|
|
58
60
|
* }
|
|
@@ -108,17 +110,19 @@ export declare const SendEmailFunction: ({ from, to, subject, html }: {
|
|
|
108
110
|
* import Renderer from 'better-svelte-email/render';
|
|
109
111
|
*
|
|
110
112
|
* const renderer = new Renderer({
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
114
|
-
*
|
|
113
|
+
* tailwindConfig: {
|
|
114
|
+
* theme: {
|
|
115
|
+
* extend: {
|
|
116
|
+
* colors: {
|
|
117
|
+
* brand: '#FF3E00'
|
|
118
|
+
* }
|
|
115
119
|
* }
|
|
116
120
|
* }
|
|
117
121
|
* }
|
|
118
122
|
* });
|
|
119
123
|
*
|
|
120
124
|
* export const actions = {
|
|
121
|
-
* ...createEmail(renderer),
|
|
125
|
+
* ...createEmail({ renderer }),
|
|
122
126
|
* ...sendEmail({ resendApiKey: PRIVATE_RESEND_API_KEY, renderer })
|
|
123
127
|
* };
|
|
124
128
|
* ```
|
package/dist/preview/index.js
CHANGED
|
@@ -98,10 +98,12 @@ const getEmailSource = async (emailPath, file) => {
|
|
|
98
98
|
* import Renderer from 'better-svelte-email/render';
|
|
99
99
|
*
|
|
100
100
|
* const renderer = new Renderer({
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
101
|
+
* tailwindConfig: {
|
|
102
|
+
* theme: {
|
|
103
|
+
* extend: {
|
|
104
|
+
* colors: {
|
|
105
|
+
* brand: '#FF3E00'
|
|
106
|
+
* }
|
|
105
107
|
* }
|
|
106
108
|
* }
|
|
107
109
|
* }
|
|
@@ -176,17 +178,19 @@ const defaultSendEmailFunction = async ({ from, to, subject, html }, resendApiKe
|
|
|
176
178
|
* import Renderer from 'better-svelte-email/render';
|
|
177
179
|
*
|
|
178
180
|
* const renderer = new Renderer({
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
*
|
|
181
|
+
* tailwindConfig: {
|
|
182
|
+
* theme: {
|
|
183
|
+
* extend: {
|
|
184
|
+
* colors: {
|
|
185
|
+
* brand: '#FF3E00'
|
|
186
|
+
* }
|
|
183
187
|
* }
|
|
184
188
|
* }
|
|
185
189
|
* }
|
|
186
190
|
* });
|
|
187
191
|
*
|
|
188
192
|
* export const actions = {
|
|
189
|
-
* ...createEmail(renderer),
|
|
193
|
+
* ...createEmail({ renderer }),
|
|
190
194
|
* ...sendEmail({ resendApiKey: PRIVATE_RESEND_API_KEY, renderer })
|
|
191
195
|
* };
|
|
192
196
|
* ```
|
package/dist/render/index.d.ts
CHANGED
|
@@ -2,6 +2,28 @@ import { type DefaultTreeAdapterTypes } from 'parse5';
|
|
|
2
2
|
import type { Config } from 'tailwindcss';
|
|
3
3
|
export type TailwindConfig = Omit<Config, 'content'>;
|
|
4
4
|
export type { DefaultTreeAdapterTypes as AST };
|
|
5
|
+
/**
|
|
6
|
+
* Options for creating a Renderer instance
|
|
7
|
+
*/
|
|
8
|
+
export type RendererOptions = {
|
|
9
|
+
/** Tailwind CSS configuration */
|
|
10
|
+
tailwindConfig?: TailwindConfig;
|
|
11
|
+
/**
|
|
12
|
+
* Custom CSS to inject into email rendering (e.g., app theme variables).
|
|
13
|
+
*
|
|
14
|
+
* This CSS is injected during Tailwind compilation, making variables and styles
|
|
15
|
+
* available for processing. Useful for maintaining consistent styling between
|
|
16
|
+
* your app and emails (e.g., shadcn-svelte theme variables).
|
|
17
|
+
*
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import appStyles from './app.css?raw';
|
|
22
|
+
* const renderer = new Renderer({ customCSS: appStyles });
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
customCSS?: string;
|
|
26
|
+
};
|
|
5
27
|
/**
|
|
6
28
|
* Options for rendering a Svelte component
|
|
7
29
|
*/
|
|
@@ -16,13 +38,19 @@ export type RenderOptions = {
|
|
|
16
38
|
* @example
|
|
17
39
|
* ```ts
|
|
18
40
|
* import Renderer from 'better-svelte-email/renderer';
|
|
19
|
-
* import EmailComponent from '
|
|
41
|
+
* import EmailComponent from '../emails/email.svelte';
|
|
42
|
+
* import layoutStyles from 'src/routes/layout.css?raw';
|
|
20
43
|
*
|
|
21
44
|
* const renderer = new Renderer({
|
|
22
|
-
* theme
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
45
|
+
* // Inject custom CSS such as app theme variables
|
|
46
|
+
* customCSS: layoutStyles,
|
|
47
|
+
* // Or provide a tailwind v3 config to extend the default theme
|
|
48
|
+
* tailwindConfig: {
|
|
49
|
+
* theme: {
|
|
50
|
+
* extend: {
|
|
51
|
+
* colors: {
|
|
52
|
+
* brand: '#FF3E00'
|
|
53
|
+
* }
|
|
26
54
|
* }
|
|
27
55
|
* }
|
|
28
56
|
* }
|
|
@@ -35,7 +63,9 @@ export type RenderOptions = {
|
|
|
35
63
|
*/
|
|
36
64
|
export default class Renderer {
|
|
37
65
|
private tailwindConfig;
|
|
66
|
+
private customCSS?;
|
|
38
67
|
constructor(tailwindConfig?: TailwindConfig);
|
|
68
|
+
constructor(options?: RendererOptions);
|
|
39
69
|
/**
|
|
40
70
|
* Renders a Svelte component to email-safe HTML with inlined Tailwind CSS.
|
|
41
71
|
*
|
package/dist/render/index.js
CHANGED
|
@@ -17,13 +17,19 @@ import { convert } from 'html-to-text';
|
|
|
17
17
|
* @example
|
|
18
18
|
* ```ts
|
|
19
19
|
* import Renderer from 'better-svelte-email/renderer';
|
|
20
|
-
* import EmailComponent from '
|
|
20
|
+
* import EmailComponent from '../emails/email.svelte';
|
|
21
|
+
* import layoutStyles from 'src/routes/layout.css?raw';
|
|
21
22
|
*
|
|
22
23
|
* const renderer = new Renderer({
|
|
23
|
-
* theme
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
24
|
+
* // Inject custom CSS such as app theme variables
|
|
25
|
+
* customCSS: layoutStyles,
|
|
26
|
+
* // Or provide a tailwind v3 config to extend the default theme
|
|
27
|
+
* tailwindConfig: {
|
|
28
|
+
* theme: {
|
|
29
|
+
* extend: {
|
|
30
|
+
* colors: {
|
|
31
|
+
* brand: '#FF3E00'
|
|
32
|
+
* }
|
|
27
33
|
* }
|
|
28
34
|
* }
|
|
29
35
|
* }
|
|
@@ -36,8 +42,22 @@ import { convert } from 'html-to-text';
|
|
|
36
42
|
*/
|
|
37
43
|
export default class Renderer {
|
|
38
44
|
tailwindConfig;
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
customCSS;
|
|
46
|
+
constructor(optionsOrConfig = {}) {
|
|
47
|
+
// Detect whether the argument is a bare TailwindConfig (old API)
|
|
48
|
+
// or a RendererOptions object (new API).
|
|
49
|
+
if (optionsOrConfig &&
|
|
50
|
+
typeof optionsOrConfig === 'object' &&
|
|
51
|
+
('tailwindConfig' in optionsOrConfig || 'customCSS' in optionsOrConfig)) {
|
|
52
|
+
const options = optionsOrConfig;
|
|
53
|
+
this.tailwindConfig = options.tailwindConfig || {};
|
|
54
|
+
this.customCSS = options.customCSS;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
const config = optionsOrConfig;
|
|
58
|
+
this.tailwindConfig = config || {};
|
|
59
|
+
this.customCSS = undefined;
|
|
60
|
+
}
|
|
41
61
|
}
|
|
42
62
|
/**
|
|
43
63
|
* Renders a Svelte component to email-safe HTML with inlined Tailwind CSS.
|
|
@@ -64,7 +84,7 @@ export default class Renderer {
|
|
|
64
84
|
let ast = parse(body);
|
|
65
85
|
ast = removeAttributesFunctions(ast);
|
|
66
86
|
let classesUsed = [];
|
|
67
|
-
const tailwindSetup = await setupTailwind(this.tailwindConfig);
|
|
87
|
+
const tailwindSetup = await setupTailwind(this.tailwindConfig, this.customCSS);
|
|
68
88
|
walk(ast, (node) => {
|
|
69
89
|
if (isValidNode(node)) {
|
|
70
90
|
const classAttr = node.attrs?.find((attr) => attr.name === 'class');
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import valueParser from 'postcss-value-parser';
|
|
2
|
+
const MAX_CSS_VARIABLE_RESOLUTION_ITERATIONS = 10;
|
|
2
3
|
function getSelector(decl) {
|
|
3
4
|
const parent = decl.parent;
|
|
4
5
|
if (parent?.type === 'rule') {
|
|
@@ -57,79 +58,108 @@ function doSelectorsIntersect(first, second) {
|
|
|
57
58
|
return false;
|
|
58
59
|
}
|
|
59
60
|
export function resolveAllCssVariables(root) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
//
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}
|
|
76
|
-
else if (decl.value.includes('var(')) {
|
|
77
|
-
const parseVariableUses = (value) => {
|
|
78
|
-
const parsed = valueParser(value);
|
|
79
|
-
parsed.walk((node) => {
|
|
80
|
-
if (node.type === 'function' && node.value === 'var') {
|
|
81
|
-
const varNameNode = node.nodes[0];
|
|
82
|
-
const varName = varNameNode ? valueParser.stringify(varNameNode).trim() : '';
|
|
83
|
-
// Find fallback (after the comma)
|
|
84
|
-
let fallback;
|
|
85
|
-
const commaIndex = node.nodes.findIndex((n) => n.type === 'div' && n.value === ',');
|
|
86
|
-
if (commaIndex !== -1) {
|
|
87
|
-
fallback = valueParser.stringify(node.nodes.slice(commaIndex + 1)).trim();
|
|
88
|
-
}
|
|
89
|
-
const raw = valueParser.stringify(node);
|
|
90
|
-
variableUses.push({
|
|
91
|
-
declaration: decl,
|
|
92
|
-
selector: getSelector(decl),
|
|
93
|
-
inAtRule: isInAtRule(decl),
|
|
94
|
-
atRuleSelector: getAtRuleSelector(decl),
|
|
95
|
-
fallback,
|
|
96
|
-
variableName: varName,
|
|
97
|
-
raw
|
|
98
|
-
});
|
|
99
|
-
// If fallback contains var(), recursively parse those too
|
|
100
|
-
if (fallback?.includes('var(')) {
|
|
101
|
-
parseVariableUses(fallback);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
61
|
+
let iteration = 0;
|
|
62
|
+
while (iteration < MAX_CSS_VARIABLE_RESOLUTION_ITERATIONS) {
|
|
63
|
+
const variableDefinitions = new Set();
|
|
64
|
+
const variableUses = [];
|
|
65
|
+
// First pass: collect variable definitions and uses
|
|
66
|
+
root.walkDecls((decl) => {
|
|
67
|
+
// Skip @layer (properties) { ... } to avoid variable resolution conflicts
|
|
68
|
+
if (isInPropertiesLayer(decl)) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (decl.prop.startsWith('--')) {
|
|
72
|
+
variableDefinitions.add({
|
|
73
|
+
declaration: decl,
|
|
74
|
+
selector: getSelector(decl),
|
|
75
|
+
variableName: decl.prop
|
|
104
76
|
});
|
|
105
|
-
};
|
|
106
|
-
parseVariableUses(decl.value);
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
// Second pass: resolve variables
|
|
110
|
-
for (const use of variableUses) {
|
|
111
|
-
let hasReplaced = false;
|
|
112
|
-
for (const definition of variableDefinitions) {
|
|
113
|
-
if (use.variableName !== definition.variableName) {
|
|
114
|
-
continue;
|
|
115
77
|
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
78
|
+
if (decl.value.includes('var(')) {
|
|
79
|
+
const parseVariableUses = (value) => {
|
|
80
|
+
const parsed = valueParser(value);
|
|
81
|
+
parsed.walk((node) => {
|
|
82
|
+
if (node.type === 'function' && node.value === 'var') {
|
|
83
|
+
const varNameNode = node.nodes[0];
|
|
84
|
+
const varName = varNameNode ? valueParser.stringify(varNameNode).trim() : '';
|
|
85
|
+
// Find fallback (after the comma)
|
|
86
|
+
let fallback;
|
|
87
|
+
const commaIndex = node.nodes.findIndex((n) => n.type === 'div' && n.value === ',');
|
|
88
|
+
if (commaIndex !== -1) {
|
|
89
|
+
fallback = valueParser.stringify(node.nodes.slice(commaIndex + 1)).trim();
|
|
90
|
+
}
|
|
91
|
+
const raw = valueParser.stringify(node);
|
|
92
|
+
variableUses.push({
|
|
93
|
+
declaration: decl,
|
|
94
|
+
selector: getSelector(decl),
|
|
95
|
+
inAtRule: isInAtRule(decl),
|
|
96
|
+
atRuleSelector: getAtRuleSelector(decl),
|
|
97
|
+
fallback,
|
|
98
|
+
variableName: varName,
|
|
99
|
+
raw
|
|
100
|
+
});
|
|
101
|
+
// If fallback contains var(), recursively parse those too
|
|
102
|
+
if (fallback?.includes('var(')) {
|
|
103
|
+
parseVariableUses(fallback);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
parseVariableUses(decl.value);
|
|
123
109
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
110
|
+
});
|
|
111
|
+
// Early exit: If no variable uses found, we're done
|
|
112
|
+
if (variableUses.length === 0) {
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
// Second pass: resolve variables
|
|
116
|
+
let replacedInThisIteration = false;
|
|
117
|
+
for (const use of variableUses) {
|
|
118
|
+
let hasReplaced = false;
|
|
119
|
+
for (const definition of variableDefinitions) {
|
|
120
|
+
if (use.variableName !== definition.variableName) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// Check if use is in an at-rule and definition is in a matching rule
|
|
124
|
+
if (use.inAtRule &&
|
|
125
|
+
use.atRuleSelector &&
|
|
126
|
+
doSelectorsIntersect(use.atRuleSelector, definition.selector)) {
|
|
127
|
+
use.declaration.value = use.declaration.value.replaceAll(use.raw, definition.declaration.value);
|
|
128
|
+
hasReplaced = true;
|
|
129
|
+
replacedInThisIteration = true;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
// Check if use is in a top-level at-rule (no atRuleSelector) and definition is in :root or universal
|
|
133
|
+
if (use.inAtRule &&
|
|
134
|
+
!use.atRuleSelector &&
|
|
135
|
+
(definition.selector.includes(':root') || definition.selector === '*')) {
|
|
136
|
+
use.declaration.value = use.declaration.value.replaceAll(use.raw, definition.declaration.value);
|
|
137
|
+
hasReplaced = true;
|
|
138
|
+
replacedInThisIteration = true;
|
|
139
|
+
break;
|
|
140
|
+
}
|
|
141
|
+
// Check if both are in rules with matching selectors
|
|
142
|
+
if (!use.inAtRule && doSelectorsIntersect(use.selector, definition.selector)) {
|
|
143
|
+
use.declaration.value = use.declaration.value.replaceAll(use.raw, definition.declaration.value);
|
|
144
|
+
hasReplaced = true;
|
|
145
|
+
replacedInThisIteration = true;
|
|
146
|
+
break;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
if (!hasReplaced && use.fallback) {
|
|
150
|
+
use.declaration.value = use.declaration.value.replaceAll(use.raw, use.fallback);
|
|
151
|
+
replacedInThisIteration = true;
|
|
129
152
|
}
|
|
130
153
|
}
|
|
131
|
-
|
|
132
|
-
|
|
154
|
+
// Early exit: If nothing was replaced, no point continuing
|
|
155
|
+
if (!replacedInThisIteration) {
|
|
156
|
+
break;
|
|
133
157
|
}
|
|
158
|
+
iteration++;
|
|
159
|
+
}
|
|
160
|
+
// Warning for circular references
|
|
161
|
+
if (iteration === MAX_CSS_VARIABLE_RESOLUTION_ITERATIONS) {
|
|
162
|
+
console.warn(`[better-svelte-email] CSS variable resolution hit maximum iterations (${MAX_CSS_VARIABLE_RESOLUTION_ITERATIONS}). ` +
|
|
163
|
+
`This may indicate circular variable references.`);
|
|
134
164
|
}
|
|
135
165
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sanitizeCustomCss(css: string): string;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import postcss from 'postcss';
|
|
2
|
+
export function sanitizeCustomCss(css) {
|
|
3
|
+
const root = postcss.parse(css);
|
|
4
|
+
root.walkAtRules((atRule) => {
|
|
5
|
+
if (atRule.name === 'import' || atRule.name === 'plugin') {
|
|
6
|
+
atRule.remove();
|
|
7
|
+
}
|
|
8
|
+
});
|
|
9
|
+
return root.toString();
|
|
10
|
+
}
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { type Root } from 'postcss';
|
|
2
2
|
import type { TailwindConfig } from '../../index.js';
|
|
3
3
|
export type TailwindSetup = Awaited<ReturnType<typeof setupTailwind>>;
|
|
4
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Set up Tailwind CSS compiler with optional custom CSS injection
|
|
6
|
+
* @param config - Tailwind configuration
|
|
7
|
+
* @param customCSS - Optional custom CSS string to inject (e.g., your theme CSS variables)
|
|
8
|
+
*/
|
|
9
|
+
export declare function setupTailwind(config: TailwindConfig, customCSS?: string): Promise<{
|
|
5
10
|
addUtilities: (candidates: string[]) => void;
|
|
6
11
|
getStyleSheet: () => Root;
|
|
7
12
|
}>;
|
|
@@ -4,11 +4,19 @@ import indexCss from './tailwind-stylesheets/index.js';
|
|
|
4
4
|
import preflightCss from './tailwind-stylesheets/preflight.js';
|
|
5
5
|
import themeCss from './tailwind-stylesheets/theme.js';
|
|
6
6
|
import utilitiesCss from './tailwind-stylesheets/utilities.js';
|
|
7
|
-
|
|
7
|
+
import { sanitizeCustomCss } from './sanitize-custom-css.js';
|
|
8
|
+
/**
|
|
9
|
+
* Set up Tailwind CSS compiler with optional custom CSS injection
|
|
10
|
+
* @param config - Tailwind configuration
|
|
11
|
+
* @param customCSS - Optional custom CSS string to inject (e.g., your theme CSS variables)
|
|
12
|
+
*/
|
|
13
|
+
export async function setupTailwind(config, customCSS) {
|
|
14
|
+
// Inject customCSS after base imports for theme variable resolution during compilation
|
|
8
15
|
const baseCss = `
|
|
9
16
|
@layer theme, base, components, utilities;
|
|
10
17
|
@import "tailwindcss/theme.css" layer(theme);
|
|
11
18
|
@import "tailwindcss/utilities.css" layer(utilities);
|
|
19
|
+
${customCSS ? sanitizeCustomCss(customCSS) : ''}
|
|
12
20
|
@config;
|
|
13
21
|
`;
|
|
14
22
|
const compiler = await compile(baseCss, {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "better-svelte-email",
|
|
3
3
|
"description": "Svelte email renderer with Tailwind support",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.2.0",
|
|
5
5
|
"author": "Konixy",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"@sveltejs/vite-plugin-svelte": "^6.2.1",
|
|
39
39
|
"@tailwindcss/vite": "^4.1.17",
|
|
40
40
|
"@types/html-to-text": "^9.0.4",
|
|
41
|
-
"@types/node": "
|
|
41
|
+
"@types/node": "22",
|
|
42
42
|
"@vitest/coverage-v8": "^4.0.14",
|
|
43
43
|
"eslint": "^9.39.1",
|
|
44
44
|
"eslint-config-prettier": "^10.1.8",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"publint": "^0.3.15",
|
|
52
52
|
"rehype-autolink-headings": "^7.1.0",
|
|
53
53
|
"rehype-slug": "^6.0.0",
|
|
54
|
-
"svelte": "5.
|
|
54
|
+
"svelte": "5.45.2",
|
|
55
55
|
"svelte-check": "^4.3.4",
|
|
56
56
|
"tailwindcss-motion": "^1.1.1",
|
|
57
57
|
"typescript": "^5.9.3",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"build": "bun run prepack && vite build",
|
|
120
120
|
"preview": "vite preview",
|
|
121
121
|
"package": "svelte-package",
|
|
122
|
-
"package:watch": "
|
|
122
|
+
"package:watch": "svelte-package --watch",
|
|
123
123
|
"prepare": "svelte-kit sync || echo ''",
|
|
124
124
|
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
125
125
|
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|