@emailshepherd/cli 0.2.0 → 0.2.2

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/cli.js CHANGED
@@ -8,7 +8,7 @@ import updateNotifier from "update-notifier";
8
8
  // package.json
9
9
  var package_default = {
10
10
  name: "@emailshepherd/cli",
11
- version: "0.2.0",
11
+ version: "0.2.2",
12
12
  type: "module",
13
13
  publishConfig: {
14
14
  registry: "https://registry.npmjs.org",
@@ -27,7 +27,10 @@ var package_default = {
27
27
  "dist"
28
28
  ],
29
29
  scripts: {
30
- build: "tsup && cp -r src/templates dist/",
30
+ typecheck: "tsc",
31
+ "build:cli": "tsup",
32
+ "build:dev-ui": "vite build",
33
+ build: "pnpm run typecheck && pnpm run build:cli && pnpm run build:dev-ui && cp -r src/templates dist/",
31
34
  test: "vitest run",
32
35
  "test:watch": "vitest",
33
36
  prepublishOnly: "pnpm run build"
@@ -37,12 +40,14 @@ var package_default = {
37
40
  chokidar: "^4.0.3",
38
41
  commander: "^14.0.2",
39
42
  dotenv: "^17.2.3",
43
+ preact: "^10.28.1",
40
44
  "update-notifier": "^7.3.1",
41
45
  vite: "^7.2.6",
42
46
  "vite-plugin-checker": "^0.12.0"
43
47
  },
44
48
  devDependencies: {
45
49
  "@emailshepherd/api-client": "workspace:*",
50
+ "@preact/preset-vite": "^2.10.2",
46
51
  "@types/node": "^24.10.1",
47
52
  "@types/update-notifier": "^6.0.8",
48
53
  msw: "^2.12.7",
@@ -83,10 +88,41 @@ function configureAxios(config) {
83
88
 
84
89
  // src/buildHtml.ts
85
90
  import { AxiosError } from "axios";
86
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
91
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
87
92
  import { dirname, resolve } from "path";
88
93
  import { fileURLToPath } from "url";
89
94
  import { createServer } from "vite";
95
+
96
+ // src/env.ts
97
+ function getEDSEnvConfig() {
98
+ const workspaceIdStr = process.env.EMAILSHEPHERD_WORKSPACE_ID;
99
+ const edsIdStr = process.env.EMAILSHEPHERD_EDS_ID;
100
+ if (!workspaceIdStr) {
101
+ throw new Error(
102
+ "Missing EMAILSHEPHERD_WORKSPACE_ID environment variable. Set it in your .env file or provide it via the environment."
103
+ );
104
+ }
105
+ if (!edsIdStr) {
106
+ throw new Error(
107
+ "Missing EMAILSHEPHERD_EDS_ID environment variable. Set it in your .env file or provide it via the environment."
108
+ );
109
+ }
110
+ const workspaceId = parseInt(workspaceIdStr, 10);
111
+ const edsId = parseInt(edsIdStr, 10);
112
+ if (isNaN(workspaceId)) {
113
+ throw new Error(
114
+ `Invalid EMAILSHEPHERD_WORKSPACE_ID: "${workspaceIdStr}" is not a valid number.`
115
+ );
116
+ }
117
+ if (isNaN(edsId)) {
118
+ throw new Error(
119
+ `Invalid EMAILSHEPHERD_EDS_ID: "${edsIdStr}" is not a valid number.`
120
+ );
121
+ }
122
+ return { workspaceId, edsId };
123
+ }
124
+
125
+ // src/buildHtml.ts
90
126
  var __dirname = dirname(fileURLToPath(import.meta.url));
91
127
  var viteServer = null;
92
128
  async function getViteServer() {
@@ -183,16 +219,19 @@ function writeDevWrapper() {
183
219
  const templatePath = resolve(__dirname, "templates", "devWrapper.html");
184
220
  const devWrapperHtml = readFileSync(templatePath, "utf-8");
185
221
  writeFileSync(resolve(distDir, "index.html"), devWrapperHtml);
222
+ const devUiPath = resolve(__dirname, "dev-ui", "dev-ui.js");
223
+ copyFileSync(devUiPath, resolve(distDir, "dev-ui.js"));
186
224
  }
187
225
  async function buildHtml() {
188
226
  configureAxios();
189
227
  let html;
190
228
  try {
229
+ const { workspaceId, edsId } = getEDSEnvConfig();
191
230
  const eds = await loadEDS();
192
231
  const objectRepresentation = await buildEmailDesignSystemObject(eds);
193
232
  const response = await renderEmailDesignSystem(
194
- eds.workspace_id,
195
- eds.email_design_system_id,
233
+ workspaceId,
234
+ edsId,
196
235
  objectRepresentation
197
236
  );
198
237
  if (response.data.html) {
@@ -276,11 +315,12 @@ function registerValidateCommand(program2) {
276
315
  process.exit(1);
277
316
  }
278
317
  configureAxios();
318
+ const { workspaceId, edsId } = getEDSEnvConfig();
279
319
  const eds = await loadEDS2();
280
320
  const objectRepresentation = await buildEmailDesignSystemObject(eds);
281
321
  const response = await renderEmailDesignSystem(
282
- eds.workspace_id,
283
- eds.email_design_system_id,
322
+ workspaceId,
323
+ edsId,
284
324
  objectRepresentation
285
325
  );
286
326
  await closeViteServer2();
@@ -318,11 +358,12 @@ function registerDeployCommand(program2) {
318
358
  process.exit(1);
319
359
  }
320
360
  configureAxios();
361
+ const { workspaceId, edsId } = getEDSEnvConfig();
321
362
  const eds = await loadEDS2();
322
363
  console.log("Deploying Email Design System...");
323
364
  const edsResponse = await syncEmailDesignSystem(
324
- eds.workspace_id,
325
- eds.email_design_system_id,
365
+ workspaceId,
366
+ edsId,
326
367
  {
327
368
  email_design_system: {
328
369
  name: eds.eds_metadata.name,
@@ -414,12 +455,13 @@ function applyOverrides(eds, overrides) {
414
455
  }
415
456
  async function renderWithOverrides(overrides) {
416
457
  configureAxios();
458
+ const { workspaceId, edsId } = getEDSEnvConfig();
417
459
  const eds = await loadEDS();
418
460
  const modifiedEds = applyOverrides(eds, overrides);
419
461
  const objectRepresentation = await buildEmailDesignSystemObject(modifiedEds);
420
462
  const response = await renderEmailDesignSystem(
421
- modifiedEds.workspace_id,
422
- modifiedEds.email_design_system_id,
463
+ workspaceId,
464
+ edsId,
423
465
  objectRepresentation
424
466
  );
425
467
  if (response.data.html) {
@@ -0,0 +1,511 @@
1
+ var B, d, me, x, re, ye, ge, be, X, J, Y, F = {}, ke = [], Ae = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i, O = Array.isArray;
2
+ function C(e, _) {
3
+ for (var t in _) e[t] = _[t];
4
+ return e;
5
+ }
6
+ function Z(e) {
7
+ e && e.parentNode && e.parentNode.removeChild(e);
8
+ }
9
+ function Fe(e, _, t) {
10
+ var n, l, r, i = {};
11
+ for (r in _) r == "key" ? n = _[r] : r == "ref" ? l = _[r] : i[r] = _[r];
12
+ if (arguments.length > 2 && (i.children = arguments.length > 3 ? B.call(arguments, 2) : t), typeof e == "function" && e.defaultProps != null) for (r in e.defaultProps) i[r] === void 0 && (i[r] = e.defaultProps[r]);
13
+ return L(e, i, n, l, null);
14
+ }
15
+ function L(e, _, t, n, l) {
16
+ var r = { type: e, props: _, key: t, ref: n, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: l ?? ++me, __i: -1, __u: 0 };
17
+ return l == null && d.vnode != null && d.vnode(r), r;
18
+ }
19
+ function V(e) {
20
+ return e.children;
21
+ }
22
+ function W(e, _) {
23
+ this.props = e, this.context = _;
24
+ }
25
+ function T(e, _) {
26
+ if (_ == null) return e.__ ? T(e.__, e.__i + 1) : null;
27
+ for (var t; _ < e.__k.length; _++) if ((t = e.__k[_]) != null && t.__e != null) return t.__e;
28
+ return typeof e.type == "function" ? T(e) : null;
29
+ }
30
+ function we(e) {
31
+ var _, t;
32
+ if ((e = e.__) != null && e.__c != null) {
33
+ for (e.__e = e.__c.base = null, _ = 0; _ < e.__k.length; _++) if ((t = e.__k[_]) != null && t.__e != null) {
34
+ e.__e = e.__c.base = t.__e;
35
+ break;
36
+ }
37
+ return we(e);
38
+ }
39
+ }
40
+ function oe(e) {
41
+ (!e.__d && (e.__d = !0) && x.push(e) && !j.__r++ || re != d.debounceRendering) && ((re = d.debounceRendering) || ye)(j);
42
+ }
43
+ function j() {
44
+ for (var e, _, t, n, l, r, i, s = 1; x.length; ) x.length > s && x.sort(ge), e = x.shift(), s = x.length, e.__d && (t = void 0, n = void 0, l = (n = (_ = e).__v).__e, r = [], i = [], _.__P && ((t = C({}, n)).__v = n.__v + 1, d.vnode && d.vnode(t), ee(_.__P, t, n, _.__n, _.__P.namespaceURI, 32 & n.__u ? [l] : null, r, l ?? T(n), !!(32 & n.__u), i), t.__v = n.__v, t.__.__k[t.__i] = t, He(r, t, i), n.__e = n.__ = null, t.__e != l && we(t)));
45
+ j.__r = 0;
46
+ }
47
+ function $e(e, _, t, n, l, r, i, s, f, c, p) {
48
+ var o, a, u, y, w, g, m, v = n && n.__k || ke, H = _.length;
49
+ for (f = Ne(t, _, v, f, H), o = 0; o < H; o++) (u = t.__k[o]) != null && (a = u.__i == -1 ? F : v[u.__i] || F, u.__i = o, g = ee(e, u, a, l, r, i, s, f, c, p), y = u.__e, u.ref && a.ref != u.ref && (a.ref && _e(a.ref, null, u), p.push(u.ref, u.__c || y, u)), w == null && y != null && (w = y), (m = !!(4 & u.__u)) || a.__k === u.__k ? f = Ce(u, f, e, m) : typeof u.type == "function" && g !== void 0 ? f = g : y && (f = y.nextSibling), u.__u &= -7);
50
+ return t.__e = w, f;
51
+ }
52
+ function Ne(e, _, t, n, l) {
53
+ var r, i, s, f, c, p = t.length, o = p, a = 0;
54
+ for (e.__k = new Array(l), r = 0; r < l; r++) (i = _[r]) != null && typeof i != "boolean" && typeof i != "function" ? (typeof i == "string" || typeof i == "number" || typeof i == "bigint" || i.constructor == String ? i = e.__k[r] = L(null, i, null, null, null) : O(i) ? i = e.__k[r] = L(V, { children: i }, null, null, null) : i.constructor == null && i.__b > 0 ? i = e.__k[r] = L(i.type, i.props, i.key, i.ref ? i.ref : null, i.__v) : e.__k[r] = i, f = r + a, i.__ = e, i.__b = e.__b + 1, s = null, (c = i.__i = Ue(i, t, f, o)) != -1 && (o--, (s = t[c]) && (s.__u |= 2)), s == null || s.__v == null ? (c == -1 && (l > p ? a-- : l < p && a++), typeof i.type != "function" && (i.__u |= 4)) : c != f && (c == f - 1 ? a-- : c == f + 1 ? a++ : (c > f ? a-- : a++, i.__u |= 4))) : e.__k[r] = null;
55
+ if (o) for (r = 0; r < p; r++) (s = t[r]) != null && (2 & s.__u) == 0 && (s.__e == n && (n = T(s)), xe(s, s));
56
+ return n;
57
+ }
58
+ function Ce(e, _, t, n) {
59
+ var l, r;
60
+ if (typeof e.type == "function") {
61
+ for (l = e.__k, r = 0; l && r < l.length; r++) l[r] && (l[r].__ = e, _ = Ce(l[r], _, t, n));
62
+ return _;
63
+ }
64
+ e.__e != _ && (n && (_ && e.type && !_.parentNode && (_ = T(e)), t.insertBefore(e.__e, _ || null)), _ = e.__e);
65
+ do
66
+ _ = _ && _.nextSibling;
67
+ while (_ != null && _.nodeType == 8);
68
+ return _;
69
+ }
70
+ function Ue(e, _, t, n) {
71
+ var l, r, i, s = e.key, f = e.type, c = _[t], p = c != null && (2 & c.__u) == 0;
72
+ if (c === null && s == null || p && s == c.key && f == c.type) return t;
73
+ if (n > (p ? 1 : 0)) {
74
+ for (l = t - 1, r = t + 1; l >= 0 || r < _.length; ) if ((c = _[i = l >= 0 ? l-- : r++]) != null && (2 & c.__u) == 0 && s == c.key && f == c.type) return i;
75
+ }
76
+ return -1;
77
+ }
78
+ function le(e, _, t) {
79
+ _[0] == "-" ? e.setProperty(_, t ?? "") : e[_] = t == null ? "" : typeof t != "number" || Ae.test(_) ? t : t + "px";
80
+ }
81
+ function D(e, _, t, n, l) {
82
+ var r, i;
83
+ e: if (_ == "style") if (typeof t == "string") e.style.cssText = t;
84
+ else {
85
+ if (typeof n == "string" && (e.style.cssText = n = ""), n) for (_ in n) t && _ in t || le(e.style, _, "");
86
+ if (t) for (_ in t) n && t[_] == n[_] || le(e.style, _, t[_]);
87
+ }
88
+ else if (_[0] == "o" && _[1] == "n") r = _ != (_ = _.replace(be, "$1")), i = _.toLowerCase(), _ = i in e || _ == "onFocusOut" || _ == "onFocusIn" ? i.slice(2) : _.slice(2), e.l || (e.l = {}), e.l[_ + r] = t, t ? n ? t.u = n.u : (t.u = X, e.addEventListener(_, r ? Y : J, r)) : e.removeEventListener(_, r ? Y : J, r);
89
+ else {
90
+ if (l == "http://www.w3.org/2000/svg") _ = _.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s");
91
+ else if (_ != "width" && _ != "height" && _ != "href" && _ != "list" && _ != "form" && _ != "tabIndex" && _ != "download" && _ != "rowSpan" && _ != "colSpan" && _ != "role" && _ != "popover" && _ in e) try {
92
+ e[_] = t ?? "";
93
+ break e;
94
+ } catch {
95
+ }
96
+ typeof t == "function" || (t == null || t === !1 && _[4] != "-" ? e.removeAttribute(_) : e.setAttribute(_, _ == "popover" && t == 1 ? "" : t));
97
+ }
98
+ }
99
+ function ie(e) {
100
+ return function(_) {
101
+ if (this.l) {
102
+ var t = this.l[_.type + e];
103
+ if (_.t == null) _.t = X++;
104
+ else if (_.t < t.u) return;
105
+ return t(d.event ? d.event(_) : _);
106
+ }
107
+ };
108
+ }
109
+ function ee(e, _, t, n, l, r, i, s, f, c) {
110
+ var p, o, a, u, y, w, g, m, v, H, S, U, E, ne, M, A, z, $ = _.type;
111
+ if (_.constructor != null) return null;
112
+ 128 & t.__u && (f = !!(32 & t.__u), r = [s = _.__e = t.__e]), (p = d.__b) && p(_);
113
+ e: if (typeof $ == "function") try {
114
+ if (m = _.props, v = "prototype" in $ && $.prototype.render, H = (p = $.contextType) && n[p.__c], S = p ? H ? H.props.value : p.__ : n, t.__c ? g = (o = _.__c = t.__c).__ = o.__E : (v ? _.__c = o = new $(m, S) : (_.__c = o = new W(m, S), o.constructor = $, o.render = De), H && H.sub(o), o.state || (o.state = {}), o.__n = n, a = o.__d = !0, o.__h = [], o._sb = []), v && o.__s == null && (o.__s = o.state), v && $.getDerivedStateFromProps != null && (o.__s == o.state && (o.__s = C({}, o.__s)), C(o.__s, $.getDerivedStateFromProps(m, o.__s))), u = o.props, y = o.state, o.__v = _, a) v && $.getDerivedStateFromProps == null && o.componentWillMount != null && o.componentWillMount(), v && o.componentDidMount != null && o.__h.push(o.componentDidMount);
115
+ else {
116
+ if (v && $.getDerivedStateFromProps == null && m !== u && o.componentWillReceiveProps != null && o.componentWillReceiveProps(m, S), _.__v == t.__v || !o.__e && o.shouldComponentUpdate != null && o.shouldComponentUpdate(m, o.__s, S) === !1) {
117
+ for (_.__v != t.__v && (o.props = m, o.state = o.__s, o.__d = !1), _.__e = t.__e, _.__k = t.__k, _.__k.some(function(P) {
118
+ P && (P.__ = _);
119
+ }), U = 0; U < o._sb.length; U++) o.__h.push(o._sb[U]);
120
+ o._sb = [], o.__h.length && i.push(o);
121
+ break e;
122
+ }
123
+ o.componentWillUpdate != null && o.componentWillUpdate(m, o.__s, S), v && o.componentDidUpdate != null && o.__h.push(function() {
124
+ o.componentDidUpdate(u, y, w);
125
+ });
126
+ }
127
+ if (o.context = S, o.props = m, o.__P = e, o.__e = !1, E = d.__r, ne = 0, v) {
128
+ for (o.state = o.__s, o.__d = !1, E && E(_), p = o.render(o.props, o.state, o.context), M = 0; M < o._sb.length; M++) o.__h.push(o._sb[M]);
129
+ o._sb = [];
130
+ } else do
131
+ o.__d = !1, E && E(_), p = o.render(o.props, o.state, o.context), o.state = o.__s;
132
+ while (o.__d && ++ne < 25);
133
+ o.state = o.__s, o.getChildContext != null && (n = C(C({}, n), o.getChildContext())), v && !a && o.getSnapshotBeforeUpdate != null && (w = o.getSnapshotBeforeUpdate(u, y)), A = p, p != null && p.type === V && p.key == null && (A = Se(p.props.children)), s = $e(e, O(A) ? A : [A], _, t, n, l, r, i, s, f, c), o.base = _.__e, _.__u &= -161, o.__h.length && i.push(o), g && (o.__E = o.__ = null);
134
+ } catch (P) {
135
+ if (_.__v = null, f || r != null) if (P.then) {
136
+ for (_.__u |= f ? 160 : 128; s && s.nodeType == 8 && s.nextSibling; ) s = s.nextSibling;
137
+ r[r.indexOf(s)] = null, _.__e = s;
138
+ } else {
139
+ for (z = r.length; z--; ) Z(r[z]);
140
+ K(_);
141
+ }
142
+ else _.__e = t.__e, _.__k = t.__k, P.then || K(_);
143
+ d.__e(P, _, t);
144
+ }
145
+ else r == null && _.__v == t.__v ? (_.__k = t.__k, _.__e = t.__e) : s = _.__e = Me(t.__e, _, t, n, l, r, i, f, c);
146
+ return (p = d.diffed) && p(_), 128 & _.__u ? void 0 : s;
147
+ }
148
+ function K(e) {
149
+ e && e.__c && (e.__c.__e = !0), e && e.__k && e.__k.forEach(K);
150
+ }
151
+ function He(e, _, t) {
152
+ for (var n = 0; n < t.length; n++) _e(t[n], t[++n], t[++n]);
153
+ d.__c && d.__c(_, e), e.some(function(l) {
154
+ try {
155
+ e = l.__h, l.__h = [], e.some(function(r) {
156
+ r.call(l);
157
+ });
158
+ } catch (r) {
159
+ d.__e(r, l.__v);
160
+ }
161
+ });
162
+ }
163
+ function Se(e) {
164
+ return typeof e != "object" || e == null || e.__b && e.__b > 0 ? e : O(e) ? e.map(Se) : C({}, e);
165
+ }
166
+ function Me(e, _, t, n, l, r, i, s, f) {
167
+ var c, p, o, a, u, y, w, g = t.props || F, m = _.props, v = _.type;
168
+ if (v == "svg" ? l = "http://www.w3.org/2000/svg" : v == "math" ? l = "http://www.w3.org/1998/Math/MathML" : l || (l = "http://www.w3.org/1999/xhtml"), r != null) {
169
+ for (c = 0; c < r.length; c++) if ((u = r[c]) && "setAttribute" in u == !!v && (v ? u.localName == v : u.nodeType == 3)) {
170
+ e = u, r[c] = null;
171
+ break;
172
+ }
173
+ }
174
+ if (e == null) {
175
+ if (v == null) return document.createTextNode(m);
176
+ e = document.createElementNS(l, v, m.is && m), s && (d.__m && d.__m(_, r), s = !1), r = null;
177
+ }
178
+ if (v == null) g === m || s && e.data == m || (e.data = m);
179
+ else {
180
+ if (r = r && B.call(e.childNodes), !s && r != null) for (g = {}, c = 0; c < e.attributes.length; c++) g[(u = e.attributes[c]).name] = u.value;
181
+ for (c in g) if (u = g[c], c != "children") {
182
+ if (c == "dangerouslySetInnerHTML") o = u;
183
+ else if (!(c in m)) {
184
+ if (c == "value" && "defaultValue" in m || c == "checked" && "defaultChecked" in m) continue;
185
+ D(e, c, null, u, l);
186
+ }
187
+ }
188
+ for (c in m) u = m[c], c == "children" ? a = u : c == "dangerouslySetInnerHTML" ? p = u : c == "value" ? y = u : c == "checked" ? w = u : s && typeof u != "function" || g[c] === u || D(e, c, u, g[c], l);
189
+ if (p) s || o && (p.__html == o.__html || p.__html == e.innerHTML) || (e.innerHTML = p.__html), _.__k = [];
190
+ else if (o && (e.innerHTML = ""), $e(_.type == "template" ? e.content : e, O(a) ? a : [a], _, t, n, v == "foreignObject" ? "http://www.w3.org/1999/xhtml" : l, r, i, r ? r[0] : t.__k && T(t, 0), s, f), r != null) for (c = r.length; c--; ) Z(r[c]);
191
+ s || (c = "value", v == "progress" && y == null ? e.removeAttribute("value") : y != null && (y !== e[c] || v == "progress" && !y || v == "option" && y != g[c]) && D(e, c, y, g[c], l), c = "checked", w != null && w != e[c] && D(e, c, w, g[c], l));
192
+ }
193
+ return e;
194
+ }
195
+ function _e(e, _, t) {
196
+ try {
197
+ if (typeof e == "function") {
198
+ var n = typeof e.__u == "function";
199
+ n && e.__u(), n && _ == null || (e.__u = e(_));
200
+ } else e.current = _;
201
+ } catch (l) {
202
+ d.__e(l, t);
203
+ }
204
+ }
205
+ function xe(e, _, t) {
206
+ var n, l;
207
+ if (d.unmount && d.unmount(e), (n = e.ref) && (n.current && n.current != e.__e || _e(n, null, _)), (n = e.__c) != null) {
208
+ if (n.componentWillUnmount) try {
209
+ n.componentWillUnmount();
210
+ } catch (r) {
211
+ d.__e(r, _);
212
+ }
213
+ n.base = n.__P = null;
214
+ }
215
+ if (n = e.__k) for (l = 0; l < n.length; l++) n[l] && xe(n[l], _, t || typeof e.type != "function");
216
+ t || Z(e.__e), e.__c = e.__ = e.__e = void 0;
217
+ }
218
+ function De(e, _, t) {
219
+ return this.constructor(e, t);
220
+ }
221
+ function Le(e, _, t) {
222
+ var n, l, r, i;
223
+ _ == document && (_ = document.documentElement), d.__ && d.__(e, _), l = (n = !1) ? null : _.__k, r = [], i = [], ee(_, e = _.__k = Fe(V, null, [e]), l || F, F, _.namespaceURI, l ? null : _.firstChild ? B.call(_.childNodes) : null, r, l ? l.__e : _.firstChild, n, i), He(r, e, i);
224
+ }
225
+ B = ke.slice, d = { __e: function(e, _, t, n) {
226
+ for (var l, r, i; _ = _.__; ) if ((l = _.__c) && !l.__) try {
227
+ if ((r = l.constructor) && r.getDerivedStateFromError != null && (l.setState(r.getDerivedStateFromError(e)), i = l.__d), l.componentDidCatch != null && (l.componentDidCatch(e, n || {}), i = l.__d), i) return l.__E = l;
228
+ } catch (s) {
229
+ e = s;
230
+ }
231
+ throw e;
232
+ } }, me = 0, W.prototype.setState = function(e, _) {
233
+ var t;
234
+ t = this.__s != null && this.__s != this.state ? this.__s : this.__s = C({}, this.state), typeof e == "function" && (e = e(C({}, t), this.props)), e && C(t, e), e != null && this.__v && (_ && this._sb.push(_), oe(this));
235
+ }, W.prototype.forceUpdate = function(e) {
236
+ this.__v && (this.__e = !0, e && this.__h.push(e), oe(this));
237
+ }, W.prototype.render = V, x = [], ye = typeof Promise == "function" ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, ge = function(e, _) {
238
+ return e.__v.__b - _.__v.__b;
239
+ }, j.__r = 0, be = /(PointerCapture)$|Capture$/i, X = 0, J = ie(!1), Y = ie(!0);
240
+ var We = 0;
241
+ function h(e, _, t, n, l, r) {
242
+ _ || (_ = {});
243
+ var i, s, f = _;
244
+ if ("ref" in f) for (s in f = {}, _) s == "ref" ? i = _[s] : f[s] = _[s];
245
+ var c = { type: e, props: f, key: t, ref: i, __k: null, __: null, __b: 0, __e: null, __c: null, constructor: void 0, __v: --We, __i: -1, __u: 0, __source: l, __self: r };
246
+ if (typeof e == "function" && (i = e.defaultProps)) for (s in i) f[s] === void 0 && (f[s] = i[s]);
247
+ return d.vnode && d.vnode(c), c;
248
+ }
249
+ var N, b, G, ce, q = 0, Pe = [], k = d, se = k.__b, ue = k.__r, ae = k.diffed, fe = k.__c, pe = k.unmount, he = k.__;
250
+ function te(e, _) {
251
+ k.__h && k.__h(b, e, q || _), q = 0;
252
+ var t = b.__H || (b.__H = { __: [], __h: [] });
253
+ return e >= t.__.length && t.__.push({}), t.__[e];
254
+ }
255
+ function I(e) {
256
+ return q = 1, Ie(Ee, e);
257
+ }
258
+ function Ie(e, _, t) {
259
+ var n = te(N++, 2);
260
+ if (n.t = e, !n.__c && (n.__ = [Ee(void 0, _), function(s) {
261
+ var f = n.__N ? n.__N[0] : n.__[0], c = n.t(f, s);
262
+ f !== c && (n.__N = [c, n.__[1]], n.__c.setState({}));
263
+ }], n.__c = b, !b.__f)) {
264
+ var l = function(s, f, c) {
265
+ if (!n.__c.__H) return !0;
266
+ var p = n.__c.__H.__.filter(function(a) {
267
+ return !!a.__c;
268
+ });
269
+ if (p.every(function(a) {
270
+ return !a.__N;
271
+ })) return !r || r.call(this, s, f, c);
272
+ var o = n.__c.props !== s;
273
+ return p.forEach(function(a) {
274
+ if (a.__N) {
275
+ var u = a.__[0];
276
+ a.__ = a.__N, a.__N = void 0, u !== a.__[0] && (o = !0);
277
+ }
278
+ }), r && r.call(this, s, f, c) || o;
279
+ };
280
+ b.__f = !0;
281
+ var r = b.shouldComponentUpdate, i = b.componentWillUpdate;
282
+ b.componentWillUpdate = function(s, f, c) {
283
+ if (this.__e) {
284
+ var p = r;
285
+ r = void 0, l(s, f, c), r = p;
286
+ }
287
+ i && i.call(this, s, f, c);
288
+ }, b.shouldComponentUpdate = l;
289
+ }
290
+ return n.__N || n.__;
291
+ }
292
+ function Re(e, _) {
293
+ var t = te(N++, 3);
294
+ !k.__s && Te(t.__H, _) && (t.__ = e, t.u = _, b.__H.__h.push(t));
295
+ }
296
+ function de(e) {
297
+ return q = 5, je(function() {
298
+ return { current: e };
299
+ }, []);
300
+ }
301
+ function je(e, _) {
302
+ var t = te(N++, 7);
303
+ return Te(t.__H, _) && (t.__ = e(), t.__H = _, t.__h = e), t.__;
304
+ }
305
+ function qe() {
306
+ for (var e; e = Pe.shift(); ) if (e.__P && e.__H) try {
307
+ e.__H.__h.forEach(R), e.__H.__h.forEach(Q), e.__H.__h = [];
308
+ } catch (_) {
309
+ e.__H.__h = [], k.__e(_, e.__v);
310
+ }
311
+ }
312
+ k.__b = function(e) {
313
+ b = null, se && se(e);
314
+ }, k.__ = function(e, _) {
315
+ e && _.__k && _.__k.__m && (e.__m = _.__k.__m), he && he(e, _);
316
+ }, k.__r = function(e) {
317
+ ue && ue(e), N = 0;
318
+ var _ = (b = e.__c).__H;
319
+ _ && (G === b ? (_.__h = [], b.__h = [], _.__.forEach(function(t) {
320
+ t.__N && (t.__ = t.__N), t.u = t.__N = void 0;
321
+ })) : (_.__h.forEach(R), _.__h.forEach(Q), _.__h = [], N = 0)), G = b;
322
+ }, k.diffed = function(e) {
323
+ ae && ae(e);
324
+ var _ = e.__c;
325
+ _ && _.__H && (_.__H.__h.length && (Pe.push(_) !== 1 && ce === k.requestAnimationFrame || ((ce = k.requestAnimationFrame) || Be)(qe)), _.__H.__.forEach(function(t) {
326
+ t.u && (t.__H = t.u), t.u = void 0;
327
+ })), G = b = null;
328
+ }, k.__c = function(e, _) {
329
+ _.some(function(t) {
330
+ try {
331
+ t.__h.forEach(R), t.__h = t.__h.filter(function(n) {
332
+ return !n.__ || Q(n);
333
+ });
334
+ } catch (n) {
335
+ _.some(function(l) {
336
+ l.__h && (l.__h = []);
337
+ }), _ = [], k.__e(n, t.__v);
338
+ }
339
+ }), fe && fe(e, _);
340
+ }, k.unmount = function(e) {
341
+ pe && pe(e);
342
+ var _, t = e.__c;
343
+ t && t.__H && (t.__H.__.forEach(function(n) {
344
+ try {
345
+ R(n);
346
+ } catch (l) {
347
+ _ = l;
348
+ }
349
+ }), t.__H = void 0, _ && k.__e(_, t.__v));
350
+ };
351
+ var ve = typeof requestAnimationFrame == "function";
352
+ function Be(e) {
353
+ var _, t = function() {
354
+ clearTimeout(n), ve && cancelAnimationFrame(_), setTimeout(e);
355
+ }, n = setTimeout(t, 35);
356
+ ve && (_ = requestAnimationFrame(t));
357
+ }
358
+ function R(e) {
359
+ var _ = b, t = e.__c;
360
+ typeof t == "function" && (e.__c = void 0, t()), b = _;
361
+ }
362
+ function Q(e) {
363
+ var _ = b;
364
+ e.__c = e.__(), b = _;
365
+ }
366
+ function Te(e, _) {
367
+ return !e || e.length !== _.length || _.some(function(t, n) {
368
+ return t !== e[n];
369
+ });
370
+ }
371
+ function Ee(e, _) {
372
+ return typeof _ == "function" ? _(e) : _;
373
+ }
374
+ function Oe({ field: e, value: _, onChange: t }) {
375
+ return e.type === "boolean" ? /* @__PURE__ */ h("div", { class: "field", children: /* @__PURE__ */ h("label", { class: "checkbox-label", children: [
376
+ /* @__PURE__ */ h(
377
+ "input",
378
+ {
379
+ type: "checkbox",
380
+ checked: !!_,
381
+ onChange: (n) => t(n.target.checked)
382
+ }
383
+ ),
384
+ e.label
385
+ ] }) }) : e.type === "enum" && e.options ? /* @__PURE__ */ h("div", { class: "field", children: [
386
+ /* @__PURE__ */ h("label", { children: e.label }),
387
+ /* @__PURE__ */ h(
388
+ "select",
389
+ {
390
+ value: String(_),
391
+ onChange: (n) => t(n.target.value),
392
+ children: e.options.map((n) => /* @__PURE__ */ h("option", { value: n.value, children: n.label }, n.value))
393
+ }
394
+ )
395
+ ] }) : e.type === "number" ? /* @__PURE__ */ h("div", { class: "field", children: [
396
+ /* @__PURE__ */ h("label", { children: e.label }),
397
+ /* @__PURE__ */ h(
398
+ "input",
399
+ {
400
+ type: "number",
401
+ value: _,
402
+ onInput: (n) => t(parseFloat(n.target.value) || 0)
403
+ }
404
+ )
405
+ ] }) : /* @__PURE__ */ h("div", { class: "field", children: [
406
+ /* @__PURE__ */ h("label", { children: e.label }),
407
+ /* @__PURE__ */ h(
408
+ "input",
409
+ {
410
+ type: "text",
411
+ value: String(_),
412
+ onInput: (n) => t(n.target.value)
413
+ }
414
+ )
415
+ ] });
416
+ }
417
+ function Ve({
418
+ component: e,
419
+ overrides: _,
420
+ onFieldChange: t
421
+ }) {
422
+ const [n, l] = I(!0);
423
+ return /* @__PURE__ */ h("div", { class: `component-section ${n ? "collapsed" : ""}`, children: [
424
+ /* @__PURE__ */ h("div", { class: "component-header", onClick: () => l(!n), children: [
425
+ /* @__PURE__ */ h("h3", { children: e.label }),
426
+ /* @__PURE__ */ h("span", { class: "collapse-icon", children: "▼" })
427
+ ] }),
428
+ !n && /* @__PURE__ */ h("div", { class: "component-fields", children: e.fields.map((r) => {
429
+ const i = _[e.name]?.[r.liquid_variable] ?? r.default_value;
430
+ return /* @__PURE__ */ h(
431
+ Oe,
432
+ {
433
+ field: r,
434
+ value: i,
435
+ onChange: (s) => t(e.name, r.liquid_variable, s)
436
+ },
437
+ r.liquid_variable
438
+ );
439
+ }) })
440
+ ] });
441
+ }
442
+ function ze() {
443
+ const [e, _] = I(null), [t, n] = I({}), [l, r] = I(!1), i = de(null), s = de(null);
444
+ Re(() => {
445
+ fetch("./fields.json").then((a) => a.json()).then(_);
446
+ }, []);
447
+ const f = (a, u, y) => {
448
+ n((w) => ({
449
+ ...w,
450
+ [a]: {
451
+ ...w[a],
452
+ [u]: y
453
+ }
454
+ })), i.current && clearTimeout(i.current), i.current = window.setTimeout(() => {
455
+ c({
456
+ ...t,
457
+ [a]: {
458
+ ...t[a],
459
+ [u]: y
460
+ }
461
+ });
462
+ }, 300);
463
+ }, c = async (a) => {
464
+ r(!0);
465
+ try {
466
+ const u = s.current?.contentWindow?.scrollY ?? 0, w = await (await fetch("/api/render", {
467
+ method: "POST",
468
+ headers: { "Content-Type": "application/json" },
469
+ body: JSON.stringify(a)
470
+ })).json();
471
+ if (w.html && s.current) {
472
+ const g = s.current;
473
+ g.srcdoc = w.html, g.onload = () => {
474
+ g.contentWindow?.scrollTo(0, u);
475
+ };
476
+ } else w.error && console.error("Render error:", w.error);
477
+ } catch (u) {
478
+ console.error("Failed to update preview:", u);
479
+ } finally {
480
+ r(!1);
481
+ }
482
+ }, p = () => {
483
+ n({}), s.current && (s.current.removeAttribute("srcdoc"), s.current.src = "./rendered.html");
484
+ };
485
+ if (!e)
486
+ return /* @__PURE__ */ h("div", { class: "panel", children: "Loading..." });
487
+ const o = [e.container_component, ...e.components];
488
+ return /* @__PURE__ */ h("div", { class: "container", children: [
489
+ /* @__PURE__ */ h("div", { class: "panel", children: [
490
+ /* @__PURE__ */ h("div", { class: "panel-header", children: [
491
+ /* @__PURE__ */ h("h2", { children: "Preview Values" }),
492
+ /* @__PURE__ */ h("p", { children: "Adjust field values to preview how your components will look with different content." }),
493
+ /* @__PURE__ */ h("button", { class: "reset-btn", onClick: p, children: "Reset All" })
494
+ ] }),
495
+ /* @__PURE__ */ h("div", { class: "fields-container", children: o.map((a) => /* @__PURE__ */ h(
496
+ Ve,
497
+ {
498
+ component: a,
499
+ overrides: t,
500
+ onFieldChange: f
501
+ },
502
+ a.name
503
+ )) })
504
+ ] }),
505
+ /* @__PURE__ */ h("div", { class: "preview", children: [
506
+ /* @__PURE__ */ h("div", { class: `loading-overlay ${l ? "visible" : ""}`, children: /* @__PURE__ */ h("div", { class: "spinner" }) }),
507
+ /* @__PURE__ */ h("iframe", { ref: s, src: "./rendered.html" })
508
+ ] })
509
+ ] });
510
+ }
511
+ Le(/* @__PURE__ */ h(ze, {}), document.getElementById("app"));
@@ -6,7 +6,7 @@
6
6
  <title>EmailShepherd Dev</title>
7
7
  <style>
8
8
  * { margin: 0; padding: 0; box-sizing: border-box; }
9
- html, body { height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
9
+ html, body, #app { height: 100%; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; }
10
10
  .container { display: flex; height: 100%; }
11
11
  .panel {
12
12
  width: 320px;
@@ -118,164 +118,7 @@
118
118
  </style>
119
119
  </head>
120
120
  <body>
121
- <div class="container">
122
- <div class="panel" id="panel">
123
- <div class="panel-header">
124
- <h2>Preview Values</h2>
125
- <p>Adjust field values to preview how your components will look with different content.</p>
126
- <button class="reset-btn" id="reset-btn">Reset All</button>
127
- </div>
128
- <div id="fields-container"></div>
129
- </div>
130
- <div class="preview">
131
- <div class="loading-overlay" id="loading-overlay"><div class="spinner"></div></div>
132
- <iframe id="preview-frame" src="./rendered.html"></iframe>
133
- </div>
134
- </div>
135
- <script>
136
- let fieldsManifest = null;
137
- let overrides = {};
138
- let debounceTimer = null;
139
- let collapsedSections = {};
140
-
141
- async function loadFields() {
142
- const res = await fetch('./fields.json');
143
- fieldsManifest = await res.json();
144
- renderForm();
145
- }
146
-
147
- function renderForm() {
148
- const container = document.getElementById('fields-container');
149
- container.innerHTML = '';
150
-
151
- // Container component
152
- container.appendChild(createComponentSection(fieldsManifest.container_component));
153
-
154
- // Regular components
155
- for (const component of fieldsManifest.components) {
156
- container.appendChild(createComponentSection(component));
157
- }
158
- }
159
-
160
- function createComponentSection(component) {
161
- const section = document.createElement('div');
162
- section.className = 'component-section';
163
- // Collapsed by default unless explicitly expanded
164
- if (collapsedSections[component.name] !== false) {
165
- section.classList.add('collapsed');
166
- }
167
-
168
- const header = document.createElement('div');
169
- header.className = 'component-header';
170
- header.innerHTML = '<h3>' + escapeHtml(component.label) + '</h3><span class="collapse-icon">▼</span>';
171
- header.addEventListener('click', () => {
172
- section.classList.toggle('collapsed');
173
- collapsedSections[component.name] = !section.classList.contains('collapsed');
174
- });
175
- section.appendChild(header);
176
-
177
- const fields = document.createElement('div');
178
- fields.className = 'component-fields';
179
- for (const field of component.fields) {
180
- fields.appendChild(createFieldInput(component.name, field));
181
- }
182
- section.appendChild(fields);
183
-
184
- return section;
185
- }
186
-
187
- function createFieldInput(componentName, field) {
188
- const div = document.createElement('div');
189
- div.className = 'field';
190
-
191
- const defaultValue = field.default_value;
192
- const currentValue = overrides[componentName]?.[field.liquid_variable] ?? defaultValue;
193
-
194
- if (field.type === 'boolean') {
195
- const id = componentName + '_' + field.liquid_variable;
196
- div.innerHTML = '<label class="checkbox-label"><input type="checkbox" id="' + id + '" ' + (currentValue ? 'checked' : '') + '> ' + escapeHtml(field.label) + '</label>';
197
- const input = div.querySelector('input');
198
- input.addEventListener('change', () => handleChange(componentName, field.liquid_variable, input.checked));
199
- } else if (field.type === 'enum') {
200
- div.innerHTML = '<label>' + escapeHtml(field.label) + '</label>';
201
- const select = document.createElement('select');
202
- for (const opt of field.options) {
203
- const option = document.createElement('option');
204
- option.value = opt.value;
205
- option.textContent = opt.label;
206
- if (opt.value === currentValue) option.selected = true;
207
- select.appendChild(option);
208
- }
209
- select.addEventListener('change', () => handleChange(componentName, field.liquid_variable, select.value));
210
- div.appendChild(select);
211
- } else if (field.type === 'number') {
212
- div.innerHTML = '<label>' + escapeHtml(field.label) + '</label><input type="number" value="' + escapeHtml(String(currentValue)) + '">';
213
- const input = div.querySelector('input');
214
- input.addEventListener('input', () => handleChange(componentName, field.liquid_variable, parseFloat(input.value) || 0));
215
- } else {
216
- div.innerHTML = '<label>' + escapeHtml(field.label) + '</label><input type="text" value="' + escapeHtml(String(currentValue)) + '">';
217
- const input = div.querySelector('input');
218
- input.addEventListener('input', () => handleChange(componentName, field.liquid_variable, input.value));
219
- }
220
-
221
- return div;
222
- }
223
-
224
- function handleChange(componentName, fieldName, value) {
225
- if (!overrides[componentName]) overrides[componentName] = {};
226
- overrides[componentName][fieldName] = value;
227
-
228
- clearTimeout(debounceTimer);
229
- debounceTimer = setTimeout(updatePreview, 300);
230
- }
231
-
232
- function resetAll() {
233
- overrides = {};
234
- renderForm();
235
- const frame = document.getElementById('preview-frame');
236
- frame.removeAttribute('srcdoc');
237
- frame.src = './rendered.html';
238
- }
239
-
240
- function setLoading(loading) {
241
- const overlay = document.getElementById('loading-overlay');
242
- if (loading) {
243
- overlay.classList.add('visible');
244
- } else {
245
- overlay.classList.remove('visible');
246
- }
247
- }
248
-
249
- async function updatePreview() {
250
- setLoading(true);
251
-
252
- try {
253
- const res = await fetch('/api/render', {
254
- method: 'POST',
255
- headers: { 'Content-Type': 'application/json' },
256
- body: JSON.stringify(overrides),
257
- });
258
- const data = await res.json();
259
-
260
- if (data.html) {
261
- const frame = document.getElementById('preview-frame');
262
- frame.srcdoc = data.html;
263
- } else if (data.error) {
264
- console.error('Render error:', data.error);
265
- }
266
- } catch (err) {
267
- console.error('Failed to update preview:', err);
268
- } finally {
269
- setLoading(false);
270
- }
271
- }
272
-
273
- function escapeHtml(str) {
274
- return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;');
275
- }
276
-
277
- document.getElementById('reset-btn').addEventListener('click', resetAll);
278
- loadFields();
279
- </script>
121
+ <div id="app"></div>
122
+ <script type="module" src="./dev-ui.js"></script>
280
123
  </body>
281
124
  </html>
package/dist/types.d.ts CHANGED
@@ -9,8 +9,6 @@ type EDSMetadata = {
9
9
  custom_styles?: RichTextCustomStyle[];
10
10
  };
11
11
  type EDSConfig = {
12
- workspace_id: number;
13
- email_design_system_id: number;
14
12
  eds_metadata: EDSMetadata;
15
13
  container_component: ComponentDefinition;
16
14
  components: ComponentDefinition[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@emailshepherd/cli",
3
- "version": "0.2.0",
3
+ "version": "0.2.2",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org",
@@ -23,11 +23,13 @@
23
23
  "chokidar": "^4.0.3",
24
24
  "commander": "^14.0.2",
25
25
  "dotenv": "^17.2.3",
26
+ "preact": "^10.28.1",
26
27
  "update-notifier": "^7.3.1",
27
28
  "vite": "^7.2.6",
28
29
  "vite-plugin-checker": "^0.12.0"
29
30
  },
30
31
  "devDependencies": {
32
+ "@preact/preset-vite": "^2.10.2",
31
33
  "@types/node": "^24.10.1",
32
34
  "@types/update-notifier": "^6.0.8",
33
35
  "msw": "^2.12.7",
@@ -38,7 +40,10 @@
38
40
  "@emailshepherd/api-client": "0.0.0"
39
41
  },
40
42
  "scripts": {
41
- "build": "tsup && cp -r src/templates dist/",
43
+ "typecheck": "tsc",
44
+ "build:cli": "tsup",
45
+ "build:dev-ui": "vite build",
46
+ "build": "pnpm run typecheck && pnpm run build:cli && pnpm run build:dev-ui && cp -r src/templates dist/",
42
47
  "test": "vitest run",
43
48
  "test:watch": "vitest"
44
49
  }