@better-svelte-email/server 2.1.1 → 2.1.3

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/index.cjs CHANGED
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
16
16
  }
17
17
  return to;
18
18
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
20
  value: mod,
21
21
  enumerable: true
22
22
  }) : target, mod));
@@ -2072,12 +2072,13 @@ function tokenizeCalcExpression(expr) {
2072
2072
  if (current.trim()) tokens.push(current.trim());
2073
2073
  tokens.push(char);
2074
2074
  current = "";
2075
- } else if (char === "+" || char === "-") if (current.trim() && !/[eE]$/.test(current.trim())) {
2076
- tokens.push(current.trim());
2077
- tokens.push(char);
2078
- current = "";
2079
- } else current += char;
2080
- else if (char === " ") {
2075
+ } else if (char === "+" || char === "-") {
2076
+ if (current.trim() && !/[eE]$/.test(current.trim())) {
2077
+ tokens.push(current.trim());
2078
+ tokens.push(char);
2079
+ current = "";
2080
+ } else current += char;
2081
+ } else if (char === " ") {
2081
2082
  if (current.trim()) {
2082
2083
  let nextNonSpace = i + 1;
2083
2084
  while (nextNonSpace < expr.length && expr[nextNonSpace] === " ") nextNonSpace++;
@@ -2127,15 +2128,18 @@ function evaluateCalcExpression(expr, baseFontSize) {
2127
2128
  } else if (left.type === "number" && right.type === "dimension") {
2128
2129
  resultUnit = right.unit;
2129
2130
  resultType = "dimension";
2130
- } else if (left.type === "dimension" && right.type === "dimension") if (token === "/") resultType = "number";
2131
- else {
2132
- resultUnit = left.unit;
2133
- resultType = "dimension";
2134
- }
2135
- else if (left.type === "percentage" || right.type === "percentage") if (token === "/" && left.type === "percentage" && right.type === "percentage") resultType = "number";
2136
- else {
2137
- resultUnit = "%";
2138
- resultType = "percentage";
2131
+ } else if (left.type === "dimension" && right.type === "dimension") {
2132
+ if (token === "/") resultType = "number";
2133
+ else {
2134
+ resultUnit = left.unit;
2135
+ resultType = "dimension";
2136
+ }
2137
+ } else if (left.type === "percentage" || right.type === "percentage") {
2138
+ if (token === "/" && left.type === "percentage" && right.type === "percentage") resultType = "number";
2139
+ else {
2140
+ resultUnit = "%";
2141
+ resultType = "percentage";
2142
+ }
2139
2143
  }
2140
2144
  const result = formatValue({
2141
2145
  value: resultValue,
@@ -2515,7 +2519,7 @@ function sanitizeStyleSheet(root, config) {
2515
2519
  }
2516
2520
  //#endregion
2517
2521
  //#region src/utils/css/is-rule-inlinable.ts
2518
- const NON_INLINABLE_AT_RULES = new Set([
2522
+ const NON_INLINABLE_AT_RULES = /* @__PURE__ */ new Set([
2519
2523
  "media",
2520
2524
  "supports",
2521
2525
  "container",
@@ -2655,7 +2659,7 @@ function extractGlobalRules(root) {
2655
2659
  * Checks if a rule is inside a media query or other non-inlinable at-rule.
2656
2660
  */
2657
2661
  function isRuleInMediaQuery(rule) {
2658
- const NON_INLINABLE_AT_RULES = new Set([
2662
+ const NON_INLINABLE_AT_RULES = /* @__PURE__ */ new Set([
2659
2663
  "media",
2660
2664
  "supports",
2661
2665
  "container",
@@ -2738,6 +2742,45 @@ function sanitizeNonInlinableRules(root) {
2738
2742
  });
2739
2743
  }
2740
2744
  //#endregion
2745
+ //#region src/utils/css/clone-rule-with-at-rule-ancestors.ts
2746
+ /**
2747
+ * At-rules that wrap utility rules and must be preserved when extracting
2748
+ * non-inlinable CSS for the email <style> tag.
2749
+ *
2750
+ * Tailwind v4.3.3+ flattens nesting so media/supports wrap the selector
2751
+ * instead of nesting inside it. Cloning the rule alone would drop them.
2752
+ */
2753
+ const PRESERVED_AT_RULES = /* @__PURE__ */ new Set([
2754
+ "media",
2755
+ "supports",
2756
+ "container",
2757
+ "document"
2758
+ ]);
2759
+ /**
2760
+ * Clone a PostCSS rule, re-wrapping it with any ancestor conditional at-rules
2761
+ * (`@media`, `@supports`, `@container`, `@document`).
2762
+ *
2763
+ * `@layer` and other grouping at-rules are skipped.
2764
+ */
2765
+ function cloneRuleWithAtRuleAncestors(rule) {
2766
+ let current = rule.clone();
2767
+ const ancestors = [];
2768
+ let parent = rule.parent;
2769
+ while (parent && parent.type !== "root") {
2770
+ if (parent.type === "atrule") {
2771
+ const atRule = parent;
2772
+ if (PRESERVED_AT_RULES.has(atRule.name)) ancestors.push(atRule);
2773
+ }
2774
+ parent = parent.parent;
2775
+ }
2776
+ for (const atRule of ancestors) {
2777
+ const wrapper = atRule.clone({ nodes: [] });
2778
+ wrapper.append(current);
2779
+ current = wrapper;
2780
+ }
2781
+ return current;
2782
+ }
2783
+ //#endregion
2741
2784
  //#region src/utils/css/make-inline-styles-for.ts
2742
2785
  function makeInlineStylesFor(inlinableRules, customProperties) {
2743
2786
  let styles = "";
@@ -2839,17 +2882,19 @@ function addInlinedStylesToElement(element, inlinableRules, nonInlinableRules, c
2839
2882
  else residualClasses.push(className);
2840
2883
  }
2841
2884
  const newStyles = combineStyles(globalStyles, existingStyles, makeInlineStylesFor(rules, customProperties));
2842
- if (newStyles) if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2843
- if (attr.name === "style") return {
2844
- ...attr,
2885
+ if (newStyles) {
2886
+ if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2887
+ if (attr.name === "style") return {
2888
+ ...attr,
2889
+ value: newStyles
2890
+ };
2891
+ return attr;
2892
+ });
2893
+ else element.attrs = [...element.attrs, {
2894
+ name: "style",
2845
2895
  value: newStyles
2846
- };
2847
- return attr;
2848
- });
2849
- else element.attrs = [...element.attrs, {
2850
- name: "style",
2851
- value: newStyles
2852
- }];
2896
+ }];
2897
+ }
2853
2898
  if (residualClasses.length > 0) element.attrs = element.attrs?.map((attr) => {
2854
2899
  if (attr.name === "class") return {
2855
2900
  ...attr,
@@ -2866,17 +2911,19 @@ function addInlinedStylesToElement(element, inlinableRules, nonInlinableRules, c
2866
2911
  else element.attrs = element.attrs?.filter((attr) => attr.name !== "class");
2867
2912
  } else if (globalStyles) {
2868
2913
  const newStyles = combineStyles(globalStyles, existingStyles);
2869
- if (newStyles) if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2870
- if (attr.name === "style") return {
2871
- ...attr,
2914
+ if (newStyles) {
2915
+ if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2916
+ if (attr.name === "style") return {
2917
+ ...attr,
2918
+ value: newStyles
2919
+ };
2920
+ return attr;
2921
+ });
2922
+ else element.attrs = [...element.attrs || [], {
2923
+ name: "style",
2872
2924
  value: newStyles
2873
- };
2874
- return attr;
2875
- });
2876
- else element.attrs = [...element.attrs || [], {
2877
- name: "style",
2878
- value: newStyles
2879
- }];
2925
+ }];
2926
+ }
2880
2927
  }
2881
2928
  return element;
2882
2929
  }
@@ -3011,7 +3058,7 @@ var Renderer = class {
3011
3058
  const { inlinable: inlinableRules, nonInlinable: nonInlinableRules } = extractRulesPerClass(styleSheet, classesUsed);
3012
3059
  const customProperties = getCustomProperties(styleSheet);
3013
3060
  const nonInlineStyles = postcss.default.root();
3014
- for (const rule of nonInlinableRules.values()) nonInlineStyles.append(rule.clone());
3061
+ for (const rule of nonInlinableRules.values()) nonInlineStyles.append(cloneRuleWithAtRuleAncestors(rule));
3015
3062
  sanitizeNonInlinableRules(nonInlineStyles);
3016
3063
  const hasNonInlineStylesToApply = nonInlinableRules.size > 0;
3017
3064
  let appliedNonInlineStyles = false;
package/dist/index.d.cts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { DefaultTreeAdapterTypes } from "parse5";
2
2
  import { Config } from "tailwindcss";
3
-
4
3
  //#region src/utils/tailwindcss/pixel-based-preset.d.ts
5
4
  declare const pixelBasedPreset: TailwindConfig;
6
5
  //#endregion
@@ -10,7 +9,8 @@ type TailwindConfig = Omit<Config, 'content'>;
10
9
  * Options for creating a Renderer instance
11
10
  */
12
11
  type RendererOptions = {
13
- /** Tailwind CSS configuration */tailwindConfig?: TailwindConfig;
12
+ /** Tailwind CSS configuration */
13
+ tailwindConfig?: TailwindConfig;
14
14
  /**
15
15
  * Custom CSS to inject into email rendering (e.g., app theme variables).
16
16
  *
package/dist/index.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { DefaultTreeAdapterTypes } from "parse5";
2
2
  import { Config } from "tailwindcss";
3
-
4
3
  //#region src/utils/tailwindcss/pixel-based-preset.d.ts
5
4
  declare const pixelBasedPreset: TailwindConfig;
6
5
  //#endregion
@@ -10,7 +9,8 @@ type TailwindConfig = Omit<Config, 'content'>;
10
9
  * Options for creating a Renderer instance
11
10
  */
12
11
  type RendererOptions = {
13
- /** Tailwind CSS configuration */tailwindConfig?: TailwindConfig;
12
+ /** Tailwind CSS configuration */
13
+ tailwindConfig?: TailwindConfig;
14
14
  /**
15
15
  * Custom CSS to inject into email rendering (e.g., app theme variables).
16
16
  *
package/dist/index.mjs CHANGED
@@ -2047,12 +2047,13 @@ function tokenizeCalcExpression(expr) {
2047
2047
  if (current.trim()) tokens.push(current.trim());
2048
2048
  tokens.push(char);
2049
2049
  current = "";
2050
- } else if (char === "+" || char === "-") if (current.trim() && !/[eE]$/.test(current.trim())) {
2051
- tokens.push(current.trim());
2052
- tokens.push(char);
2053
- current = "";
2054
- } else current += char;
2055
- else if (char === " ") {
2050
+ } else if (char === "+" || char === "-") {
2051
+ if (current.trim() && !/[eE]$/.test(current.trim())) {
2052
+ tokens.push(current.trim());
2053
+ tokens.push(char);
2054
+ current = "";
2055
+ } else current += char;
2056
+ } else if (char === " ") {
2056
2057
  if (current.trim()) {
2057
2058
  let nextNonSpace = i + 1;
2058
2059
  while (nextNonSpace < expr.length && expr[nextNonSpace] === " ") nextNonSpace++;
@@ -2102,15 +2103,18 @@ function evaluateCalcExpression(expr, baseFontSize) {
2102
2103
  } else if (left.type === "number" && right.type === "dimension") {
2103
2104
  resultUnit = right.unit;
2104
2105
  resultType = "dimension";
2105
- } else if (left.type === "dimension" && right.type === "dimension") if (token === "/") resultType = "number";
2106
- else {
2107
- resultUnit = left.unit;
2108
- resultType = "dimension";
2109
- }
2110
- else if (left.type === "percentage" || right.type === "percentage") if (token === "/" && left.type === "percentage" && right.type === "percentage") resultType = "number";
2111
- else {
2112
- resultUnit = "%";
2113
- resultType = "percentage";
2106
+ } else if (left.type === "dimension" && right.type === "dimension") {
2107
+ if (token === "/") resultType = "number";
2108
+ else {
2109
+ resultUnit = left.unit;
2110
+ resultType = "dimension";
2111
+ }
2112
+ } else if (left.type === "percentage" || right.type === "percentage") {
2113
+ if (token === "/" && left.type === "percentage" && right.type === "percentage") resultType = "number";
2114
+ else {
2115
+ resultUnit = "%";
2116
+ resultType = "percentage";
2117
+ }
2114
2118
  }
2115
2119
  const result = formatValue({
2116
2120
  value: resultValue,
@@ -2490,7 +2494,7 @@ function sanitizeStyleSheet(root, config) {
2490
2494
  }
2491
2495
  //#endregion
2492
2496
  //#region src/utils/css/is-rule-inlinable.ts
2493
- const NON_INLINABLE_AT_RULES = new Set([
2497
+ const NON_INLINABLE_AT_RULES = /* @__PURE__ */ new Set([
2494
2498
  "media",
2495
2499
  "supports",
2496
2500
  "container",
@@ -2630,7 +2634,7 @@ function extractGlobalRules(root) {
2630
2634
  * Checks if a rule is inside a media query or other non-inlinable at-rule.
2631
2635
  */
2632
2636
  function isRuleInMediaQuery(rule) {
2633
- const NON_INLINABLE_AT_RULES = new Set([
2637
+ const NON_INLINABLE_AT_RULES = /* @__PURE__ */ new Set([
2634
2638
  "media",
2635
2639
  "supports",
2636
2640
  "container",
@@ -2713,6 +2717,45 @@ function sanitizeNonInlinableRules(root) {
2713
2717
  });
2714
2718
  }
2715
2719
  //#endregion
2720
+ //#region src/utils/css/clone-rule-with-at-rule-ancestors.ts
2721
+ /**
2722
+ * At-rules that wrap utility rules and must be preserved when extracting
2723
+ * non-inlinable CSS for the email <style> tag.
2724
+ *
2725
+ * Tailwind v4.3.3+ flattens nesting so media/supports wrap the selector
2726
+ * instead of nesting inside it. Cloning the rule alone would drop them.
2727
+ */
2728
+ const PRESERVED_AT_RULES = /* @__PURE__ */ new Set([
2729
+ "media",
2730
+ "supports",
2731
+ "container",
2732
+ "document"
2733
+ ]);
2734
+ /**
2735
+ * Clone a PostCSS rule, re-wrapping it with any ancestor conditional at-rules
2736
+ * (`@media`, `@supports`, `@container`, `@document`).
2737
+ *
2738
+ * `@layer` and other grouping at-rules are skipped.
2739
+ */
2740
+ function cloneRuleWithAtRuleAncestors(rule) {
2741
+ let current = rule.clone();
2742
+ const ancestors = [];
2743
+ let parent = rule.parent;
2744
+ while (parent && parent.type !== "root") {
2745
+ if (parent.type === "atrule") {
2746
+ const atRule = parent;
2747
+ if (PRESERVED_AT_RULES.has(atRule.name)) ancestors.push(atRule);
2748
+ }
2749
+ parent = parent.parent;
2750
+ }
2751
+ for (const atRule of ancestors) {
2752
+ const wrapper = atRule.clone({ nodes: [] });
2753
+ wrapper.append(current);
2754
+ current = wrapper;
2755
+ }
2756
+ return current;
2757
+ }
2758
+ //#endregion
2716
2759
  //#region src/utils/css/make-inline-styles-for.ts
2717
2760
  function makeInlineStylesFor(inlinableRules, customProperties) {
2718
2761
  let styles = "";
@@ -2814,17 +2857,19 @@ function addInlinedStylesToElement(element, inlinableRules, nonInlinableRules, c
2814
2857
  else residualClasses.push(className);
2815
2858
  }
2816
2859
  const newStyles = combineStyles(globalStyles, existingStyles, makeInlineStylesFor(rules, customProperties));
2817
- if (newStyles) if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2818
- if (attr.name === "style") return {
2819
- ...attr,
2860
+ if (newStyles) {
2861
+ if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2862
+ if (attr.name === "style") return {
2863
+ ...attr,
2864
+ value: newStyles
2865
+ };
2866
+ return attr;
2867
+ });
2868
+ else element.attrs = [...element.attrs, {
2869
+ name: "style",
2820
2870
  value: newStyles
2821
- };
2822
- return attr;
2823
- });
2824
- else element.attrs = [...element.attrs, {
2825
- name: "style",
2826
- value: newStyles
2827
- }];
2871
+ }];
2872
+ }
2828
2873
  if (residualClasses.length > 0) element.attrs = element.attrs?.map((attr) => {
2829
2874
  if (attr.name === "class") return {
2830
2875
  ...attr,
@@ -2841,17 +2886,19 @@ function addInlinedStylesToElement(element, inlinableRules, nonInlinableRules, c
2841
2886
  else element.attrs = element.attrs?.filter((attr) => attr.name !== "class");
2842
2887
  } else if (globalStyles) {
2843
2888
  const newStyles = combineStyles(globalStyles, existingStyles);
2844
- if (newStyles) if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2845
- if (attr.name === "style") return {
2846
- ...attr,
2889
+ if (newStyles) {
2890
+ if (styleAttr) element.attrs = element.attrs?.map((attr) => {
2891
+ if (attr.name === "style") return {
2892
+ ...attr,
2893
+ value: newStyles
2894
+ };
2895
+ return attr;
2896
+ });
2897
+ else element.attrs = [...element.attrs || [], {
2898
+ name: "style",
2847
2899
  value: newStyles
2848
- };
2849
- return attr;
2850
- });
2851
- else element.attrs = [...element.attrs || [], {
2852
- name: "style",
2853
- value: newStyles
2854
- }];
2900
+ }];
2901
+ }
2855
2902
  }
2856
2903
  return element;
2857
2904
  }
@@ -2986,7 +3033,7 @@ var Renderer = class {
2986
3033
  const { inlinable: inlinableRules, nonInlinable: nonInlinableRules } = extractRulesPerClass(styleSheet, classesUsed);
2987
3034
  const customProperties = getCustomProperties(styleSheet);
2988
3035
  const nonInlineStyles = postcss.root();
2989
- for (const rule of nonInlinableRules.values()) nonInlineStyles.append(rule.clone());
3036
+ for (const rule of nonInlinableRules.values()) nonInlineStyles.append(cloneRuleWithAtRuleAncestors(rule));
2990
3037
  sanitizeNonInlinableRules(nonInlineStyles);
2991
3038
  const hasNonInlineStylesToApply = nonInlinableRules.size > 0;
2992
3039
  let appliedNonInlineStyles = false;
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@better-svelte-email/server",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./dist/index.mjs",
6
6
  "dependencies": {
7
7
  "html-to-text": "^10.0.0",
8
8
  "parse5": "^8.0.1",
9
- "postcss": "^8.5.15",
9
+ "postcss": "^8.5.26",
10
10
  "postcss-value-parser": "^4.2.0",
11
- "tailwindcss": "^4.3.0"
11
+ "tailwindcss": "^4.3.3"
12
12
  },
13
13
  "peerDependencies": {
14
14
  "svelte": ">=5.14.3"