@syntrologie/runtime-sdk 2.0.0 → 2.0.1-canary.1

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 (280) hide show
  1. package/CAPABILITIES.md +232 -138
  2. package/README.md +76 -57
  3. package/dist/RuntimeProvider.d.ts +6 -6
  4. package/dist/RuntimeProvider.js +2 -3
  5. package/dist/RuntimeProvider.js.map +1 -1
  6. package/dist/SmartCanvasApp.d.ts +8 -8
  7. package/dist/SmartCanvasApp.js +16 -18
  8. package/dist/SmartCanvasApp.js.map +1 -1
  9. package/dist/SmartCanvasElement.d.ts +5 -5
  10. package/dist/SmartCanvasElement.js +13 -13
  11. package/dist/SmartCanvasElement.js.map +1 -1
  12. package/dist/SmartCanvasPortal.d.ts +2 -2
  13. package/dist/SmartCanvasPortal.js +2 -2
  14. package/dist/actions/ActionEngine.d.ts +1 -1
  15. package/dist/actions/ActionEngine.js +24 -24
  16. package/dist/actions/ActionEngine.js.map +1 -1
  17. package/dist/actions/executors/index.d.ts +6 -6
  18. package/dist/actions/executors/index.js +22 -22
  19. package/dist/actions/executors/index.js.map +1 -1
  20. package/dist/actions/executors/tour.d.ts +1 -1
  21. package/dist/actions/executors/tour.js +19 -19
  22. package/dist/actions/executors/tour.js.map +1 -1
  23. package/dist/actions/index.d.ts +5 -5
  24. package/dist/actions/index.js +3 -3
  25. package/dist/actions/index.js.map +1 -1
  26. package/dist/actions/types.d.ts +37 -37
  27. package/dist/actions/validation.d.ts +1 -1
  28. package/dist/actions/validation.js +195 -196
  29. package/dist/actions/validation.js.map +1 -1
  30. package/dist/antiFlicker.js +1 -1
  31. package/dist/api.d.ts +10 -10
  32. package/dist/api.js +11 -11
  33. package/dist/api.js.map +1 -1
  34. package/dist/apps/AppContext.d.ts +2 -2
  35. package/dist/apps/AppContext.js +1 -1
  36. package/dist/apps/AppContext.js.map +1 -1
  37. package/dist/apps/AppLoader.d.ts +2 -2
  38. package/dist/apps/AppLoader.js +24 -24
  39. package/dist/apps/AppLoader.js.map +1 -1
  40. package/dist/apps/AppRegistry.d.ts +2 -2
  41. package/dist/apps/AppRegistry.js +28 -28
  42. package/dist/apps/AppRegistry.js.map +1 -1
  43. package/dist/apps/adaptive-chatbot/index.js +7 -0
  44. package/dist/apps/adaptive-chatbot/index.js.map +7 -0
  45. package/dist/apps/examples/gamification-app.example.d.ts +3 -3
  46. package/dist/apps/examples/gamification-app.example.js +94 -94
  47. package/dist/apps/examples/gamification-app.example.js.map +1 -1
  48. package/dist/apps/faq/index.js.map +3 -3
  49. package/dist/apps/gamification/index.js.map +3 -3
  50. package/dist/apps/index.d.ts +10 -10
  51. package/dist/apps/index.js +6 -6
  52. package/dist/apps/nav/index.js.map +3 -3
  53. package/dist/apps/types.d.ts +10 -10
  54. package/dist/blocks/data/ComparisonBlock.d.ts +1 -1
  55. package/dist/blocks/data/ComparisonBlock.js +40 -40
  56. package/dist/blocks/data/ComparisonBlock.js.map +1 -1
  57. package/dist/blocks/data/StatsBlock.d.ts +1 -1
  58. package/dist/blocks/data/StatsBlock.js +41 -41
  59. package/dist/blocks/data/StatsBlock.js.map +1 -1
  60. package/dist/blocks/data/index.d.ts +2 -2
  61. package/dist/blocks/data/index.js +2 -2
  62. package/dist/blocks/index.d.ts +5 -5
  63. package/dist/blocks/index.js +29 -29
  64. package/dist/blocks/index.js.map +1 -1
  65. package/dist/blocks/interactive/ChecklistBlock.d.ts +1 -1
  66. package/dist/blocks/interactive/ChecklistBlock.js +60 -60
  67. package/dist/blocks/interactive/ChecklistBlock.js.map +1 -1
  68. package/dist/blocks/interactive/RatingBlock.d.ts +1 -1
  69. package/dist/blocks/interactive/RatingBlock.js +75 -65
  70. package/dist/blocks/interactive/RatingBlock.js.map +1 -1
  71. package/dist/blocks/interactive/index.d.ts +2 -2
  72. package/dist/blocks/interactive/index.js +2 -2
  73. package/dist/blocks/notification/NotificationBlock.d.ts +2 -2
  74. package/dist/blocks/notification/NotificationBlock.js +67 -63
  75. package/dist/blocks/notification/NotificationBlock.js.map +1 -1
  76. package/dist/blocks/notification/index.d.ts +1 -1
  77. package/dist/blocks/notification/index.js +1 -1
  78. package/dist/bootstrap.d.ts +10 -10
  79. package/dist/bootstrap.js +54 -40
  80. package/dist/bootstrap.js.map +1 -1
  81. package/dist/components/ShadowCanvasOverlay.d.ts +6 -6
  82. package/dist/components/ShadowCanvasOverlay.js +117 -107
  83. package/dist/components/ShadowCanvasOverlay.js.map +1 -1
  84. package/dist/components/TileCard.d.ts +5 -5
  85. package/dist/components/TileCard.js +174 -143
  86. package/dist/components/TileCard.js.map +1 -1
  87. package/dist/components/TileWheel.d.ts +3 -3
  88. package/dist/components/TileWheel.js +7 -7
  89. package/dist/components/TileWheel.js.map +1 -1
  90. package/dist/configFetcher.d.ts +2 -2
  91. package/dist/configFetcher.js +10 -7
  92. package/dist/configFetcher.js.map +1 -1
  93. package/dist/context/ContextManager.d.ts +3 -3
  94. package/dist/context/ContextManager.js +15 -15
  95. package/dist/context/ContextManager.js.map +1 -1
  96. package/dist/context/index.d.ts +4 -4
  97. package/dist/context/index.js +3 -3
  98. package/dist/context/schema.d.ts +1 -1
  99. package/dist/context/schema.js +1 -1
  100. package/dist/decisions/engine.d.ts +5 -5
  101. package/dist/decisions/engine.js +13 -13
  102. package/dist/decisions/index.d.ts +6 -6
  103. package/dist/decisions/index.js +5 -5
  104. package/dist/decisions/schema.d.ts +1 -1
  105. package/dist/decisions/schema.js +20 -20
  106. package/dist/decisions/strategies/rules.d.ts +1 -1
  107. package/dist/decisions/strategies/rules.js +24 -24
  108. package/dist/decisions/strategies/rules.js.map +1 -1
  109. package/dist/decisions/strategies/score.d.ts +1 -1
  110. package/dist/decisions/strategies/score.js +3 -3
  111. package/dist/decisions/types.d.ts +19 -19
  112. package/dist/editorLoader.js +20 -20
  113. package/dist/editorLoader.js.map +1 -1
  114. package/dist/events/EventBus.d.ts +3 -3
  115. package/dist/events/EventBus.js +5 -7
  116. package/dist/events/EventBus.js.map +1 -1
  117. package/dist/events/index.d.ts +6 -6
  118. package/dist/events/index.js +5 -5
  119. package/dist/events/normalizers/canvas.d.ts +2 -2
  120. package/dist/events/normalizers/canvas.js +3 -3
  121. package/dist/events/normalizers/canvas.js.map +1 -1
  122. package/dist/events/normalizers/posthog.d.ts +1 -1
  123. package/dist/events/normalizers/posthog.js +35 -27
  124. package/dist/events/normalizers/posthog.js.map +1 -1
  125. package/dist/events/schema.d.ts +1 -1
  126. package/dist/events/schema.js +2 -2
  127. package/dist/events/types.d.ts +1 -1
  128. package/dist/events/types.js +27 -27
  129. package/dist/experiments/adapters/growthbook.d.ts +4 -4
  130. package/dist/experiments/adapters/growthbook.js +5 -5
  131. package/dist/experiments/adapters/growthbook.js.map +1 -1
  132. package/dist/experiments/index.d.ts +3 -3
  133. package/dist/experiments/index.js +1 -1
  134. package/dist/experiments/registry.d.ts +2 -2
  135. package/dist/experiments/registry.js +2 -2
  136. package/dist/experiments/types.d.ts +5 -1
  137. package/dist/fetchers/cdnFetcher.d.ts +1 -1
  138. package/dist/fetchers/cdnFetcher.js +4 -8
  139. package/dist/fetchers/cdnFetcher.js.map +1 -1
  140. package/dist/fetchers/experimentsFetcher.d.ts +2 -2
  141. package/dist/fetchers/experimentsFetcher.js +7 -7
  142. package/dist/fetchers/experimentsFetcher.js.map +1 -1
  143. package/dist/fetchers/index.d.ts +3 -3
  144. package/dist/fetchers/index.js +2 -2
  145. package/dist/fetchers/index.js.map +1 -1
  146. package/dist/fetchers/registry.d.ts +1 -1
  147. package/dist/fetchers/registry.js +4 -4
  148. package/dist/fetchers/types.d.ts +1 -1
  149. package/dist/hooks/useCanvasOverlays.d.ts +5 -5
  150. package/dist/hooks/useCanvasOverlays.js +15 -13
  151. package/dist/hooks/useCanvasOverlays.js.map +1 -1
  152. package/dist/hooks/useHostPatches.d.ts +2 -2
  153. package/dist/hooks/useHostPatches.js +8 -8
  154. package/dist/hooks/useHostPatches.js.map +1 -1
  155. package/dist/hooks/useShadowCanvasConfig.d.ts +3 -3
  156. package/dist/hooks/useShadowCanvasConfig.js +5 -2
  157. package/dist/hooks/useShadowCanvasConfig.js.map +1 -1
  158. package/dist/hostPatcher/core/patcher.d.ts +1 -1
  159. package/dist/hostPatcher/core/patcher.js +18 -9
  160. package/dist/hostPatcher/core/patcher.js.map +1 -1
  161. package/dist/hostPatcher/core/sanitizer.js +24 -3
  162. package/dist/hostPatcher/core/sanitizer.js.map +1 -1
  163. package/dist/hostPatcher/policy/defaultPolicy.js +15 -5
  164. package/dist/hostPatcher/policy/defaultPolicy.js.map +1 -1
  165. package/dist/hostPatcher/utils/anchors.js +4 -6
  166. package/dist/hostPatcher/utils/anchors.js.map +1 -1
  167. package/dist/index.d.ts +32 -32
  168. package/dist/index.js +29 -29
  169. package/dist/index.js.map +1 -1
  170. package/dist/metrics/index.d.ts +1 -1
  171. package/dist/metrics/index.js +1 -1
  172. package/dist/metrics/sessionMetrics.d.ts +1 -1
  173. package/dist/metrics/sessionMetrics.js +6 -6
  174. package/dist/overlays/fetcher.d.ts +2 -2
  175. package/dist/overlays/fetcher.js +4 -4
  176. package/dist/overlays/recipeRegistry.js +2 -2
  177. package/dist/overlays/recipeRegistry.js.map +1 -1
  178. package/dist/overlays/runtime/anchor/resolve.js +1 -1
  179. package/dist/overlays/runtime/anchor/resolve.js.map +1 -1
  180. package/dist/overlays/runtime/index.d.ts +7 -7
  181. package/dist/overlays/runtime/index.js +7 -7
  182. package/dist/overlays/runtime/overlay/highlight.js +39 -39
  183. package/dist/overlays/runtime/overlay/highlight.js.map +1 -1
  184. package/dist/overlays/runtime/overlay/modal.js +5 -5
  185. package/dist/overlays/runtime/overlay/modal.js.map +1 -1
  186. package/dist/overlays/runtime/overlay/root.js +1 -1
  187. package/dist/overlays/runtime/overlay/runner.js +70 -23
  188. package/dist/overlays/runtime/overlay/runner.js.map +1 -1
  189. package/dist/overlays/runtime/overlay/tooltip.d.ts +1 -1
  190. package/dist/overlays/runtime/overlay/tooltip.js +10 -10
  191. package/dist/overlays/runtime/overlay/tooltip.js.map +1 -1
  192. package/dist/overlays/runtime/utils/dom.js +4 -1
  193. package/dist/overlays/runtime/utils/dom.js.map +1 -1
  194. package/dist/overlays/schema.js +12 -8
  195. package/dist/overlays/schema.js.map +1 -1
  196. package/dist/react.d.ts +7 -7
  197. package/dist/react.js +4 -4
  198. package/dist/react.js.map +1 -1
  199. package/dist/render/RenderContext.d.ts +2 -2
  200. package/dist/render/RenderContext.js +5 -5
  201. package/dist/render/RenderContext.js.map +1 -1
  202. package/dist/render/index.d.ts +3 -3
  203. package/dist/render/index.js +1 -1
  204. package/dist/render/types.d.ts +4 -4
  205. package/dist/runtime.d.ts +12 -12
  206. package/dist/runtime.js +20 -20
  207. package/dist/runtime.js.map +1 -1
  208. package/dist/smart-canvas.esm.js +16 -16
  209. package/dist/smart-canvas.esm.js.map +4 -4
  210. package/dist/smart-canvas.js +644 -491
  211. package/dist/smart-canvas.js.map +4 -4
  212. package/dist/smart-canvas.min.js +15 -15
  213. package/dist/smart-canvas.min.js.map +4 -4
  214. package/dist/state/StateStore.d.ts +1 -1
  215. package/dist/state/StateStore.js +9 -9
  216. package/dist/state/StateStore.js.map +1 -1
  217. package/dist/state/helpers/cooldowns.d.ts +1 -1
  218. package/dist/state/helpers/cooldowns.js +1 -1
  219. package/dist/state/helpers/dismissals.d.ts +1 -1
  220. package/dist/state/helpers/dismissals.js +1 -1
  221. package/dist/state/helpers/frequency.d.ts +1 -1
  222. package/dist/state/helpers/frequency.js +1 -1
  223. package/dist/state/index.d.ts +4 -4
  224. package/dist/state/index.js +3 -3
  225. package/dist/state/schema.d.ts +1 -1
  226. package/dist/state/schema.js +1 -1
  227. package/dist/store/example.js +13 -13
  228. package/dist/store/example.js.map +1 -1
  229. package/dist/store/mini-effector.js +6 -8
  230. package/dist/store/mini-effector.js.map +1 -1
  231. package/dist/surfaces/Surfaces.d.ts +1 -1
  232. package/dist/surfaces/Surfaces.js +25 -25
  233. package/dist/surfaces/Surfaces.js.map +1 -1
  234. package/dist/surfaces/index.d.ts +4 -4
  235. package/dist/surfaces/index.js +3 -3
  236. package/dist/surfaces/positioning.d.ts +2 -2
  237. package/dist/surfaces/positioning.js +74 -77
  238. package/dist/surfaces/positioning.js.map +1 -1
  239. package/dist/surfaces/types.d.ts +9 -9
  240. package/dist/surfaces/types.js +7 -7
  241. package/dist/surfaces/types.js.map +1 -1
  242. package/dist/telemetry/adapters/noop.d.ts +12 -0
  243. package/dist/telemetry/adapters/noop.js +42 -0
  244. package/dist/telemetry/adapters/noop.js.map +1 -0
  245. package/dist/telemetry/adapters/posthog.d.ts +2 -2
  246. package/dist/telemetry/adapters/posthog.js +29 -16
  247. package/dist/telemetry/adapters/posthog.js.map +1 -1
  248. package/dist/telemetry/index.d.ts +4 -3
  249. package/dist/telemetry/index.js +3 -2
  250. package/dist/telemetry/index.js.map +1 -1
  251. package/dist/telemetry/registry.d.ts +2 -2
  252. package/dist/telemetry/registry.js +4 -2
  253. package/dist/telemetry/registry.js.map +1 -1
  254. package/dist/telemetry/types.d.ts +1 -1
  255. package/dist/theme/ThemeProvider.d.ts +2 -2
  256. package/dist/theme/ThemeProvider.js +21 -21
  257. package/dist/theme/ThemeProvider.js.map +1 -1
  258. package/dist/theme/defaultTheme.d.ts +2 -2
  259. package/dist/theme/defaultTheme.js +111 -111
  260. package/dist/theme/defaultTheme.js.map +1 -1
  261. package/dist/theme/extractHostTheme.d.ts +1 -1
  262. package/dist/theme/extractHostTheme.js +42 -44
  263. package/dist/theme/extractHostTheme.js.map +1 -1
  264. package/dist/theme/index.d.ts +5 -5
  265. package/dist/theme/index.js +3 -3
  266. package/dist/theme/index.js.map +1 -1
  267. package/dist/theme/types.d.ts +2 -2
  268. package/dist/token.js +3 -6
  269. package/dist/token.js.map +1 -1
  270. package/dist/types-only.d.ts +1 -1
  271. package/dist/types.d.ts +43 -43
  272. package/dist/widgets/WidgetRegistry.d.ts +2 -2
  273. package/dist/widgets/WidgetRegistry.js +11 -11
  274. package/dist/widgets/WidgetRegistry.js.map +1 -1
  275. package/dist/widgets/index.d.ts +2 -2
  276. package/dist/widgets/index.js +1 -1
  277. package/dist/widgets/index.js.map +1 -1
  278. package/package.json +4 -2
  279. package/schema/canvas-config.schema.json +51 -7
  280. package/schema/runtime-context.schema.json +1 -5
