@emailshepherd/cli 0.2.1 → 0.2.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/cli.js +15 -5
- package/dist/dev-ui/dev-ui.js +511 -0
- package/dist/templates/devWrapper.html +3 -160
- package/dist/types.d.ts +304 -19
- package/package.json +9 -2
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.
|
|
11
|
+
version: "0.2.3",
|
|
12
12
|
type: "module",
|
|
13
13
|
publishConfig: {
|
|
14
14
|
registry: "https://registry.npmjs.org",
|
|
@@ -27,7 +27,11 @@ var package_default = {
|
|
|
27
27
|
"dist"
|
|
28
28
|
],
|
|
29
29
|
scripts: {
|
|
30
|
-
|
|
30
|
+
typecheck: "tsc",
|
|
31
|
+
"build:cli": "tsup",
|
|
32
|
+
"build:types": "dts-bundle-generator -o dist/types.d.ts src/types.ts",
|
|
33
|
+
"build:dev-ui": "vite build",
|
|
34
|
+
build: "pnpm run typecheck && pnpm run build:cli && pnpm run build:types && pnpm run build:dev-ui && cp -r src/templates dist/",
|
|
31
35
|
test: "vitest run",
|
|
32
36
|
"test:watch": "vitest",
|
|
33
37
|
prepublishOnly: "pnpm run build"
|
|
@@ -37,14 +41,17 @@ var package_default = {
|
|
|
37
41
|
chokidar: "^4.0.3",
|
|
38
42
|
commander: "^14.0.2",
|
|
39
43
|
dotenv: "^17.2.3",
|
|
44
|
+
preact: "^10.28.1",
|
|
40
45
|
"update-notifier": "^7.3.1",
|
|
41
46
|
vite: "^7.2.6",
|
|
42
47
|
"vite-plugin-checker": "^0.12.0"
|
|
43
48
|
},
|
|
44
49
|
devDependencies: {
|
|
45
50
|
"@emailshepherd/api-client": "workspace:*",
|
|
51
|
+
"@preact/preset-vite": "^2.10.2",
|
|
46
52
|
"@types/node": "^24.10.1",
|
|
47
53
|
"@types/update-notifier": "^6.0.8",
|
|
54
|
+
"dts-bundle-generator": "^9.5.1",
|
|
48
55
|
msw: "^2.12.7",
|
|
49
56
|
tsup: "^8.5.1",
|
|
50
57
|
tsx: "^4.21.0",
|
|
@@ -83,7 +90,7 @@ function configureAxios(config) {
|
|
|
83
90
|
|
|
84
91
|
// src/buildHtml.ts
|
|
85
92
|
import { AxiosError } from "axios";
|
|
86
|
-
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
93
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
|
|
87
94
|
import { dirname, resolve } from "path";
|
|
88
95
|
import { fileURLToPath } from "url";
|
|
89
96
|
import { createServer } from "vite";
|
|
@@ -214,6 +221,8 @@ function writeDevWrapper() {
|
|
|
214
221
|
const templatePath = resolve(__dirname, "templates", "devWrapper.html");
|
|
215
222
|
const devWrapperHtml = readFileSync(templatePath, "utf-8");
|
|
216
223
|
writeFileSync(resolve(distDir, "index.html"), devWrapperHtml);
|
|
224
|
+
const devUiPath = resolve(__dirname, "dev-ui", "dev-ui.js");
|
|
225
|
+
copyFileSync(devUiPath, resolve(distDir, "dev-ui.js"));
|
|
217
226
|
}
|
|
218
227
|
async function buildHtml() {
|
|
219
228
|
configureAxios();
|
|
@@ -448,12 +457,13 @@ function applyOverrides(eds, overrides) {
|
|
|
448
457
|
}
|
|
449
458
|
async function renderWithOverrides(overrides) {
|
|
450
459
|
configureAxios();
|
|
460
|
+
const { workspaceId, edsId } = getEDSEnvConfig();
|
|
451
461
|
const eds = await loadEDS();
|
|
452
462
|
const modifiedEds = applyOverrides(eds, overrides);
|
|
453
463
|
const objectRepresentation = await buildEmailDesignSystemObject(modifiedEds);
|
|
454
464
|
const response = await renderEmailDesignSystem(
|
|
455
|
-
|
|
456
|
-
|
|
465
|
+
workspaceId,
|
|
466
|
+
edsId,
|
|
457
467
|
objectRepresentation
|
|
458
468
|
);
|
|
459
469
|
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
|
|
122
|
-
|
|
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, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
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
|
@@ -1,38 +1,323 @@
|
|
|
1
|
-
|
|
2
|
-
export { DesignTokens, FieldDefinition, RichTextCustomStyle } from '@emailshepherd/api-client';
|
|
1
|
+
// Generated by dts-bundle-generator v9.5.1
|
|
3
2
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
3
|
+
/**
|
|
4
|
+
* @nullable
|
|
5
|
+
*/
|
|
6
|
+
export type DesignTokens = {
|
|
7
|
+
[key: string]: unknown;
|
|
8
|
+
} | null;
|
|
9
|
+
export interface RichTextCustomStyle {
|
|
10
|
+
style: string;
|
|
11
|
+
name: string;
|
|
12
|
+
label: string;
|
|
13
|
+
}
|
|
14
|
+
export type FieldDefinition = TextFieldDefinition | NumberFieldDefinition | EnumFieldDefinition | BooleanFieldDefinition | UrlFieldDefinition | ImageFieldDefinition | ColorFieldDefinition | RichTextFieldDefinition | CodeFieldDefinition;
|
|
15
|
+
export type TextFieldDefinitionType = typeof TextFieldDefinitionType[keyof typeof TextFieldDefinitionType];
|
|
16
|
+
declare const TextFieldDefinitionType: {
|
|
17
|
+
readonly text: "text";
|
|
18
|
+
};
|
|
19
|
+
export type TextFieldDefinitionValidations = {
|
|
20
|
+
min_length?: number;
|
|
21
|
+
max_length?: number;
|
|
22
|
+
must_not_be_blank?: boolean;
|
|
23
|
+
must_not_be_default?: boolean;
|
|
24
|
+
};
|
|
25
|
+
export interface TextFieldDefinition {
|
|
26
|
+
type: TextFieldDefinitionType;
|
|
27
|
+
label: string;
|
|
28
|
+
/** @nullable */
|
|
29
|
+
group?: string | null;
|
|
30
|
+
liquid_variable: string;
|
|
31
|
+
visible_if?: string;
|
|
32
|
+
default_value: string;
|
|
33
|
+
validations?: TextFieldDefinitionValidations;
|
|
34
|
+
hint?: string;
|
|
35
|
+
hidden_in_editor?: boolean;
|
|
36
|
+
hidden_from_ai?: boolean;
|
|
37
|
+
/** @nullable */
|
|
38
|
+
feed_field_name?: string | null;
|
|
39
|
+
}
|
|
40
|
+
export type NumberFieldDefinitionType = typeof NumberFieldDefinitionType[keyof typeof NumberFieldDefinitionType];
|
|
41
|
+
declare const NumberFieldDefinitionType: {
|
|
42
|
+
readonly number: "number";
|
|
43
|
+
};
|
|
44
|
+
export type NumberFieldDefinitionValidations = {
|
|
45
|
+
min?: number;
|
|
46
|
+
max?: number;
|
|
47
|
+
};
|
|
48
|
+
export interface NumberFieldDefinition {
|
|
49
|
+
type: NumberFieldDefinitionType;
|
|
50
|
+
label: string;
|
|
51
|
+
/** @nullable */
|
|
52
|
+
group?: string | null;
|
|
53
|
+
liquid_variable: string;
|
|
54
|
+
visible_if?: string;
|
|
55
|
+
default_value: number;
|
|
56
|
+
validations?: NumberFieldDefinitionValidations;
|
|
57
|
+
hint?: string;
|
|
58
|
+
hidden_in_editor?: boolean;
|
|
59
|
+
hidden_from_ai?: boolean;
|
|
60
|
+
/** @nullable */
|
|
61
|
+
feed_field_name?: string | null;
|
|
62
|
+
}
|
|
63
|
+
export type EnumFieldDefinitionType = typeof EnumFieldDefinitionType[keyof typeof EnumFieldDefinitionType];
|
|
64
|
+
declare const EnumFieldDefinitionType: {
|
|
65
|
+
readonly enum: "enum";
|
|
66
|
+
};
|
|
67
|
+
export type EnumFieldDefinitionValidations = {
|
|
68
|
+
[key: string]: unknown;
|
|
69
|
+
};
|
|
70
|
+
export type EnumFieldDefinitionOptionsItem = {
|
|
71
|
+
label: string;
|
|
72
|
+
value: string;
|
|
73
|
+
/** @nullable */
|
|
74
|
+
icon_url?: string | null;
|
|
75
|
+
};
|
|
76
|
+
export interface EnumFieldDefinition {
|
|
77
|
+
type: EnumFieldDefinitionType;
|
|
78
|
+
label: string;
|
|
79
|
+
/** @nullable */
|
|
80
|
+
group?: string | null;
|
|
81
|
+
liquid_variable: string;
|
|
82
|
+
visible_if?: string;
|
|
83
|
+
default_value: string;
|
|
84
|
+
validations?: EnumFieldDefinitionValidations;
|
|
85
|
+
options: EnumFieldDefinitionOptionsItem[];
|
|
86
|
+
hint?: string;
|
|
87
|
+
hidden_in_editor?: boolean;
|
|
88
|
+
hidden_from_ai?: boolean;
|
|
89
|
+
/** @nullable */
|
|
90
|
+
feed_field_name?: string | null;
|
|
91
|
+
}
|
|
92
|
+
export type BooleanFieldDefinitionType = typeof BooleanFieldDefinitionType[keyof typeof BooleanFieldDefinitionType];
|
|
93
|
+
declare const BooleanFieldDefinitionType: {
|
|
94
|
+
readonly boolean: "boolean";
|
|
95
|
+
};
|
|
96
|
+
export type BooleanFieldDefinitionValidations = {
|
|
97
|
+
[key: string]: unknown;
|
|
98
|
+
};
|
|
99
|
+
export interface BooleanFieldDefinition {
|
|
100
|
+
type: BooleanFieldDefinitionType;
|
|
101
|
+
label: string;
|
|
102
|
+
/** @nullable */
|
|
103
|
+
group?: string | null;
|
|
104
|
+
liquid_variable: string;
|
|
105
|
+
visible_if?: string;
|
|
106
|
+
default_value: boolean;
|
|
107
|
+
validations?: BooleanFieldDefinitionValidations;
|
|
108
|
+
hint?: string;
|
|
109
|
+
hidden_in_editor?: boolean;
|
|
110
|
+
hidden_from_ai?: boolean;
|
|
111
|
+
/** @nullable */
|
|
112
|
+
feed_field_name?: string | null;
|
|
113
|
+
}
|
|
114
|
+
export type UrlFieldDefinitionType = typeof UrlFieldDefinitionType[keyof typeof UrlFieldDefinitionType];
|
|
115
|
+
declare const UrlFieldDefinitionType: {
|
|
116
|
+
readonly url: "url";
|
|
117
|
+
};
|
|
118
|
+
export type UrlFieldDefinitionValidations = {
|
|
119
|
+
must_not_be_blank?: boolean;
|
|
120
|
+
must_not_be_default?: boolean;
|
|
121
|
+
};
|
|
122
|
+
export interface UrlFieldDefinition {
|
|
123
|
+
type: UrlFieldDefinitionType;
|
|
124
|
+
label: string;
|
|
125
|
+
/** @nullable */
|
|
126
|
+
group?: string | null;
|
|
127
|
+
liquid_variable: string;
|
|
128
|
+
visible_if?: string;
|
|
129
|
+
default_value: string;
|
|
130
|
+
validations?: UrlFieldDefinitionValidations;
|
|
131
|
+
hint?: string;
|
|
132
|
+
hidden_in_editor?: boolean;
|
|
133
|
+
hidden_from_ai?: boolean;
|
|
134
|
+
/** @nullable */
|
|
135
|
+
feed_field_name?: string | null;
|
|
136
|
+
/** @nullable */
|
|
137
|
+
skip_link_tracking?: boolean | null;
|
|
138
|
+
}
|
|
139
|
+
export type ImageFieldDefinitionType = typeof ImageFieldDefinitionType[keyof typeof ImageFieldDefinitionType];
|
|
140
|
+
declare const ImageFieldDefinitionType: {
|
|
141
|
+
readonly image: "image";
|
|
142
|
+
};
|
|
143
|
+
export type ImageFieldDefinitionValidations = {
|
|
144
|
+
must_not_be_blank?: boolean;
|
|
145
|
+
must_not_be_default?: boolean;
|
|
146
|
+
};
|
|
147
|
+
export interface ImageFieldDefinition {
|
|
148
|
+
type: ImageFieldDefinitionType;
|
|
149
|
+
label: string;
|
|
150
|
+
/** @nullable */
|
|
151
|
+
group?: string | null;
|
|
152
|
+
liquid_variable: string;
|
|
153
|
+
visible_if?: string;
|
|
154
|
+
default_value: string;
|
|
155
|
+
validations?: ImageFieldDefinitionValidations;
|
|
156
|
+
hint?: string;
|
|
157
|
+
hidden_in_editor?: boolean;
|
|
158
|
+
hidden_from_ai?: boolean;
|
|
159
|
+
/** @nullable */
|
|
160
|
+
feed_field_name?: string | null;
|
|
161
|
+
}
|
|
162
|
+
export type ColorFieldDefinitionType = typeof ColorFieldDefinitionType[keyof typeof ColorFieldDefinitionType];
|
|
163
|
+
declare const ColorFieldDefinitionType: {
|
|
164
|
+
readonly color: "color";
|
|
165
|
+
};
|
|
166
|
+
export type ColorFieldDefinitionValidations = {
|
|
167
|
+
[key: string]: unknown;
|
|
168
|
+
};
|
|
169
|
+
export interface ColorFieldDefinition {
|
|
170
|
+
type: ColorFieldDefinitionType;
|
|
171
|
+
label: string;
|
|
172
|
+
/** @nullable */
|
|
173
|
+
group?: string | null;
|
|
174
|
+
liquid_variable: string;
|
|
175
|
+
visible_if?: string;
|
|
176
|
+
default_value: string;
|
|
177
|
+
validations?: ColorFieldDefinitionValidations;
|
|
178
|
+
hint?: string;
|
|
179
|
+
hidden_in_editor?: boolean;
|
|
180
|
+
hidden_from_ai?: boolean;
|
|
181
|
+
/** @nullable */
|
|
182
|
+
feed_field_name?: string | null;
|
|
183
|
+
}
|
|
184
|
+
export type RichTextFieldDefinitionType = typeof RichTextFieldDefinitionType[keyof typeof RichTextFieldDefinitionType];
|
|
185
|
+
declare const RichTextFieldDefinitionType: {
|
|
186
|
+
readonly rich_text: "rich_text";
|
|
187
|
+
};
|
|
188
|
+
export type RichTextFieldDefinitionValidations = {
|
|
189
|
+
max_content_length?: number;
|
|
190
|
+
min_content_length?: number;
|
|
191
|
+
must_not_be_blank?: boolean;
|
|
192
|
+
must_not_be_default?: boolean;
|
|
193
|
+
};
|
|
194
|
+
export type RichTextFieldDefinitionMarksBold = {
|
|
195
|
+
enabled: boolean;
|
|
196
|
+
};
|
|
197
|
+
export type RichTextFieldDefinitionMarksItalic = {
|
|
198
|
+
enabled: boolean;
|
|
199
|
+
};
|
|
200
|
+
export type RichTextFieldDefinitionMarksLink = {
|
|
201
|
+
enabled: boolean;
|
|
202
|
+
};
|
|
203
|
+
export type RichTextFieldDefinitionMarksBulletList = {
|
|
204
|
+
enabled: boolean;
|
|
205
|
+
};
|
|
206
|
+
export type RichTextFieldDefinitionMarksNumberedList = {
|
|
207
|
+
enabled: boolean;
|
|
208
|
+
};
|
|
209
|
+
/**
|
|
210
|
+
* @nullable
|
|
211
|
+
*/
|
|
212
|
+
export type RichTextFieldDefinitionMarks = {
|
|
213
|
+
bold: RichTextFieldDefinitionMarksBold;
|
|
214
|
+
italic: RichTextFieldDefinitionMarksItalic;
|
|
215
|
+
link: RichTextFieldDefinitionMarksLink;
|
|
216
|
+
bullet_list: RichTextFieldDefinitionMarksBulletList;
|
|
217
|
+
numbered_list: RichTextFieldDefinitionMarksNumberedList;
|
|
218
|
+
} | null;
|
|
219
|
+
export interface RichTextFieldDefinition {
|
|
220
|
+
type: RichTextFieldDefinitionType;
|
|
221
|
+
label: string;
|
|
222
|
+
/** @nullable */
|
|
223
|
+
group?: string | null;
|
|
224
|
+
liquid_variable: string;
|
|
225
|
+
visible_if?: string;
|
|
226
|
+
default_value: string;
|
|
227
|
+
validations?: RichTextFieldDefinitionValidations;
|
|
228
|
+
hint?: string;
|
|
229
|
+
hidden_in_editor?: boolean;
|
|
230
|
+
hidden_from_ai?: boolean;
|
|
231
|
+
/** @nullable */
|
|
232
|
+
feed_field_name?: string | null;
|
|
233
|
+
/** @nullable */
|
|
234
|
+
marks: RichTextFieldDefinitionMarks;
|
|
235
|
+
/** @nullable */
|
|
236
|
+
custom_styles_names?: string[] | null;
|
|
237
|
+
}
|
|
238
|
+
export type CodeFieldDefinitionType = typeof CodeFieldDefinitionType[keyof typeof CodeFieldDefinitionType];
|
|
239
|
+
declare const CodeFieldDefinitionType: {
|
|
240
|
+
readonly code: "code";
|
|
241
|
+
};
|
|
242
|
+
export type CodeFieldDefinitionValidations = {
|
|
243
|
+
must_not_be_blank?: boolean;
|
|
244
|
+
must_not_be_default?: boolean;
|
|
245
|
+
};
|
|
246
|
+
export interface CodeFieldDefinition {
|
|
247
|
+
type: CodeFieldDefinitionType;
|
|
248
|
+
label: string;
|
|
249
|
+
/** @nullable */
|
|
250
|
+
group?: string | null;
|
|
251
|
+
liquid_variable: string;
|
|
252
|
+
visible_if?: string;
|
|
253
|
+
default_value: string;
|
|
254
|
+
validations?: CodeFieldDefinitionValidations;
|
|
255
|
+
hint?: string;
|
|
256
|
+
hidden_in_editor?: boolean;
|
|
257
|
+
hidden_from_ai?: boolean;
|
|
258
|
+
/** @nullable */
|
|
259
|
+
feed_field_name?: string | null;
|
|
260
|
+
}
|
|
261
|
+
export interface Component {
|
|
262
|
+
id: number;
|
|
263
|
+
name: string;
|
|
264
|
+
label: string;
|
|
265
|
+
/** @nullable */
|
|
266
|
+
description: string | null;
|
|
267
|
+
email_design_system_id: number;
|
|
268
|
+
updated_at: string;
|
|
269
|
+
created_at: string;
|
|
270
|
+
/** @nullable */
|
|
271
|
+
container?: boolean | null;
|
|
272
|
+
template: string;
|
|
273
|
+
field_definitions: FieldDefinition[];
|
|
274
|
+
screenshot_url: string;
|
|
275
|
+
/** @nullable */
|
|
276
|
+
position: number | null;
|
|
277
|
+
/** @nullable */
|
|
278
|
+
last_updated_by: UserReference;
|
|
279
|
+
/** @nullable */
|
|
280
|
+
feed_id: number | null;
|
|
281
|
+
deprecated: boolean;
|
|
282
|
+
}
|
|
283
|
+
export interface UserReference {
|
|
284
|
+
id: number;
|
|
285
|
+
first_name: string;
|
|
286
|
+
last_name: string;
|
|
287
|
+
/** @nullable */
|
|
288
|
+
profile_image_url: string | null;
|
|
289
|
+
}
|
|
290
|
+
export type ComponentDefinition = Omit<Component, "id" | "email_design_system_id" | "created_at" | "updated_at" | "screenshot_url" | "last_updated_by" | "container" | "position">;
|
|
291
|
+
export type EDSMetadata = {
|
|
292
|
+
name: string;
|
|
293
|
+
description: string;
|
|
294
|
+
design_tokens: DesignTokens;
|
|
295
|
+
custom_styles?: RichTextCustomStyle[];
|
|
296
|
+
};
|
|
297
|
+
export type EDSConfig = {
|
|
298
|
+
eds_metadata: EDSMetadata;
|
|
299
|
+
container_component: ComponentDefinition;
|
|
300
|
+
components: ComponentDefinition[];
|
|
15
301
|
};
|
|
16
|
-
|
|
17
302
|
/**
|
|
18
303
|
* Define an Email Design System configuration.
|
|
19
304
|
* Use this in your src/eds.ts file.
|
|
20
305
|
*/
|
|
21
|
-
declare function defineEDS(config: EDSConfig): EDSConfig;
|
|
306
|
+
export declare function defineEDS(config: EDSConfig): EDSConfig;
|
|
22
307
|
/**
|
|
23
308
|
* Define a component with its template.
|
|
24
309
|
* Use this in your src/components/{name}/index.ts file.
|
|
25
310
|
*/
|
|
26
|
-
declare function defineComponent(config: ComponentDefinition): ComponentDefinition;
|
|
311
|
+
export declare function defineComponent(config: ComponentDefinition): ComponentDefinition;
|
|
27
312
|
/**
|
|
28
313
|
* Define design tokens for your Email Design System.
|
|
29
314
|
* Use this in your src/design_tokens.ts file.
|
|
30
315
|
*/
|
|
31
|
-
declare function defineDesignTokens(tokens: DesignTokens): DesignTokens;
|
|
316
|
+
export declare function defineDesignTokens(tokens: DesignTokens): DesignTokens;
|
|
32
317
|
/**
|
|
33
318
|
* Define custom styles for rich text fields.
|
|
34
319
|
* Use this in your src/custom_styles.ts file.
|
|
35
320
|
*/
|
|
36
|
-
declare function defineCustomStyles(styles: RichTextCustomStyle[]): RichTextCustomStyle[];
|
|
321
|
+
export declare function defineCustomStyles(styles: RichTextCustomStyle[]): RichTextCustomStyle[];
|
|
37
322
|
|
|
38
|
-
export {
|
|
323
|
+
export {};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@emailshepherd/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"registry": "https://registry.npmjs.org",
|
|
@@ -23,13 +23,16 @@
|
|
|
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",
|
|
35
|
+
"dts-bundle-generator": "^9.5.1",
|
|
33
36
|
"msw": "^2.12.7",
|
|
34
37
|
"tsup": "^8.5.1",
|
|
35
38
|
"tsx": "^4.21.0",
|
|
@@ -38,7 +41,11 @@
|
|
|
38
41
|
"@emailshepherd/api-client": "0.0.0"
|
|
39
42
|
},
|
|
40
43
|
"scripts": {
|
|
41
|
-
"
|
|
44
|
+
"typecheck": "tsc",
|
|
45
|
+
"build:cli": "tsup",
|
|
46
|
+
"build:types": "dts-bundle-generator -o dist/types.d.ts src/types.ts",
|
|
47
|
+
"build:dev-ui": "vite build",
|
|
48
|
+
"build": "pnpm run typecheck && pnpm run build:cli && pnpm run build:types && pnpm run build:dev-ui && cp -r src/templates dist/",
|
|
42
49
|
"test": "vitest run",
|
|
43
50
|
"test:watch": "vitest"
|
|
44
51
|
}
|