@embeddables/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +116 -0
  2. package/bin/embeddables.mjs +2 -0
  3. package/dist/auth/index.d.ts +43 -0
  4. package/dist/auth/index.d.ts.map +1 -0
  5. package/dist/auth/index.js +100 -0
  6. package/dist/cli.d.ts +2 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +75 -0
  9. package/dist/commands/build-workbench.d.ts +5 -0
  10. package/dist/commands/build-workbench.d.ts.map +1 -0
  11. package/dist/commands/build-workbench.js +122 -0
  12. package/dist/commands/build.d.ts +7 -0
  13. package/dist/commands/build.d.ts.map +1 -0
  14. package/dist/commands/build.js +22 -0
  15. package/dist/commands/dev.d.ts +11 -0
  16. package/dist/commands/dev.d.ts.map +1 -0
  17. package/dist/commands/dev.js +153 -0
  18. package/dist/commands/login.d.ts +2 -0
  19. package/dist/commands/login.d.ts.map +1 -0
  20. package/dist/commands/login.js +112 -0
  21. package/dist/commands/logout.d.ts +2 -0
  22. package/dist/commands/logout.d.ts.map +1 -0
  23. package/dist/commands/logout.js +18 -0
  24. package/dist/commands/pull.d.ts +7 -0
  25. package/dist/commands/pull.d.ts.map +1 -0
  26. package/dist/commands/pull.js +97 -0
  27. package/dist/compiler/errors.d.ts +20 -0
  28. package/dist/compiler/errors.d.ts.map +1 -0
  29. package/dist/compiler/errors.js +35 -0
  30. package/dist/compiler/evalStatic.d.ts +3 -0
  31. package/dist/compiler/evalStatic.d.ts.map +1 -0
  32. package/dist/compiler/evalStatic.js +57 -0
  33. package/dist/compiler/flatten.js +1 -0
  34. package/dist/compiler/helpers/duplicateIds.d.ts +9 -0
  35. package/dist/compiler/helpers/duplicateIds.d.ts.map +1 -0
  36. package/dist/compiler/helpers/duplicateIds.js +71 -0
  37. package/dist/compiler/index.d.ts +16 -0
  38. package/dist/compiler/index.d.ts.map +1 -0
  39. package/dist/compiler/index.js +934 -0
  40. package/dist/compiler/parsePage.d.ts +15 -0
  41. package/dist/compiler/parsePage.d.ts.map +1 -0
  42. package/dist/compiler/parsePage.js +562 -0
  43. package/dist/compiler/registry.d.ts +4 -0
  44. package/dist/compiler/registry.d.ts.map +1 -0
  45. package/dist/compiler/registry.js +44 -0
  46. package/dist/compiler/reverse.d.ts +17 -0
  47. package/dist/compiler/reverse.d.ts.map +1 -0
  48. package/dist/compiler/reverse.js +1632 -0
  49. package/dist/compiler/types.d.ts +21 -0
  50. package/dist/compiler/types.d.ts.map +1 -0
  51. package/dist/compiler/types.js +1 -0
  52. package/dist/components/index.d.ts +21 -0
  53. package/dist/components/index.d.ts.map +1 -0
  54. package/dist/components/index.js +21 -0
  55. package/dist/components/primitives/BaseComponent.d.ts +32 -0
  56. package/dist/components/primitives/BaseComponent.d.ts.map +1 -0
  57. package/dist/components/primitives/BaseComponent.js +26 -0
  58. package/dist/components/primitives/BookMeeting.d.ts +18 -0
  59. package/dist/components/primitives/BookMeeting.d.ts.map +1 -0
  60. package/dist/components/primitives/BookMeeting.js +5 -0
  61. package/dist/components/primitives/Chart.d.ts +41 -0
  62. package/dist/components/primitives/Chart.d.ts.map +1 -0
  63. package/dist/components/primitives/Chart.js +5 -0
  64. package/dist/components/primitives/Container.d.ts +8 -0
  65. package/dist/components/primitives/Container.d.ts.map +1 -0
  66. package/dist/components/primitives/Container.js +5 -0
  67. package/dist/components/primitives/CustomButton.d.ts +37 -0
  68. package/dist/components/primitives/CustomButton.d.ts.map +1 -0
  69. package/dist/components/primitives/CustomButton.js +10 -0
  70. package/dist/components/primitives/CustomHTML.d.ts +8 -0
  71. package/dist/components/primitives/CustomHTML.d.ts.map +1 -0
  72. package/dist/components/primitives/CustomHTML.js +5 -0
  73. package/dist/components/primitives/FileUpload.d.ts +18 -0
  74. package/dist/components/primitives/FileUpload.d.ts.map +1 -0
  75. package/dist/components/primitives/FileUpload.js +16 -0
  76. package/dist/components/primitives/InputBox.d.ts +34 -0
  77. package/dist/components/primitives/InputBox.d.ts.map +1 -0
  78. package/dist/components/primitives/InputBox.js +25 -0
  79. package/dist/components/primitives/Lottie.d.ts +11 -0
  80. package/dist/components/primitives/Lottie.d.ts.map +1 -0
  81. package/dist/components/primitives/Lottie.js +5 -0
  82. package/dist/components/primitives/MediaEmbed.d.ts +13 -0
  83. package/dist/components/primitives/MediaEmbed.d.ts.map +1 -0
  84. package/dist/components/primitives/MediaEmbed.js +6 -0
  85. package/dist/components/primitives/MediaImage.d.ts +8 -0
  86. package/dist/components/primitives/MediaImage.d.ts.map +1 -0
  87. package/dist/components/primitives/MediaImage.js +5 -0
  88. package/dist/components/primitives/OptionSelector.d.ts +35 -0
  89. package/dist/components/primitives/OptionSelector.d.ts.map +1 -0
  90. package/dist/components/primitives/OptionSelector.js +8 -0
  91. package/dist/components/primitives/PaypalCheckout.d.ts +25 -0
  92. package/dist/components/primitives/PaypalCheckout.d.ts.map +1 -0
  93. package/dist/components/primitives/PaypalCheckout.js +5 -0
  94. package/dist/components/primitives/PlainText.d.ts +6 -0
  95. package/dist/components/primitives/PlainText.d.ts.map +1 -0
  96. package/dist/components/primitives/PlainText.js +5 -0
  97. package/dist/components/primitives/ProgressBar.d.ts +15 -0
  98. package/dist/components/primitives/ProgressBar.d.ts.map +1 -0
  99. package/dist/components/primitives/ProgressBar.js +5 -0
  100. package/dist/components/primitives/RichText.d.ts +6 -0
  101. package/dist/components/primitives/RichText.d.ts.map +1 -0
  102. package/dist/components/primitives/RichText.js +5 -0
  103. package/dist/components/primitives/RichTextMarkdown.d.ts +6 -0
  104. package/dist/components/primitives/RichTextMarkdown.d.ts.map +1 -0
  105. package/dist/components/primitives/RichTextMarkdown.js +5 -0
  106. package/dist/components/primitives/Rive.d.ts +16 -0
  107. package/dist/components/primitives/Rive.d.ts.map +1 -0
  108. package/dist/components/primitives/Rive.js +8 -0
  109. package/dist/components/primitives/StripeCheckout.d.ts +52 -0
  110. package/dist/components/primitives/StripeCheckout.d.ts.map +1 -0
  111. package/dist/components/primitives/StripeCheckout.js +5 -0
  112. package/dist/components/primitives/StripeCheckout2.d.ts +30 -0
  113. package/dist/components/primitives/StripeCheckout2.d.ts.map +1 -0
  114. package/dist/components/primitives/StripeCheckout2.js +7 -0
  115. package/dist/proxy/injectApiInterceptor.d.ts +6 -0
  116. package/dist/proxy/injectApiInterceptor.d.ts.map +1 -0
  117. package/dist/proxy/injectApiInterceptor.js +66 -0
  118. package/dist/proxy/injectReload.d.ts +2 -0
  119. package/dist/proxy/injectReload.d.ts.map +1 -0
  120. package/dist/proxy/injectReload.js +14 -0
  121. package/dist/proxy/injectWorkbench.d.ts +4 -0
  122. package/dist/proxy/injectWorkbench.d.ts.map +1 -0
  123. package/dist/proxy/injectWorkbench.js +16 -0
  124. package/dist/proxy/server.d.ts +11 -0
  125. package/dist/proxy/server.d.ts.map +1 -0
  126. package/dist/proxy/server.js +246 -0
  127. package/dist/proxy/sse.d.ts +5 -0
  128. package/dist/proxy/sse.d.ts.map +1 -0
  129. package/dist/proxy/sse.js +17 -0
  130. package/dist/types-builder.d.ts +800 -0
  131. package/dist/types-builder.d.ts.map +1 -0
  132. package/dist/types-builder.js +20 -0
  133. package/dist/workbench/ActionsPanel.d.ts +6 -0
  134. package/dist/workbench/ActionsPanel.d.ts.map +1 -0
  135. package/dist/workbench/ActionsPanel.js +47 -0
  136. package/dist/workbench/AutofillPanel.d.ts +6 -0
  137. package/dist/workbench/AutofillPanel.d.ts.map +1 -0
  138. package/dist/workbench/AutofillPanel.js +543 -0
  139. package/dist/workbench/ComputedFieldsPanel.d.ts +6 -0
  140. package/dist/workbench/ComputedFieldsPanel.d.ts.map +1 -0
  141. package/dist/workbench/ComputedFieldsPanel.js +31 -0
  142. package/dist/workbench/ExperimentsPanel.d.ts +6 -0
  143. package/dist/workbench/ExperimentsPanel.d.ts.map +1 -0
  144. package/dist/workbench/ExperimentsPanel.js +182 -0
  145. package/dist/workbench/FieldEditorPanel.d.ts +9 -0
  146. package/dist/workbench/FieldEditorPanel.d.ts.map +1 -0
  147. package/dist/workbench/FieldEditorPanel.js +650 -0
  148. package/dist/workbench/InspectorPanel.d.ts +6 -0
  149. package/dist/workbench/InspectorPanel.d.ts.map +1 -0
  150. package/dist/workbench/InspectorPanel.js +341 -0
  151. package/dist/workbench/PageNavigator.d.ts +6 -0
  152. package/dist/workbench/PageNavigator.d.ts.map +1 -0
  153. package/dist/workbench/PageNavigator.js +123 -0
  154. package/dist/workbench/SchemaPanel.d.ts +6 -0
  155. package/dist/workbench/SchemaPanel.d.ts.map +1 -0
  156. package/dist/workbench/SchemaPanel.js +222 -0
  157. package/dist/workbench/UserDataPanel.d.ts +6 -0
  158. package/dist/workbench/UserDataPanel.d.ts.map +1 -0
  159. package/dist/workbench/UserDataPanel.js +350 -0
  160. package/dist/workbench/WorkbenchApp.d.ts +6 -0
  161. package/dist/workbench/WorkbenchApp.d.ts.map +1 -0
  162. package/dist/workbench/WorkbenchApp.js +193 -0
  163. package/dist/workbench/cloudflare-worker/README.md +31 -0
  164. package/dist/workbench/cloudflare-worker/public/workbench.css +1614 -0
  165. package/dist/workbench/cloudflare-worker/public/workbench.js +77 -0
  166. package/dist/workbench/cloudflare-worker/worker.js +40 -0
  167. package/dist/workbench/cloudflare-worker/wrangler.toml +10 -0
  168. package/dist/workbench/index.d.ts +9 -0
  169. package/dist/workbench/index.d.ts.map +1 -0
  170. package/dist/workbench/index.js +44 -0
  171. package/dist/workbench/workbench.css +1614 -0
  172. package/dist/workbench/workbench.js +77 -0
  173. package/package.json +79 -0