@@ -3,41 +3,41 @@
3
3
  *
4
4
  * Validates action steps before execution.
5
5
  */
6
- import { hasExecutor } from "./executors";
6
+ import { hasExecutor } from './executors';
7
7
  /** Known action kinds */
8
8
  const VALID_KINDS = [
9
- "overlays:highlight",
10
- "overlays:pulse",
11
- "overlays:badge",
12
- "overlays:tooltip",
13
- "overlays:modal",
14
- "content:insertHtml",
15
- "content:setText",
16
- "content:setAttr",
17
- "content:addClass",
18
- "content:removeClass",
19
- "content:setStyle",
20
- "core:mountWidget",
21
- "core:wait",
22
- "core:sequence",
23
- "core:parallel",
24
- "core:tour",
25
- "navigation:scrollTo",
26
- "navigation:navigate",
9
+ 'overlays:highlight',
10
+ 'overlays:pulse',
11
+ 'overlays:badge',
12
+ 'overlays:tooltip',
13
+ 'overlays:modal',
14
+ 'content:insertHtml',
15
+ 'content:setText',
16
+ 'content:setAttr',
17
+ 'content:addClass',
18
+ 'content:removeClass',
19
+ 'content:setStyle',
20
+ 'core:mountWidget',
21
+ 'core:wait',
22
+ 'core:sequence',
23
+ 'core:parallel',
24
+ 'core:tour',
25
+ 'navigation:scrollTo',
26
+ 'navigation:navigate',
27
27
  ];
28
28
  /** Dangerous attribute names that should not be set */
29
29
  const DANGEROUS_ATTRS = new Set([
30
- "onclick",
31
- "onerror",
32
- "onload",
33
- "onmouseover",
34
- "onfocus",
35
- "onblur",
36
- "onchange",
37
- "onsubmit",
38
- "onkeydown",
39
- "onkeyup",
40
- "onkeypress",
30
+ 'onclick',
31
+ 'onerror',
32
+ 'onload',
33
+ 'onmouseover',
34
+ 'onfocus',
35
+ 'onblur',
36
+ 'onchange',
37
+ 'onsubmit',
38
+ 'onkeydown',
39
+ 'onkeyup',
40
+ 'onkeypress',
41
41
  ]);
42
42
  /** Maximum HTML content length */
43
43
  const MAX_HTML_LENGTH = 50000;
@@ -50,93 +50,93 @@ export function validateAction(action) {
50
50
  const errors = [];
51
51
  const warnings = [];
52
52
  // Check action has a kind
53
- if (!action || typeof action !== "object") {
53
+ if (!action || typeof action !== 'object') {
54
54
  errors.push({
55
- code: "INVALID_ACTION",
56
- message: "Action must be an object",
55
+ code: 'INVALID_ACTION',
56
+ message: 'Action must be an object',
57
57
  });
58
58
  return { valid: false, errors, warnings };
59
59
  }
60
60
  const kind = action.kind;
61
61
  // Check kind is valid
62
- if (!kind || typeof kind !== "string") {
62
+ if (!kind || typeof kind !== 'string') {
63
63
  errors.push({
64
- code: "MISSING_KIND",
64
+ code: 'MISSING_KIND',
65
65
  message: "Action must have a 'kind' property",
66
66
  });
67
67
  return { valid: false, errors, warnings };
68
68
  }
69
69
  if (!VALID_KINDS.includes(kind)) {
70
70
  errors.push({
71
- code: "UNKNOWN_KIND",
71
+ code: 'UNKNOWN_KIND',
72
72
  message: `Unknown action kind: ${kind}`,
73
- field: "kind",
73
+ field: 'kind',
74
74
  });
75
75
  return { valid: false, errors, warnings };
76
76
  }
77
77
  // Check executor exists
78
- if (!hasExecutor(kind) && kind !== "core:mountWidget") {
78
+ if (!hasExecutor(kind) && kind !== 'core:mountWidget') {
79
79
  errors.push({
80
- code: "NO_EXECUTOR",
80
+ code: 'NO_EXECUTOR',
81
81
  message: `No executor registered for action kind: ${kind}`,
82
- field: "kind",
82
+ field: 'kind',
83
83
  });
84
84
  }
85
85
  // Kind-specific validation
86
86
  switch (kind) {
87
- case "overlays:highlight":
88
- case "overlays:pulse":
89
- case "navigation:scrollTo":
87
+ case 'overlays:highlight':
88
+ case 'overlays:pulse':
89
+ case 'navigation:scrollTo':
90
90
  validateAnchorAction(action, errors, warnings);
91
91
  break;
92
- case "overlays:badge":
92
+ case 'overlays:badge':
93
93
  validateAnchorAction(action, errors, warnings);
94
94
  validateBadgeAction(action, errors, warnings);
95
95
  break;
96
- case "overlays:tooltip":
96
+ case 'overlays:tooltip':
97
97
  validateAnchorAction(action, errors, warnings);
98
98
  validateTooltipAction(action, errors, warnings);
99
99
  break;
100
- case "overlays:modal":
100
+ case 'overlays:modal':
101
101
  validateModalAction(action, errors, warnings);
102
102
  break;
103
- case "content:insertHtml":
103
+ case 'content:insertHtml':
104
104
  validateAnchorAction(action, errors, warnings);
105
105
  validateInsertHtmlAction(action, errors, warnings);
106
106
  break;
107
- case "content:setText":
107
+ case 'content:setText':
108
108
  validateAnchorAction(action, errors, warnings);
109
109
  validateSetTextAction(action, errors, warnings);
110
110
  break;
111
- case "content:setAttr":
111
+ case 'content:setAttr':
112
112
  validateAnchorAction(action, errors, warnings);
113
113
  validateSetAttrAction(action, errors, warnings);
114
114
  break;
115
- case "content:addClass":
116
- case "content:removeClass":
115
+ case 'content:addClass':
116
+ case 'content:removeClass':
117
117
  validateAnchorAction(action, errors, warnings);
118
118
  validateClassAction(action, errors, warnings);
119
119
  break;
120
- case "content:setStyle":
120
+ case 'content:setStyle':
121
121
  validateAnchorAction(action, errors, warnings);
122
122
  validateSetStyleAction(action, errors, warnings);
123
123
  break;
124
- case "core:mountWidget":
124
+ case 'core:mountWidget':
125
125
  validateMountWidgetAction(action, errors, warnings);
126
126
  break;
127
- case "core:wait":
127
+ case 'core:wait':
128
128
  validateWaitAction(action, errors, warnings);
129
129
  break;
130
- case "core:sequence":
130
+ case 'core:sequence':
131
131
  validateSequenceAction(action, errors, warnings);
132
132
  break;
133
- case "core:parallel":
133
+ case 'core:parallel':
134
134
  validateParallelAction(action, errors, warnings);
135
135
  break;
136
- case "core:tour":
136
+ case 'core:tour':
137
137
  validateTourAction(action, errors, warnings);
138
138
  break;
139
- case "navigation:navigate":
139
+ case 'navigation:navigate':
140
140
  validateNavigateAction(action, errors, warnings);
141
141
  break;
142
142
  }
@@ -147,148 +147,149 @@ export function validateAction(action) {
147
147
  };
148
148
  }
149
149
  function validateAnchorAction(action, errors, warnings) {
150
- if (!action.anchorId || typeof action.anchorId !== "string") {
150
+ if (!action.anchorId || typeof action.anchorId !== 'string') {
151
151
  errors.push({
152
- code: "MISSING_ANCHOR_ID",
152
+ code: 'MISSING_ANCHOR_ID',
153
153
  message: "Action requires an 'anchorId' property",
154
- field: "anchorId",
154
+ field: 'anchorId',
155
155
  });
156
156
  }
157
157
  else if (action.anchorId.length > 200) {
158
158
  warnings.push({
159
- code: "LONG_ANCHOR_ID",
160
- message: "Anchor ID is unusually long",
161
- suggestion: "Consider using a shorter, more descriptive ID",
159
+ code: 'LONG_ANCHOR_ID',
160
+ message: 'Anchor ID is unusually long',
161
+ suggestion: 'Consider using a shorter, more descriptive ID',
162
162
  });
163
163
  }
164
164
  }
165
165
  function validateBadgeAction(action, errors, warnings) {
166
- if (!action.content || typeof action.content !== "string") {
166
+ if (!action.content || typeof action.content !== 'string') {
167
167
  errors.push({
168
- code: "MISSING_CONTENT",
168
+ code: 'MISSING_CONTENT',
169
169
  message: "Badge action requires 'content' property",
170
- field: "content",
170
+ field: 'content',
171
171
  });
172
172
  }
173
173
  else if (action.content.length > 100) {
174
174
  warnings.push({
175
- code: "LONG_BADGE_CONTENT",
176
- message: "Badge content is quite long",
177
- suggestion: "Keep badge content short (under 100 characters)",
175
+ code: 'LONG_BADGE_CONTENT',
176
+ message: 'Badge content is quite long',
177
+ suggestion: 'Keep badge content short (under 100 characters)',
178
178
  });
179
179
  }
180
180
  }
181
- function validateTooltipAction(action, errors, warnings) {
182
- if (!action.content || typeof action.content !== "object") {
181
+ function validateTooltipAction(action, errors, _warnings) {
182
+ if (!action.content || typeof action.content !== 'object') {
183
183
  errors.push({
184
- code: "MISSING_CONTENT",
184
+ code: 'MISSING_CONTENT',
185
185
  message: "Tooltip action requires 'content' object",
186
- field: "content",
186
+ field: 'content',
187
187
  });
188
188
  return;
189
189
  }
190
- if (!action.content.body || typeof action.content.body !== "string") {
190
+ if (!action.content.body || typeof action.content.body !== 'string') {
191
191
  errors.push({
192
- code: "MISSING_BODY",
192
+ code: 'MISSING_BODY',
193
193
  message: "Tooltip content requires 'body' property",
194
- field: "content.body",
194
+ field: 'content.body',
195
195
  });
196
196
  }
197
197
  }
198
- function validateInsertHtmlAction(action, errors, warnings) {
199
- if (!action.html || typeof action.html !== "string") {
198
+ function validateInsertHtmlAction(action, errors, _warnings) {
199
+ if (!action.html || typeof action.html !== 'string') {
200
200
  errors.push({
201
- code: "MISSING_HTML",
201
+ code: 'MISSING_HTML',
202
202
  message: "insertHtml action requires 'html' property",
203
- field: "html",
203
+ field: 'html',
204
204
  });
205
205
  }
206
206
  else if (action.html.length > MAX_HTML_LENGTH) {
207
207
  errors.push({
208
- code: "HTML_TOO_LONG",
208
+ code: 'HTML_TOO_LONG',
209
209
  message: `HTML content exceeds maximum length of ${MAX_HTML_LENGTH}`,
210
- field: "html",
210
+ field: 'html',
211
211
  });
212
212
  }
213
- const validPositions = ["before", "after", "prepend", "append", "replace"];
213
+ const validPositions = ['before', 'after', 'prepend', 'append', 'replace'];
214
214
  if (!action.position || !validPositions.includes(action.position)) {
215
215
  errors.push({
216
- code: "INVALID_POSITION",
217
- message: `Position must be one of: ${validPositions.join(", ")}`,
218
- field: "position",
216
+ code: 'INVALID_POSITION',
217
+ message: `Position must be one of: ${validPositions.join(', ')}`,
218
+ field: 'position',
219
219
  });
220
220
  }
221
221
  }
222
- function validateSetTextAction(action, errors, warnings) {
222
+ function validateSetTextAction(action, errors, _warnings) {
223
223
  if (action.text === undefined || action.text === null) {
224
224
  errors.push({
225
- code: "MISSING_TEXT",
225
+ code: 'MISSING_TEXT',
226
226
  message: "setText action requires 'text' property",
227
- field: "text",
227
+ field: 'text',
228
228
  });
229
229
  }
230
230
  }
231
- function validateSetAttrAction(action, errors, warnings) {
232
- if (!action.attr || typeof action.attr !== "string") {
231
+ function validateSetAttrAction(action, errors, _warnings) {
232
+ if (!action.attr || typeof action.attr !== 'string') {
233
233
  errors.push({
234
- code: "MISSING_ATTR",
234
+ code: 'MISSING_ATTR',
235
235
  message: "setAttr action requires 'attr' property",
236
- field: "attr",
236
+ field: 'attr',
237
237
  });
238
238
  }
239
- else if (DANGEROUS_ATTRS.has(action.attr.toLowerCase()) || action.attr.toLowerCase().startsWith("on")) {
239
+ else if (DANGEROUS_ATTRS.has(action.attr.toLowerCase()) ||
240
+ action.attr.toLowerCase().startsWith('on')) {
240
241
  errors.push({
241
- code: "DANGEROUS_ATTR",
242
+ code: 'DANGEROUS_ATTR',
242
243
  message: `Event handler attributes are not allowed: ${action.attr}`,
243
- field: "attr",
244
+ field: 'attr',
244
245
  });
245
246
  }
246
247
  if (action.value === undefined || action.value === null) {
247
248
  errors.push({
248
- code: "MISSING_VALUE",
249
+ code: 'MISSING_VALUE',
249
250
  message: "setAttr action requires 'value' property",
250
- field: "value",
251
+ field: 'value',
251
252
  });
252
253
  }
253
254
  }
254
255
  function validateClassAction(action, errors, warnings) {
255
- if (!action.className || typeof action.className !== "string") {
256
+ if (!action.className || typeof action.className !== 'string') {
256
257
  errors.push({
257
- code: "MISSING_CLASS_NAME",
258
+ code: 'MISSING_CLASS_NAME',
258
259
  message: "Class action requires 'className' property",
259
- field: "className",
260
+ field: 'className',
260
261
  });
261
262
  }
262
263
  else if (!/^[a-zA-Z_-][a-zA-Z0-9_-]*$/.test(action.className)) {
263
264
  warnings.push({
264
- code: "INVALID_CLASS_NAME",
265
- message: "Class name contains unusual characters",
266
- suggestion: "Use alphanumeric characters, hyphens, and underscores",
265
+ code: 'INVALID_CLASS_NAME',
266
+ message: 'Class name contains unusual characters',
267
+ suggestion: 'Use alphanumeric characters, hyphens, and underscores',
267
268
  });
268
269
  }
269
270
  }
270
- function validateSetStyleAction(action, errors, warnings) {
271
- if (!action.styles || typeof action.styles !== "object") {
271
+ function validateSetStyleAction(action, errors, _warnings) {
272
+ if (!action.styles || typeof action.styles !== 'object') {
272
273
  errors.push({
273
- code: "MISSING_STYLES",
274
+ code: 'MISSING_STYLES',
274
275
  message: "setStyle action requires 'styles' object",
275
- field: "styles",
276
+ field: 'styles',
276
277
  });
277
278
  }
278
279
  else {
279
280
  const styleCount = Object.keys(action.styles).length;
280
281
  if (styleCount > MAX_STYLE_COUNT) {
281
282
  errors.push({
282
- code: "TOO_MANY_STYLES",
283
+ code: 'TOO_MANY_STYLES',
283
284
  message: `Too many styles (${styleCount}). Maximum is ${MAX_STYLE_COUNT}`,
284
- field: "styles",
285
+ field: 'styles',
285
286
  });
286
287
  }
287
288
  // Check for potentially dangerous style values
288
289
  for (const [prop, value] of Object.entries(action.styles)) {
289
- if (typeof value === "string" && value.includes("expression(")) {
290
+ if (typeof value === 'string' && value.includes('expression(')) {
290
291
  errors.push({
291
- code: "DANGEROUS_STYLE",
292
+ code: 'DANGEROUS_STYLE',
292
293
  message: `Style expressions are not allowed: ${prop}`,
293
294
  field: `styles.${prop}`,
294
295
  });
@@ -296,65 +297,65 @@ function validateSetStyleAction(action, errors, warnings) {
296
297
  }
297
298
  }
298
299
  }
299
- function validateMountWidgetAction(action, errors, warnings) {
300
- if (!action.slot || typeof action.slot !== "string") {
300
+ function validateMountWidgetAction(action, errors, _warnings) {
301
+ if (!action.slot || typeof action.slot !== 'string') {
301
302
  errors.push({
302
- code: "MISSING_SLOT",
303
+ code: 'MISSING_SLOT',
303
304
  message: "mountWidget action requires 'slot' property",
304
- field: "slot",
305
+ field: 'slot',
305
306
  });
306
307
  }
307
- if (!action.widget || typeof action.widget !== "object") {
308
+ if (!action.widget || typeof action.widget !== 'object') {
308
309
  errors.push({
309
- code: "MISSING_WIDGET",
310
+ code: 'MISSING_WIDGET',
310
311
  message: "mountWidget action requires 'widget' object",
311
- field: "widget",
312
+ field: 'widget',
312
313
  });
313
314
  }
314
- else if (!action.widget.widgetId || typeof action.widget.widgetId !== "string") {
315
+ else if (!action.widget.widgetId || typeof action.widget.widgetId !== 'string') {
315
316
  errors.push({
316
- code: "MISSING_WIDGET_ID",
317
+ code: 'MISSING_WIDGET_ID',
317
318
  message: "Widget must have a 'widgetId' property",
318
- field: "widget.widgetId",
319
+ field: 'widget.widgetId',
319
320
  });
320
321
  }
321
322
  }
322
- function validateWaitAction(action, errors, warnings) {
323
+ function validateWaitAction(action, errors, _warnings) {
323
324
  if (action.durationMs === undefined && !action.event) {
324
325
  errors.push({
325
- code: "MISSING_WAIT_CONFIG",
326
+ code: 'MISSING_WAIT_CONFIG',
326
327
  message: "wait action requires either 'durationMs' or 'event' property",
327
328
  });
328
329
  }
329
330
  if (action.durationMs !== undefined && action.durationMs < 0) {
330
331
  errors.push({
331
- code: "INVALID_DURATION",
332
- message: "durationMs must be a positive number",
333
- field: "durationMs",
332
+ code: 'INVALID_DURATION',
333
+ message: 'durationMs must be a positive number',
334
+ field: 'durationMs',
334
335
  });
335
336
  }
336
- if (action.event !== undefined && typeof action.event !== "string") {
337
+ if (action.event !== undefined && typeof action.event !== 'string') {
337
338
  errors.push({
338
- code: "INVALID_EVENT",
339
- message: "event must be a string",
340
- field: "event",
339
+ code: 'INVALID_EVENT',
340
+ message: 'event must be a string',
341
+ field: 'event',
341
342
  });
342
343
  }
343
344
  }
344
345
  function validateSequenceAction(action, errors, warnings) {
345
346
  if (!action.actions || !Array.isArray(action.actions)) {
346
347
  errors.push({
347
- code: "MISSING_ACTIONS",
348
+ code: 'MISSING_ACTIONS',
348
349
  message: "sequence action requires 'actions' array",
349
- field: "actions",
350
+ field: 'actions',
350
351
  });
351
352
  return;
352
353
  }
353
354
  if (action.actions.length === 0) {
354
355
  warnings.push({
355
- code: "EMPTY_SEQUENCE",
356
- message: "sequence has no actions",
357
- suggestion: "Add at least one action to the sequence",
356
+ code: 'EMPTY_SEQUENCE',
357
+ message: 'sequence has no actions',
358
+ suggestion: 'Add at least one action to the sequence',
358
359
  });
359
360
  }
360
361
  // Recursively validate nested actions
@@ -363,7 +364,7 @@ function validateSequenceAction(action, errors, warnings) {
363
364
  for (const error of result.errors) {
364
365
  errors.push({
365
366
  ...error,
366
- field: `actions[${i}]${error.field ? `.${error.field}` : ""}`,
367
+ field: `actions[${i}]${error.field ? `.${error.field}` : ''}`,
367
368
  });
368
369
  }
369
370
  for (const warning of result.warnings) {
@@ -374,24 +375,24 @@ function validateSequenceAction(action, errors, warnings) {
374
375
  function validateParallelAction(action, errors, warnings) {
375
376
  if (!action.actions || !Array.isArray(action.actions)) {
376
377
  errors.push({
377
- code: "MISSING_ACTIONS",
378
+ code: 'MISSING_ACTIONS',
378
379
  message: "parallel action requires 'actions' array",
379
- field: "actions",
380
+ field: 'actions',
380
381
  });
381
382
  return;
382
383
  }
383
384
  if (action.actions.length === 0) {
384
385
  warnings.push({
385
- code: "EMPTY_PARALLEL",
386
- message: "parallel has no actions",
387
- suggestion: "Add at least one action to the parallel group",
386
+ code: 'EMPTY_PARALLEL',
387
+ message: 'parallel has no actions',
388
+ suggestion: 'Add at least one action to the parallel group',
388
389
  });
389
390
  }
390
- if (action.waitFor && !["all", "any"].includes(action.waitFor)) {
391
+ if (action.waitFor && !['all', 'any'].includes(action.waitFor)) {
391
392
  errors.push({
392
- code: "INVALID_WAIT_FOR",
393
+ code: 'INVALID_WAIT_FOR',
393
394
  message: "waitFor must be 'all' or 'any'",
394
- field: "waitFor",
395
+ field: 'waitFor',
395
396
  });
396
397
  }
397
398
  // Recursively validate nested actions
@@ -400,7 +401,7 @@ function validateParallelAction(action, errors, warnings) {
400
401
  for (const error of result.errors) {
401
402
  errors.push({
402
403
  ...error,
403
- field: `actions[${i}]${error.field ? `.${error.field}` : ""}`,
404
+ field: `actions[${i}]${error.field ? `.${error.field}` : ''}`,
404
405
  });
405
406
  }
406
407
  for (const warning of result.warnings) {
@@ -409,76 +410,76 @@ function validateParallelAction(action, errors, warnings) {
409
410
  }
410
411
  }
411
412
  function validateNavigateAction(action, errors, warnings) {
412
- if (!action.url || typeof action.url !== "string") {
413
+ if (!action.url || typeof action.url !== 'string') {
413
414
  errors.push({
414
- code: "MISSING_URL",
415
+ code: 'MISSING_URL',
415
416
  message: "navigate action requires 'url' property",
416
- field: "url",
417
+ field: 'url',
417
418
  });
418
419
  }
419
420
  else {
420
421
  const url = action.url.trim().toLowerCase();
421
- if (url.startsWith("javascript:")) {
422
+ if (url.startsWith('javascript:')) {
422
423
  errors.push({
423
- code: "DANGEROUS_URL",
424
- message: "javascript: URLs are not allowed",
425
- field: "url",
424
+ code: 'DANGEROUS_URL',
425
+ message: 'javascript: URLs are not allowed',
426
+ field: 'url',
426
427
  });
427
428
  }
428
429
  // Warn about data: URLs
429
- if (url.startsWith("data:")) {
430
+ if (url.startsWith('data:')) {
430
431
  warnings.push({
431
- code: "DATA_URL",
432
- message: "data: URLs may have limited support",
433
- suggestion: "Consider using a regular URL instead",
432
+ code: 'DATA_URL',
433
+ message: 'data: URLs may have limited support',
434
+ suggestion: 'Consider using a regular URL instead',
434
435
  });
435
436
  }
436
437
  }
437
438
  }
438
- function validateModalAction(action, errors, warnings) {
439
- if (!action.content || typeof action.content !== "object") {
439
+ function validateModalAction(action, errors, _warnings) {
440
+ if (!action.content || typeof action.content !== 'object') {
440
441
  errors.push({
441
- code: "MISSING_CONTENT",
442
+ code: 'MISSING_CONTENT',
442
443
  message: "Modal action requires 'content' object",
443
- field: "content",
444
+ field: 'content',
444
445
  });
445
446
  return;
446
447
  }
447
- if (!action.content.body || typeof action.content.body !== "string") {
448
+ if (!action.content.body || typeof action.content.body !== 'string') {
448
449
  errors.push({
449
- code: "MISSING_BODY",
450
+ code: 'MISSING_BODY',
450
451
  message: "Modal content requires 'body' property",
451
- field: "content.body",
452
+ field: 'content.body',
452
453
  });
453
454
  }
454
- if (action.size && !["sm", "md", "lg"].includes(action.size)) {
455
+ if (action.size && !['sm', 'md', 'lg'].includes(action.size)) {
455
456
  errors.push({
456
- code: "INVALID_SIZE",
457
+ code: 'INVALID_SIZE',
457
458
  message: "Modal size must be 'sm', 'md', or 'lg'",
458
- field: "size",
459
+ field: 'size',
459
460
  });
460
461
  }
461
462
  if (action.ctaButtons) {
462
463
  if (!Array.isArray(action.ctaButtons)) {
463
464
  errors.push({
464
- code: "INVALID_CTA_BUTTONS",
465
- message: "ctaButtons must be an array",
466
- field: "ctaButtons",
465
+ code: 'INVALID_CTA_BUTTONS',
466
+ message: 'ctaButtons must be an array',
467
+ field: 'ctaButtons',
467
468
  });
468
469
  }
469
470
  else {
470
471
  for (let i = 0; i < action.ctaButtons.length; i++) {
471
472
  const btn = action.ctaButtons[i];
472
- if (!btn.label || typeof btn.label !== "string") {
473
+ if (!btn.label || typeof btn.label !== 'string') {
473
474
  errors.push({
474
- code: "MISSING_BUTTON_LABEL",
475
+ code: 'MISSING_BUTTON_LABEL',
475
476
  message: `CTA button at index ${i} requires 'label' property`,
476
477
  field: `ctaButtons[${i}].label`,
477
478
  });
478
479
  }
479
- if (!btn.actionId || typeof btn.actionId !== "string") {
480
+ if (!btn.actionId || typeof btn.actionId !== 'string') {
480
481
  errors.push({
481
- code: "MISSING_BUTTON_ACTION_ID",
482
+ code: 'MISSING_BUTTON_ACTION_ID',
482
483
  message: `CTA button at index ${i} requires 'actionId' property`,
483
484
  field: `ctaButtons[${i}].actionId`,
484
485
  });
@@ -488,34 +489,34 @@ function validateModalAction(action, errors, warnings) {
488
489
  }
489
490
  }
490
491
  function validateTourAction(action, errors, warnings) {
491
- if (!action.tourId || typeof action.tourId !== "string") {
492
+ if (!action.tourId || typeof action.tourId !== 'string') {
492
493
  errors.push({
493
- code: "MISSING_TOUR_ID",
494
+ code: 'MISSING_TOUR_ID',
494
495
  message: "Tour action requires 'tourId' property",
495
- field: "tourId",
496
+ field: 'tourId',
496
497
  });
497
498
  }
498
499
  if (!action.steps || !Array.isArray(action.steps)) {
499
500
  errors.push({
500
- code: "MISSING_STEPS",
501
+ code: 'MISSING_STEPS',
501
502
  message: "Tour action requires 'steps' array",
502
- field: "steps",
503
+ field: 'steps',
503
504
  });
504
505
  return;
505
506
  }
506
507
  if (action.steps.length === 0) {
507
508
  errors.push({
508
- code: "EMPTY_STEPS",
509
- message: "Tour must have at least one step",
510
- field: "steps",
509
+ code: 'EMPTY_STEPS',
510
+ message: 'Tour must have at least one step',
511
+ field: 'steps',
511
512
  });
512
513
  }
513
514
  const stepIds = new Set();
514
515
  for (let i = 0; i < action.steps.length; i++) {
515
516
  const step = action.steps[i];
516
- if (!step.id || typeof step.id !== "string") {
517
+ if (!step.id || typeof step.id !== 'string') {
517
518
  errors.push({
518
- code: "MISSING_STEP_ID",
519
+ code: 'MISSING_STEP_ID',
519
520
  message: `Step at index ${i} requires 'id' property`,
520
521
  field: `steps[${i}].id`,
521
522
  });
@@ -523,7 +524,7 @@ function validateTourAction(action, errors, warnings) {
523
524
  else {
524
525
  if (stepIds.has(step.id)) {
525
526
  errors.push({
526
- code: "DUPLICATE_STEP_ID",
527
+ code: 'DUPLICATE_STEP_ID',
527
528
  message: `Duplicate step ID: ${step.id}`,
528
529
  field: `steps[${i}].id`,
529
530
  });
@@ -532,7 +533,7 @@ function validateTourAction(action, errors, warnings) {
532
533
  }
533
534
  if (!step.action) {
534
535
  errors.push({
535
- code: "MISSING_STEP_ACTION",
536
+ code: 'MISSING_STEP_ACTION',
536
537
  message: `Step at index ${i} requires 'action' property`,
537
538
  field: `steps[${i}].action`,
538
539
  });
@@ -543,7 +544,7 @@ function validateTourAction(action, errors, warnings) {
543
544
  for (const error of result.errors) {
544
545
  errors.push({
545
546
  ...error,
546
- field: `steps[${i}].action${error.field ? `.${error.field}` : ""}`,
547
+ field: `steps[${i}].action${error.field ? `.${error.field}` : ''}`,
547
548
  });
548
549
  }
549
550
  for (const warning of result.warnings) {
@@ -552,10 +553,10 @@ function validateTourAction(action, errors, warnings) {
552
553
  }
553
554
  // Validate onAction references
554
555
  if (step.onAction) {
555
- for (const [actionId, targetStepId] of Object.entries(step.onAction)) {
556
- if (targetStepId !== "end" && !action.steps.some((s) => s.id === targetStepId)) {
556
+ for (const [_actionId, targetStepId] of Object.entries(step.onAction)) {
557
+ if (targetStepId !== 'end' && !action.steps.some((s) => s.id === targetStepId)) {
557
558
  warnings.push({
558
- code: "UNKNOWN_TARGET_STEP",
559
+ code: 'UNKNOWN_TARGET_STEP',
559
560
  message: `Step "${step.id}" references unknown target step: ${targetStepId}`,
560
561
  suggestion: `Make sure step "${targetStepId}" exists in the tour`,
561
562
  });
@@ -572,8 +573,8 @@ export function validateActions(actions) {
572
573
  const warnings = [];
573
574
  if (!Array.isArray(actions)) {
574
575
  errors.push({
575
- code: "INVALID_ACTIONS",
576
- message: "Actions must be an array",
576
+ code: 'INVALID_ACTIONS',
577
+ message: 'Actions must be an array',
577
578
  });
578
579
  return { valid: false, errors, warnings };
579
580
  }
@@ -588,9 +589,7 @@ export function validateActions(actions) {
588
589
  for (const warning of result.warnings) {
589
590
  warnings.push({
590
591
  ...warning,
591
- suggestion: warning.suggestion
592
- ? `Action ${i}: ${warning.suggestion}`
593
- : undefined,
592
+ suggestion: warning.suggestion ? `Action ${i}: ${warning.suggestion}` : undefined,
594
593
  });
595
594
  }
596
595
  }