@@ -0,0 +1,182 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ function collectVariantsFromConditions(conditions, experimentKey) {
4
+ if (!conditions)
5
+ return [];
6
+ const variants = [];
7
+ for (const cond of conditions) {
8
+ if (cond.key === experimentKey && Array.isArray(cond.values) && cond.values.length > 0) {
9
+ for (const value of cond.values) {
10
+ if (typeof value === 'string' && value !== '_no_value') {
11
+ variants.push(value);
12
+ }
13
+ }
14
+ }
15
+ }
16
+ return variants;
17
+ }
18
+ function collectVariantsFromFlowJson(flowJson, experimentKey) {
19
+ const variants = [];
20
+ const pages = flowJson.pages ?? [];
21
+ // Check global components
22
+ const globalComponents = flowJson.components ?? [];
23
+ for (const comp of globalComponents) {
24
+ variants.push(...collectVariantsFromConditions(comp.conditions, experimentKey));
25
+ }
26
+ for (const page of pages) {
27
+ // Check page-level conditions
28
+ variants.push(...collectVariantsFromConditions(page.conditions, experimentKey));
29
+ // Check page components
30
+ const pageComponents = page.components ?? [];
31
+ console.log('pageComponents', pageComponents);
32
+ for (const comp of pageComponents) {
33
+ variants.push(...collectVariantsFromConditions(comp.conditions, experimentKey));
34
+ }
35
+ }
36
+ // Dedupe and sort alphabetically
37
+ return [...new Set(variants)].sort();
38
+ }
39
+ export function ExperimentsPanel({ embeddableId }) {
40
+ const [experiments, setExperiments] = useState([]);
41
+ const [error, setError] = useState(null);
42
+ const savvy = window.Savvy;
43
+ const refresh = useCallback(() => {
44
+ setError(null);
45
+ if (!savvy?.getFlowJson) {
46
+ setError('window.Savvy.getFlowJson is not available.');
47
+ return;
48
+ }
49
+ if (!savvy?.getUserData) {
50
+ setError('window.Savvy.getUserData is not available.');
51
+ return;
52
+ }
53
+ try {
54
+ const flowJson = savvy.getFlowJson(embeddableId);
55
+ if (!flowJson) {
56
+ setError('Could not retrieve flow JSON.');
57
+ return;
58
+ }
59
+ const connectedExperiments = flowJson.connected_experiments ?? [];
60
+ const userData = savvy.getUserData(embeddableId) ?? {};
61
+ const experimentInfos = connectedExperiments.map((exp) => {
62
+ const variants = collectVariantsFromFlowJson(flowJson, exp.experiment_key);
63
+ const currentVariant = userData[exp.experiment_key] ?? null;
64
+ return {
65
+ experimentKey: exp.experiment_key,
66
+ experimentId: exp.experiment_id,
67
+ variants,
68
+ currentVariant,
69
+ };
70
+ });
71
+ setExperiments(experimentInfos);
72
+ }
73
+ catch (err) {
74
+ const message = err instanceof Error ? err.message : String(err);
75
+ setError(message);
76
+ }
77
+ }, [embeddableId, savvy]);
78
+ useEffect(() => {
79
+ const timer = setTimeout(() => {
80
+ refresh();
81
+ }, 500);
82
+ return () => clearTimeout(timer);
83
+ }, [refresh]);
84
+ const setVariant = async (experimentKey, variant) => {
85
+ if (!savvy?.getUserData || !savvy?.setUserData) {
86
+ setError('window.Savvy.getUserData/setUserData is not available.');
87
+ return;
88
+ }
89
+ try {
90
+ const userData = savvy.getUserData(embeddableId) ?? {};
91
+ await savvy.setUserData(embeddableId, {
92
+ ...userData,
93
+ [experimentKey]: variant,
94
+ });
95
+ refresh();
96
+ }
97
+ catch (err) {
98
+ const message = err instanceof Error ? err.message : String(err);
99
+ setError(message);
100
+ }
101
+ };
102
+ const resetAllToControl = async () => {
103
+ if (!savvy?.getUserData || !savvy?.setUserData) {
104
+ setError('window.Savvy.getUserData/setUserData is not available.');
105
+ return;
106
+ }
107
+ try {
108
+ const userData = savvy.getUserData(embeddableId) ?? {};
109
+ const updates = {};
110
+ for (const exp of experiments) {
111
+ if (exp.variants.length > 0) {
112
+ // First alphabetically is the "control"
113
+ updates[exp.experimentKey] = exp.variants[0];
114
+ }
115
+ }
116
+ await savvy.setUserData(embeddableId, {
117
+ ...userData,
118
+ ...updates,
119
+ });
120
+ refresh();
121
+ }
122
+ catch (err) {
123
+ const message = err instanceof Error ? err.message : String(err);
124
+ setError(message);
125
+ }
126
+ };
127
+ const shuffleAll = async () => {
128
+ if (!savvy?.getUserData || !savvy?.setUserData) {
129
+ setError('window.Savvy.getUserData/setUserData is not available.');
130
+ return;
131
+ }
132
+ try {
133
+ const userData = (await savvy.getUserData(embeddableId)) ?? {};
134
+ const updates = {};
135
+ for (const exp of experiments) {
136
+ if (exp.variants.length > 0) {
137
+ const randomIndex = Math.floor(Math.random() * exp.variants.length);
138
+ updates[exp.experimentKey] = exp.variants[randomIndex];
139
+ }
140
+ }
141
+ await savvy.setUserData(embeddableId, {
142
+ ...userData,
143
+ ...updates,
144
+ });
145
+ refresh();
146
+ }
147
+ catch (err) {
148
+ const message = err instanceof Error ? err.message : String(err);
149
+ setError(message);
150
+ }
151
+ };
152
+ const resetAllToNoValue = async () => {
153
+ if (!savvy?.getUserData || !savvy?.setUserData) {
154
+ setError('window.Savvy.getUserData/setUserData is not available.');
155
+ return;
156
+ }
157
+ try {
158
+ const userData = savvy.getUserData(embeddableId) ?? {};
159
+ const updates = {};
160
+ for (const exp of experiments) {
161
+ updates[exp.experimentKey] = undefined;
162
+ }
163
+ await savvy.setUserData(embeddableId, {
164
+ ...userData,
165
+ ...updates,
166
+ });
167
+ refresh();
168
+ }
169
+ catch (err) {
170
+ const message = err instanceof Error ? err.message : String(err);
171
+ setError(message);
172
+ }
173
+ };
174
+ return (_jsxs("div", { className: "mx-auto flex h-full w-full max-w-6xl flex-col", children: [_jsxs("div", { className: "flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-xs font-semibold tracking-wide text-slate-100", children: "Experiments" }), _jsx("div", { className: "mt-0.5 text-[11px] text-slate-400", children: "View and switch experiment variants for this embeddable." })] }), _jsxs("div", { className: "flex flex-wrap items-center justify-start gap-2 sm:justify-end", children: [_jsx("button", { type: "button", onClick: resetAllToNoValue, disabled: experiments.length === 0, className: "inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-slate-700 px-2.5 py-1.5 text-xs font-semibold text-slate-200 ring-1 ring-inset ring-slate-600 hover:bg-slate-600 hover:text-white disabled:cursor-not-allowed disabled:opacity-60", children: "Reset all to No Value" }), _jsx("button", { type: "button", onClick: resetAllToControl, disabled: experiments.length === 0, className: "inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-slate-700 px-2.5 py-1.5 text-xs font-semibold text-slate-200 ring-1 ring-inset ring-slate-600 hover:bg-slate-600 hover:text-white disabled:cursor-not-allowed disabled:opacity-60", children: "Reset all to Control" }), _jsx("button", { type: "button", onClick: shuffleAll, disabled: experiments.length === 0, className: "inline-flex cursor-pointer items-center gap-1.5 rounded-lg bg-slate-700 px-2.5 py-1.5 text-xs font-semibold text-slate-200 ring-1 ring-inset ring-slate-600 hover:bg-slate-600 hover:text-white disabled:cursor-not-allowed disabled:opacity-60", children: "Shuffle" })] })] }), error && (_jsx("div", { className: "mt-3 rounded-xl bg-rose-500/10 px-3 py-2 text-xs text-rose-200 ring-1 ring-inset ring-rose-500/20", children: error })), _jsxs("div", { className: "mt-4 flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto", children: [experiments.length === 0 && !error && (_jsx("div", { className: "text-[11px] text-slate-400", children: "No experiments connected to this embeddable." })), experiments.map((exp) => (_jsxs("div", { className: "rounded-xl bg-white/5 p-3 ring-1 ring-inset ring-white/10", children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsx("div", { className: "text-xs font-semibold text-slate-100", children: exp.experimentKey }), _jsx("div", { className: "text-[10px] text-slate-500", children: exp.experimentId })] }), exp.variants.length === 0 ? (_jsx("div", { className: "text-[11px] text-slate-400", children: "No variants found in conditions for this experiment." })) : (_jsxs("div", { className: "flex flex-wrap gap-2", children: [_jsx("button", { type: "button", onClick: () => setVariant(exp.experimentKey, undefined), className: `cursor-pointer rounded-lg px-3 py-1.5 text-xs font-medium transition-colors ${exp.currentVariant === null
175
+ ? 'bg-teal-500/20 text-teal-300 ring-1 ring-inset ring-teal-500/40'
176
+ : 'bg-slate-700 text-slate-300 ring-1 ring-inset ring-slate-600 hover:bg-slate-600 hover:text-white'}`, children: "No Value" }), exp.variants.map((variant) => {
177
+ const isSelected = exp.currentVariant === variant;
178
+ return (_jsx("button", { type: "button", onClick: () => setVariant(exp.experimentKey, variant), className: `cursor-pointer rounded-lg px-3 py-1.5 text-xs font-medium transition-colors ${isSelected
179
+ ? 'bg-teal-500/20 text-teal-300 ring-1 ring-inset ring-teal-500/40'
180
+ : 'bg-slate-700 text-slate-300 ring-1 ring-inset ring-slate-600 hover:bg-slate-600 hover:text-white'}`, children: variant }, variant));
181
+ })] }))] }, exp.experimentKey)))] })] }));
182
+ }
@@ -0,0 +1,9 @@
1
+ type FieldEditorPanelProps = {
2
+ embeddableId: string;
3
+ rawJson: string;
4
+ onUpdateUserData: (key: string, value: unknown) => void;
5
+ keyFilter: string;
6
+ };
7
+ export declare function FieldEditorPanel({ embeddableId, rawJson, onUpdateUserData, keyFilter, }: FieldEditorPanelProps): import("react/jsx-runtime").JSX.Element;
8
+ export {};
9
+ //# sourceMappingURL=FieldEditorPanel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FieldEditorPanel.d.ts","sourceRoot":"","sources":["../../src/workbench/FieldEditorPanel.tsx"],"names":[],"mappings":"AAGA,KAAK,qBAAqB,GAAG;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,CAAA;IACvD,SAAS,EAAE,MAAM,CAAA;CAClB,CAAA;AAkND,wBAAgB,gBAAgB,CAAC,EAC/B,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,SAAS,GACV,EAAE,qBAAqB,2CA+7BvB"}