@frontmcp/uipack 0.12.1 → 1.0.0-beta.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 (298) hide show
  1. package/CLAUDE.md +56 -154
  2. package/README.md +367 -62
  3. package/adapters/base-template.d.ts +30 -0
  4. package/adapters/base-template.d.ts.map +1 -0
  5. package/adapters/cdn-info.d.ts +34 -0
  6. package/adapters/cdn-info.d.ts.map +1 -0
  7. package/adapters/constants.d.ts +18 -0
  8. package/adapters/constants.d.ts.map +1 -0
  9. package/adapters/content-detector.d.ts +19 -0
  10. package/adapters/content-detector.d.ts.map +1 -0
  11. package/adapters/content-renderers.d.ts +27 -0
  12. package/adapters/content-renderers.d.ts.map +1 -0
  13. package/adapters/index.d.ts +14 -7
  14. package/adapters/index.d.ts.map +1 -1
  15. package/adapters/index.js +2343 -426
  16. package/adapters/render-failure.d.ts +18 -0
  17. package/adapters/render-failure.d.ts.map +1 -0
  18. package/adapters/response-builder.d.ts +34 -104
  19. package/adapters/response-builder.d.ts.map +1 -1
  20. package/adapters/serving-mode.d.ts +28 -91
  21. package/adapters/serving-mode.d.ts.map +1 -1
  22. package/adapters/template-renderer.d.ts +50 -0
  23. package/adapters/template-renderer.d.ts.map +1 -0
  24. package/adapters/type-detector.d.ts +18 -0
  25. package/adapters/type-detector.d.ts.map +1 -0
  26. package/bridge-runtime/index.js +1 -1
  27. package/component/index.d.ts +14 -0
  28. package/component/index.d.ts.map +1 -0
  29. package/component/index.js +2043 -0
  30. package/component/loader.d.ts +36 -0
  31. package/component/loader.d.ts.map +1 -0
  32. package/component/renderer.d.ts +30 -0
  33. package/component/renderer.d.ts.map +1 -0
  34. package/component/transpiler.d.ts +49 -0
  35. package/component/transpiler.d.ts.map +1 -0
  36. package/component/types.d.ts +82 -0
  37. package/component/types.d.ts.map +1 -0
  38. package/esm/adapters/index.mjs +2337 -422
  39. package/esm/bridge-runtime/index.mjs +1 -1
  40. package/esm/component/index.mjs +2013 -0
  41. package/esm/index.mjs +3446 -13935
  42. package/esm/package.json +3 -12
  43. package/esm/resolver/index.mjs +661 -0
  44. package/esm/shell/index.mjs +1406 -0
  45. package/esm/types/index.mjs +11 -11
  46. package/esm/utils/index.mjs +53 -8
  47. package/index.d.ts +12 -40
  48. package/index.d.ts.map +1 -1
  49. package/index.js +3579 -14218
  50. package/package.json +3 -12
  51. package/resolver/cdn-registry.d.ts +39 -0
  52. package/resolver/cdn-registry.d.ts.map +1 -0
  53. package/resolver/esm-sh.resolver.d.ts +54 -0
  54. package/resolver/esm-sh.resolver.d.ts.map +1 -0
  55. package/resolver/import-map.d.ts +47 -0
  56. package/resolver/import-map.d.ts.map +1 -0
  57. package/resolver/import-parser.d.ts +28 -0
  58. package/resolver/import-parser.d.ts.map +1 -0
  59. package/resolver/import-rewriter.d.ts +29 -0
  60. package/resolver/import-rewriter.d.ts.map +1 -0
  61. package/resolver/index.d.ts +15 -0
  62. package/resolver/index.d.ts.map +1 -0
  63. package/resolver/index.js +708 -0
  64. package/resolver/types.d.ts +191 -0
  65. package/resolver/types.d.ts.map +1 -0
  66. package/shell/builder.d.ts +31 -0
  67. package/shell/builder.d.ts.map +1 -0
  68. package/shell/csp.d.ts +37 -0
  69. package/shell/csp.d.ts.map +1 -0
  70. package/shell/custom-shell-applier.d.ts +33 -0
  71. package/shell/custom-shell-applier.d.ts.map +1 -0
  72. package/shell/custom-shell-resolver.d.ts +47 -0
  73. package/shell/custom-shell-resolver.d.ts.map +1 -0
  74. package/shell/custom-shell-types.d.ts +75 -0
  75. package/shell/custom-shell-types.d.ts.map +1 -0
  76. package/shell/custom-shell-validator.d.ts +26 -0
  77. package/shell/custom-shell-validator.d.ts.map +1 -0
  78. package/shell/data-injector.d.ts +40 -0
  79. package/shell/data-injector.d.ts.map +1 -0
  80. package/shell/index.d.ts +19 -0
  81. package/shell/index.d.ts.map +1 -0
  82. package/shell/index.js +1453 -0
  83. package/shell/types.d.ts +54 -0
  84. package/shell/types.d.ts.map +1 -0
  85. package/types/index.d.ts +1 -3
  86. package/types/index.d.ts.map +1 -1
  87. package/types/index.js +11 -11
  88. package/types/ui-config.d.ts +50 -11
  89. package/types/ui-config.d.ts.map +1 -1
  90. package/types/ui-runtime.d.ts +8 -82
  91. package/types/ui-runtime.d.ts.map +1 -1
  92. package/utils/index.d.ts +9 -3
  93. package/utils/index.d.ts.map +1 -1
  94. package/utils/index.js +59 -7
  95. package/adapters/platform-meta.constants.d.ts +0 -26
  96. package/adapters/platform-meta.constants.d.ts.map +0 -1
  97. package/adapters/platform-meta.d.ts +0 -234
  98. package/adapters/platform-meta.d.ts.map +0 -1
  99. package/base-template/bridge.d.ts +0 -90
  100. package/base-template/bridge.d.ts.map +0 -1
  101. package/base-template/default-base-template.d.ts +0 -91
  102. package/base-template/default-base-template.d.ts.map +0 -1
  103. package/base-template/index.d.ts +0 -15
  104. package/base-template/index.d.ts.map +0 -1
  105. package/base-template/index.js +0 -1393
  106. package/base-template/polyfills.d.ts +0 -31
  107. package/base-template/polyfills.d.ts.map +0 -1
  108. package/base-template/theme-styles.d.ts +0 -74
  109. package/base-template/theme-styles.d.ts.map +0 -1
  110. package/build/builders/base-builder.d.ts +0 -124
  111. package/build/builders/base-builder.d.ts.map +0 -1
  112. package/build/builders/esbuild-config.d.ts +0 -94
  113. package/build/builders/esbuild-config.d.ts.map +0 -1
  114. package/build/builders/hybrid-builder.d.ts +0 -93
  115. package/build/builders/hybrid-builder.d.ts.map +0 -1
  116. package/build/builders/index.d.ts +0 -17
  117. package/build/builders/index.d.ts.map +0 -1
  118. package/build/builders/inline-builder.d.ts +0 -83
  119. package/build/builders/inline-builder.d.ts.map +0 -1
  120. package/build/builders/static-builder.d.ts +0 -78
  121. package/build/builders/static-builder.d.ts.map +0 -1
  122. package/build/builders/types.d.ts +0 -341
  123. package/build/builders/types.d.ts.map +0 -1
  124. package/build/cdn-resources.d.ts +0 -244
  125. package/build/cdn-resources.d.ts.map +0 -1
  126. package/build/hybrid-data.d.ts +0 -127
  127. package/build/hybrid-data.d.ts.map +0 -1
  128. package/build/index.d.ts +0 -299
  129. package/build/index.d.ts.map +0 -1
  130. package/build/index.js +0 -8699
  131. package/build/ui-components-browser.d.ts +0 -64
  132. package/build/ui-components-browser.d.ts.map +0 -1
  133. package/build/widget-manifest.d.ts +0 -362
  134. package/build/widget-manifest.d.ts.map +0 -1
  135. package/bundler/cache.d.ts +0 -173
  136. package/bundler/cache.d.ts.map +0 -1
  137. package/bundler/file-cache/component-builder.d.ts +0 -167
  138. package/bundler/file-cache/component-builder.d.ts.map +0 -1
  139. package/bundler/file-cache/hash-calculator.d.ts +0 -155
  140. package/bundler/file-cache/hash-calculator.d.ts.map +0 -1
  141. package/bundler/file-cache/index.d.ts +0 -12
  142. package/bundler/file-cache/index.d.ts.map +0 -1
  143. package/bundler/file-cache/storage/filesystem.d.ts +0 -149
  144. package/bundler/file-cache/storage/filesystem.d.ts.map +0 -1
  145. package/bundler/file-cache/storage/index.d.ts +0 -11
  146. package/bundler/file-cache/storage/index.d.ts.map +0 -1
  147. package/bundler/file-cache/storage/interface.d.ts +0 -152
  148. package/bundler/file-cache/storage/interface.d.ts.map +0 -1
  149. package/bundler/file-cache/storage/redis.d.ts +0 -139
  150. package/bundler/file-cache/storage/redis.d.ts.map +0 -1
  151. package/bundler/index.d.ts +0 -35
  152. package/bundler/index.d.ts.map +0 -1
  153. package/bundler/index.js +0 -2953
  154. package/bundler/sandbox/enclave-adapter.d.ts +0 -121
  155. package/bundler/sandbox/enclave-adapter.d.ts.map +0 -1
  156. package/bundler/sandbox/executor.d.ts +0 -14
  157. package/bundler/sandbox/executor.d.ts.map +0 -1
  158. package/bundler/sandbox/policy.d.ts +0 -62
  159. package/bundler/sandbox/policy.d.ts.map +0 -1
  160. package/bundler/types.d.ts +0 -702
  161. package/bundler/types.d.ts.map +0 -1
  162. package/dependency/cdn-registry.d.ts +0 -98
  163. package/dependency/cdn-registry.d.ts.map +0 -1
  164. package/dependency/import-map.d.ts +0 -186
  165. package/dependency/import-map.d.ts.map +0 -1
  166. package/dependency/import-parser.d.ts +0 -82
  167. package/dependency/import-parser.d.ts.map +0 -1
  168. package/dependency/index.d.ts +0 -17
  169. package/dependency/index.d.ts.map +0 -1
  170. package/dependency/index.js +0 -3180
  171. package/dependency/resolver.d.ts +0 -164
  172. package/dependency/resolver.d.ts.map +0 -1
  173. package/dependency/schemas.d.ts +0 -486
  174. package/dependency/schemas.d.ts.map +0 -1
  175. package/dependency/template-loader.d.ts +0 -204
  176. package/dependency/template-loader.d.ts.map +0 -1
  177. package/dependency/template-processor.d.ts +0 -118
  178. package/dependency/template-processor.d.ts.map +0 -1
  179. package/dependency/types.d.ts +0 -739
  180. package/dependency/types.d.ts.map +0 -1
  181. package/esm/base-template/index.mjs +0 -1359
  182. package/esm/build/index.mjs +0 -8601
  183. package/esm/bundler/index.mjs +0 -2895
  184. package/esm/dependency/index.mjs +0 -3068
  185. package/esm/handlebars/index.mjs +0 -587
  186. package/esm/registry/index.mjs +0 -6305
  187. package/esm/renderers/index.mjs +0 -1557
  188. package/esm/runtime/index.mjs +0 -5361
  189. package/esm/styles/index.mjs +0 -171
  190. package/esm/theme/index.mjs +0 -756
  191. package/esm/tool-template/index.mjs +0 -3652
  192. package/esm/validation/index.mjs +0 -542
  193. package/handlebars/expression-extractor.d.ts +0 -147
  194. package/handlebars/expression-extractor.d.ts.map +0 -1
  195. package/handlebars/helpers.d.ts +0 -339
  196. package/handlebars/helpers.d.ts.map +0 -1
  197. package/handlebars/index.d.ts +0 -195
  198. package/handlebars/index.d.ts.map +0 -1
  199. package/handlebars/index.js +0 -659
  200. package/preview/claude-preview.d.ts +0 -67
  201. package/preview/claude-preview.d.ts.map +0 -1
  202. package/preview/generic-preview.d.ts +0 -66
  203. package/preview/generic-preview.d.ts.map +0 -1
  204. package/preview/index.d.ts +0 -36
  205. package/preview/index.d.ts.map +0 -1
  206. package/preview/openai-preview.d.ts +0 -70
  207. package/preview/openai-preview.d.ts.map +0 -1
  208. package/preview/types.d.ts +0 -199
  209. package/preview/types.d.ts.map +0 -1
  210. package/registry/index.d.ts +0 -46
  211. package/registry/index.d.ts.map +0 -1
  212. package/registry/index.js +0 -6342
  213. package/registry/render-template.d.ts +0 -91
  214. package/registry/render-template.d.ts.map +0 -1
  215. package/registry/tool-ui.registry.d.ts +0 -294
  216. package/registry/tool-ui.registry.d.ts.map +0 -1
  217. package/registry/uri-utils.d.ts +0 -56
  218. package/registry/uri-utils.d.ts.map +0 -1
  219. package/renderers/cache.d.ts +0 -145
  220. package/renderers/cache.d.ts.map +0 -1
  221. package/renderers/html.renderer.d.ts +0 -123
  222. package/renderers/html.renderer.d.ts.map +0 -1
  223. package/renderers/index.d.ts +0 -36
  224. package/renderers/index.d.ts.map +0 -1
  225. package/renderers/index.js +0 -1603
  226. package/renderers/mdx-client.renderer.d.ts +0 -124
  227. package/renderers/mdx-client.renderer.d.ts.map +0 -1
  228. package/renderers/registry.d.ts +0 -133
  229. package/renderers/registry.d.ts.map +0 -1
  230. package/renderers/types.d.ts +0 -343
  231. package/renderers/types.d.ts.map +0 -1
  232. package/renderers/utils/detect.d.ts +0 -107
  233. package/renderers/utils/detect.d.ts.map +0 -1
  234. package/renderers/utils/hash.d.ts +0 -40
  235. package/renderers/utils/hash.d.ts.map +0 -1
  236. package/renderers/utils/index.d.ts +0 -9
  237. package/renderers/utils/index.d.ts.map +0 -1
  238. package/renderers/utils/transpiler.d.ts +0 -70
  239. package/renderers/utils/transpiler.d.ts.map +0 -1
  240. package/runtime/adapters/html.adapter.d.ts +0 -59
  241. package/runtime/adapters/html.adapter.d.ts.map +0 -1
  242. package/runtime/adapters/index.d.ts +0 -26
  243. package/runtime/adapters/index.d.ts.map +0 -1
  244. package/runtime/adapters/mdx.adapter.d.ts +0 -73
  245. package/runtime/adapters/mdx.adapter.d.ts.map +0 -1
  246. package/runtime/adapters/types.d.ts +0 -95
  247. package/runtime/adapters/types.d.ts.map +0 -1
  248. package/runtime/csp.d.ts +0 -48
  249. package/runtime/csp.d.ts.map +0 -1
  250. package/runtime/index.d.ts +0 -17
  251. package/runtime/index.d.ts.map +0 -1
  252. package/runtime/index.js +0 -5432
  253. package/runtime/mcp-bridge.d.ts +0 -101
  254. package/runtime/mcp-bridge.d.ts.map +0 -1
  255. package/runtime/renderer-runtime.d.ts +0 -133
  256. package/runtime/renderer-runtime.d.ts.map +0 -1
  257. package/runtime/sanitizer.d.ts +0 -180
  258. package/runtime/sanitizer.d.ts.map +0 -1
  259. package/runtime/types.d.ts +0 -415
  260. package/runtime/types.d.ts.map +0 -1
  261. package/runtime/wrapper.d.ts +0 -421
  262. package/runtime/wrapper.d.ts.map +0 -1
  263. package/styles/index.d.ts +0 -8
  264. package/styles/index.d.ts.map +0 -1
  265. package/styles/index.js +0 -222
  266. package/styles/variants.d.ts +0 -51
  267. package/styles/variants.d.ts.map +0 -1
  268. package/theme/cdn.d.ts +0 -195
  269. package/theme/cdn.d.ts.map +0 -1
  270. package/theme/css-to-theme.d.ts +0 -64
  271. package/theme/css-to-theme.d.ts.map +0 -1
  272. package/theme/index.d.ts +0 -19
  273. package/theme/index.d.ts.map +0 -1
  274. package/theme/index.js +0 -814
  275. package/theme/platforms.d.ts +0 -102
  276. package/theme/platforms.d.ts.map +0 -1
  277. package/theme/presets/github-openai.d.ts +0 -50
  278. package/theme/presets/github-openai.d.ts.map +0 -1
  279. package/theme/presets/index.d.ts +0 -11
  280. package/theme/presets/index.d.ts.map +0 -1
  281. package/theme/theme.d.ts +0 -396
  282. package/theme/theme.d.ts.map +0 -1
  283. package/tool-template/builder.d.ts +0 -213
  284. package/tool-template/builder.d.ts.map +0 -1
  285. package/tool-template/index.d.ts +0 -16
  286. package/tool-template/index.d.ts.map +0 -1
  287. package/tool-template/index.js +0 -3690
  288. package/validation/error-box.d.ts +0 -56
  289. package/validation/error-box.d.ts.map +0 -1
  290. package/validation/index.d.ts +0 -13
  291. package/validation/index.d.ts.map +0 -1
  292. package/validation/index.js +0 -576
  293. package/validation/schema-paths.d.ts +0 -118
  294. package/validation/schema-paths.d.ts.map +0 -1
  295. package/validation/template-validator.d.ts +0 -143
  296. package/validation/template-validator.d.ts.map +0 -1
  297. package/validation/wrapper.d.ts +0 -97
  298. package/validation/wrapper.d.ts.map +0 -1
@@ -1,1557 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __esm = (fn, res) => function __init() {
4
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
- };
6
- var __export = (target, all) => {
7
- for (var name in all)
8
- __defProp(target, name, { get: all[name], enumerable: true });
9
- };
10
-
11
- // libs/uipack/src/utils/index.ts
12
- import {
13
- safeStringify,
14
- escapeHtml,
15
- escapeHtmlAttr,
16
- escapeJsString,
17
- escapeScriptClose,
18
- safeJsonForScript
19
- } from "@frontmcp/utils";
20
- var init_utils = __esm({
21
- "libs/uipack/src/utils/index.ts"() {
22
- "use strict";
23
- }
24
- });
25
-
26
- // libs/uipack/src/handlebars/helpers.ts
27
- function formatDate(date, format) {
28
- if (date === null || date === void 0) {
29
- return "";
30
- }
31
- let dateObj;
32
- if (date instanceof Date) {
33
- dateObj = date;
34
- } else if (typeof date === "string" || typeof date === "number") {
35
- dateObj = new Date(date);
36
- } else {
37
- return String(date);
38
- }
39
- if (isNaN(dateObj.getTime())) {
40
- return String(date);
41
- }
42
- const options = {};
43
- switch (format) {
44
- case "short":
45
- options.dateStyle = "short";
46
- break;
47
- case "medium":
48
- options.dateStyle = "medium";
49
- break;
50
- case "long":
51
- options.dateStyle = "long";
52
- break;
53
- case "full":
54
- options.dateStyle = "full";
55
- break;
56
- case "time":
57
- options.timeStyle = "short";
58
- break;
59
- case "datetime":
60
- options.dateStyle = "medium";
61
- options.timeStyle = "short";
62
- break;
63
- case "iso":
64
- return dateObj.toISOString();
65
- case "relative":
66
- return formatRelativeDate(dateObj);
67
- default:
68
- options.dateStyle = "medium";
69
- }
70
- return new Intl.DateTimeFormat("en-US", options).format(dateObj);
71
- }
72
- function formatRelativeDate(date) {
73
- const now = /* @__PURE__ */ new Date();
74
- const diffMs = now.getTime() - date.getTime();
75
- const diffSecs = Math.floor(diffMs / 1e3);
76
- const diffMins = Math.floor(diffSecs / 60);
77
- const diffHours = Math.floor(diffMins / 60);
78
- const diffDays = Math.floor(diffHours / 24);
79
- if (diffSecs < 60) {
80
- return "just now";
81
- } else if (diffMins < 60) {
82
- return `${diffMins} minute${diffMins === 1 ? "" : "s"} ago`;
83
- } else if (diffHours < 24) {
84
- return `${diffHours} hour${diffHours === 1 ? "" : "s"} ago`;
85
- } else if (diffDays < 7) {
86
- return `${diffDays} day${diffDays === 1 ? "" : "s"} ago`;
87
- } else {
88
- return formatDate(date, "medium");
89
- }
90
- }
91
- function formatCurrency(amount, currency) {
92
- if (amount === null || amount === void 0) {
93
- return "";
94
- }
95
- const num = typeof amount === "number" ? amount : parseFloat(String(amount));
96
- if (isNaN(num)) {
97
- return String(amount);
98
- }
99
- return new Intl.NumberFormat("en-US", {
100
- style: "currency",
101
- currency: typeof currency === "string" ? currency : "USD"
102
- }).format(num);
103
- }
104
- function formatNumber(value, decimals) {
105
- if (value === null || value === void 0) {
106
- return "";
107
- }
108
- const num = typeof value === "number" ? value : parseFloat(String(value));
109
- if (isNaN(num)) {
110
- return String(value);
111
- }
112
- const options = {};
113
- if (typeof decimals === "number") {
114
- options.minimumFractionDigits = decimals;
115
- options.maximumFractionDigits = decimals;
116
- }
117
- return new Intl.NumberFormat("en-US", options).format(num);
118
- }
119
- function jsonEmbed(data) {
120
- const json2 = JSON.stringify(data ?? null);
121
- return json2.replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
122
- }
123
- function json(data, pretty) {
124
- return JSON.stringify(data ?? null, null, pretty ? 2 : void 0);
125
- }
126
- function eq(a, b) {
127
- return a === b;
128
- }
129
- function ne(a, b) {
130
- return a !== b;
131
- }
132
- function gt(a, b) {
133
- return Number(a) > Number(b);
134
- }
135
- function gte(a, b) {
136
- return Number(a) >= Number(b);
137
- }
138
- function lt(a, b) {
139
- return Number(a) < Number(b);
140
- }
141
- function lte(a, b) {
142
- return Number(a) <= Number(b);
143
- }
144
- function and(a, b) {
145
- return Boolean(a) && Boolean(b);
146
- }
147
- function or(a, b) {
148
- return Boolean(a) || Boolean(b);
149
- }
150
- function not(value) {
151
- return !value;
152
- }
153
- function first(arr) {
154
- if (!Array.isArray(arr)) return void 0;
155
- return arr[0];
156
- }
157
- function last(arr) {
158
- if (!Array.isArray(arr)) return void 0;
159
- return arr[arr.length - 1];
160
- }
161
- function length(value) {
162
- if (Array.isArray(value)) return value.length;
163
- if (typeof value === "string") return value.length;
164
- return 0;
165
- }
166
- function includes(arr, value) {
167
- if (!Array.isArray(arr)) return false;
168
- return arr.includes(value);
169
- }
170
- function join(arr, separator) {
171
- if (!Array.isArray(arr)) return "";
172
- return arr.join(typeof separator === "string" ? separator : ", ");
173
- }
174
- function uppercase(str) {
175
- return String(str ?? "").toUpperCase();
176
- }
177
- function lowercase(str) {
178
- return String(str ?? "").toLowerCase();
179
- }
180
- function capitalize(str) {
181
- const s = String(str ?? "");
182
- return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
183
- }
184
- function truncate(str, maxLength, suffix) {
185
- const s = String(str ?? "");
186
- const len = typeof maxLength === "number" ? maxLength : 50;
187
- const suf = typeof suffix === "string" ? suffix : "...";
188
- if (s.length <= len) return s;
189
- return s.slice(0, len - suf.length) + suf;
190
- }
191
- function defaultValue(value, defaultValue2) {
192
- return value || defaultValue2;
193
- }
194
- function uniqueId(prefix) {
195
- const id = ++idCounter;
196
- return prefix ? `${prefix}-${id}` : `id-${id}`;
197
- }
198
- function resetUniqueIdCounter() {
199
- idCounter = 0;
200
- }
201
- function classNames(...classes) {
202
- return classes.filter(Boolean).map(String).join(" ");
203
- }
204
- var idCounter, builtinHelpers;
205
- var init_helpers = __esm({
206
- "libs/uipack/src/handlebars/helpers.ts"() {
207
- "use strict";
208
- init_utils();
209
- idCounter = 0;
210
- builtinHelpers = {
211
- // Escaping
212
- escapeHtml,
213
- // Formatting
214
- formatDate,
215
- formatCurrency,
216
- formatNumber,
217
- json,
218
- jsonEmbed,
219
- // Comparison
220
- eq,
221
- ne,
222
- gt,
223
- gte,
224
- lt,
225
- lte,
226
- // Logical
227
- and,
228
- or,
229
- not,
230
- // Array
231
- first,
232
- last,
233
- length,
234
- includes,
235
- join,
236
- // String
237
- uppercase,
238
- lowercase,
239
- capitalize,
240
- truncate,
241
- // Utility
242
- default: defaultValue,
243
- uniqueId,
244
- classNames
245
- };
246
- }
247
- });
248
-
249
- // libs/uipack/src/handlebars/expression-extractor.ts
250
- function extractExpressions(template) {
251
- const expressions = [];
252
- const positionMap = buildPositionMap(template);
253
- let match;
254
- EXPRESSION_REGEX.lastIndex = 0;
255
- while ((match = EXPRESSION_REGEX.exec(template)) !== null) {
256
- const fullExpression = match[0];
257
- const prefix = match[1];
258
- const content = match[2].trim();
259
- const position = positionMap.get(match.index) ?? { line: 1, column: 1 };
260
- let type = "variable";
261
- let helperName;
262
- if (prefix === "/") {
263
- type = "block-close";
264
- helperName = content;
265
- } else if (prefix === "#") {
266
- type = "block";
267
- const parts = content.split(/\s+/);
268
- helperName = parts[0];
269
- } else {
270
- const parts = content.split(/\s+/);
271
- if (parts.length > 1 && !content.startsWith("(")) {
272
- const firstToken = parts[0];
273
- if (!firstToken.includes(".") && !KEYWORDS.has(firstToken)) {
274
- type = "helper";
275
- helperName = firstToken;
276
- }
277
- }
278
- }
279
- const paths = extractPathsFromContent(content);
280
- for (const path of paths) {
281
- expressions.push({
282
- path,
283
- fullExpression,
284
- line: position.line,
285
- column: position.column,
286
- type,
287
- helperName
288
- });
289
- }
290
- if (paths.length === 0 && type === "variable") {
291
- const cleanContent = content.trim();
292
- if (!KEYWORDS.has(cleanContent) && !cleanContent.includes(" ") && !cleanContent.startsWith("(")) {
293
- }
294
- }
295
- }
296
- return expressions;
297
- }
298
- function extractPathsFromContent(content) {
299
- const paths = [];
300
- let match;
301
- const regex = new RegExp(PATH_REGEX.source, "g");
302
- while ((match = regex.exec(content)) !== null) {
303
- paths.push(match[0]);
304
- }
305
- return paths;
306
- }
307
- function buildPositionMap(template) {
308
- const map = /* @__PURE__ */ new Map();
309
- let line = 1;
310
- let column = 1;
311
- for (let i = 0; i < template.length; i++) {
312
- map.set(i, { line, column });
313
- if (template[i] === "\n") {
314
- line++;
315
- column = 1;
316
- } else {
317
- column++;
318
- }
319
- }
320
- return map;
321
- }
322
- function extractVariablePaths(template) {
323
- const expressions = extractExpressions(template);
324
- const paths = new Set(expressions.map((e) => e.path));
325
- return Array.from(paths);
326
- }
327
- function extractOutputPaths(template) {
328
- return extractVariablePaths(template).filter((p) => p.startsWith("output."));
329
- }
330
- function extractInputPaths(template) {
331
- return extractVariablePaths(template).filter((p) => p.startsWith("input."));
332
- }
333
- function extractStructuredContentPaths(template) {
334
- return extractVariablePaths(template).filter((p) => p.startsWith("structuredContent."));
335
- }
336
- function extractAll(template) {
337
- const expressions = extractExpressions(template);
338
- const paths = [...new Set(expressions.map((e) => e.path))];
339
- return {
340
- expressions,
341
- paths,
342
- outputPaths: paths.filter((p) => p.startsWith("output.")),
343
- inputPaths: paths.filter((p) => p.startsWith("input.")),
344
- structuredContentPaths: paths.filter((p) => p.startsWith("structuredContent."))
345
- };
346
- }
347
- function hasVariablePaths(template) {
348
- return extractVariablePaths(template).length > 0;
349
- }
350
- function getExpressionAt(template, line, column) {
351
- const expressions = extractExpressions(template);
352
- return expressions.find((expr) => {
353
- if (expr.line !== line) return false;
354
- const exprEnd = expr.column + expr.fullExpression.length;
355
- return column >= expr.column && column <= exprEnd;
356
- });
357
- }
358
- function normalizePath(path) {
359
- return path.replace(/\.\d+\./g, ".[].").replace(/\.\d+$/g, ".[]").replace(/\[\d+\]/g, ".[]");
360
- }
361
- var EXPRESSION_REGEX, PATH_REGEX, KEYWORDS;
362
- var init_expression_extractor = __esm({
363
- "libs/uipack/src/handlebars/expression-extractor.ts"() {
364
- "use strict";
365
- EXPRESSION_REGEX = /\{\{\{?(?!!)(#|\/)?([^}]+?)\}?\}\}/g;
366
- PATH_REGEX = /\b(output|input|structuredContent)(\.[a-zA-Z_$][a-zA-Z0-9_$]*|\.\[[^\]]+\])+/g;
367
- KEYWORDS = /* @__PURE__ */ new Set(["this", "else", "@index", "@key", "@first", "@last", "@root"]);
368
- }
369
- });
370
-
371
- // libs/uipack/src/handlebars/index.ts
372
- var handlebars_exports = {};
373
- __export(handlebars_exports, {
374
- HandlebarsRenderer: () => HandlebarsRenderer,
375
- and: () => and,
376
- builtinHelpers: () => builtinHelpers,
377
- capitalize: () => capitalize,
378
- classNames: () => classNames,
379
- containsHandlebars: () => containsHandlebars,
380
- createHandlebarsRenderer: () => createHandlebarsRenderer,
381
- defaultValue: () => defaultValue,
382
- eq: () => eq,
383
- escapeHtml: () => escapeHtml,
384
- extractAll: () => extractAll,
385
- extractExpressions: () => extractExpressions,
386
- extractInputPaths: () => extractInputPaths,
387
- extractOutputPaths: () => extractOutputPaths,
388
- extractStructuredContentPaths: () => extractStructuredContentPaths,
389
- extractVariablePaths: () => extractVariablePaths,
390
- first: () => first,
391
- formatCurrency: () => formatCurrency,
392
- formatDate: () => formatDate,
393
- formatNumber: () => formatNumber,
394
- getExpressionAt: () => getExpressionAt,
395
- gt: () => gt,
396
- gte: () => gte,
397
- hasVariablePaths: () => hasVariablePaths,
398
- includes: () => includes,
399
- isHandlebarsAvailable: () => isHandlebarsAvailable,
400
- join: () => join,
401
- json: () => json,
402
- jsonEmbed: () => jsonEmbed,
403
- last: () => last,
404
- length: () => length,
405
- lowercase: () => lowercase,
406
- lt: () => lt,
407
- lte: () => lte,
408
- ne: () => ne,
409
- normalizePath: () => normalizePath,
410
- not: () => not,
411
- or: () => or,
412
- renderTemplate: () => renderTemplate,
413
- resetUniqueIdCounter: () => resetUniqueIdCounter,
414
- truncate: () => truncate,
415
- uniqueId: () => uniqueId,
416
- uppercase: () => uppercase
417
- });
418
- async function loadHandlebars() {
419
- if (Handlebars !== null) {
420
- return Handlebars;
421
- }
422
- try {
423
- Handlebars = await import("handlebars");
424
- return Handlebars;
425
- } catch {
426
- throw new Error("Handlebars is required for template rendering. Install it: npm install handlebars");
427
- }
428
- }
429
- async function isHandlebarsAvailable() {
430
- try {
431
- await loadHandlebars();
432
- return true;
433
- } catch {
434
- return false;
435
- }
436
- }
437
- function createHandlebarsRenderer(options) {
438
- return new HandlebarsRenderer(options);
439
- }
440
- async function renderTemplate(template, context) {
441
- const renderer = createHandlebarsRenderer();
442
- return renderer.render(template, context);
443
- }
444
- function containsHandlebars(template) {
445
- return HandlebarsRenderer.containsHandlebars(template);
446
- }
447
- var Handlebars, HandlebarsRenderer;
448
- var init_handlebars = __esm({
449
- "libs/uipack/src/handlebars/index.ts"() {
450
- "use strict";
451
- init_helpers();
452
- init_helpers();
453
- init_expression_extractor();
454
- Handlebars = null;
455
- HandlebarsRenderer = class {
456
- options;
457
- compiledTemplates = /* @__PURE__ */ new Map();
458
- initialized = false;
459
- hbs = null;
460
- constructor(options = {}) {
461
- this.options = {
462
- strict: false,
463
- autoEscape: true,
464
- ...options
465
- };
466
- }
467
- /**
468
- * Initialize the renderer with Handlebars.
469
- */
470
- async init() {
471
- if (this.initialized) return;
472
- this.hbs = await loadHandlebars();
473
- for (const [name, helper] of Object.entries(builtinHelpers)) {
474
- this.hbs.registerHelper(name, helper);
475
- }
476
- if (this.options.helpers) {
477
- for (const [name, helper] of Object.entries(this.options.helpers)) {
478
- this.hbs.registerHelper(name, helper);
479
- }
480
- }
481
- if (this.options.partials) {
482
- for (const [name, template] of Object.entries(this.options.partials)) {
483
- this.hbs.registerPartial(name, template);
484
- }
485
- }
486
- this.initialized = true;
487
- }
488
- /**
489
- * Render a Handlebars template.
490
- *
491
- * @param template - Template string
492
- * @param context - Render context with input/output
493
- * @returns Rendered HTML string
494
- */
495
- async render(template, context) {
496
- await this.init();
497
- if (!this.hbs) {
498
- throw new Error("Handlebars not initialized");
499
- }
500
- let compiled = this.compiledTemplates.get(template);
501
- if (!compiled) {
502
- compiled = this.hbs.compile(template, {
503
- strict: this.options.strict,
504
- noEscape: !this.options.autoEscape
505
- });
506
- this.compiledTemplates.set(template, compiled);
507
- }
508
- const data = {
509
- input: context.input ?? {},
510
- output: context.output ?? {},
511
- structuredContent: context.structuredContent,
512
- // Also expose at root level for convenience
513
- ...context.input,
514
- ...typeof context.output === "object" && context.output !== null ? context.output : {}
515
- };
516
- try {
517
- return compiled(data);
518
- } catch (error) {
519
- throw new Error(`Template rendering failed: ${error instanceof Error ? error.message : String(error)}`);
520
- }
521
- }
522
- /**
523
- * Render a template synchronously.
524
- *
525
- * Note: Requires Handlebars to be pre-loaded. Use `render()` for async loading.
526
- *
527
- * @param template - Template string
528
- * @param context - Render context
529
- * @returns Rendered HTML string
530
- */
531
- renderSync(template, context) {
532
- if (!this.initialized || !this.hbs) {
533
- throw new Error("HandlebarsRenderer not initialized. Call render() first or use initSync().");
534
- }
535
- let compiled = this.compiledTemplates.get(template);
536
- if (!compiled) {
537
- compiled = this.hbs.compile(template, {
538
- strict: this.options.strict,
539
- noEscape: !this.options.autoEscape
540
- });
541
- this.compiledTemplates.set(template, compiled);
542
- }
543
- const data = {
544
- input: context.input ?? {},
545
- output: context.output ?? {},
546
- structuredContent: context.structuredContent,
547
- ...context.input,
548
- ...typeof context.output === "object" && context.output !== null ? context.output : {}
549
- };
550
- return compiled(data);
551
- }
552
- /**
553
- * Initialize synchronously (for environments where Handlebars is already loaded).
554
- */
555
- initSync(handlebars) {
556
- this.hbs = handlebars;
557
- for (const [name, helper] of Object.entries(builtinHelpers)) {
558
- this.hbs.registerHelper(name, helper);
559
- }
560
- if (this.options.helpers) {
561
- for (const [name, helper] of Object.entries(this.options.helpers)) {
562
- this.hbs.registerHelper(name, helper);
563
- }
564
- }
565
- if (this.options.partials) {
566
- for (const [name, template] of Object.entries(this.options.partials)) {
567
- this.hbs.registerPartial(name, template);
568
- }
569
- }
570
- this.initialized = true;
571
- }
572
- /**
573
- * Register a custom helper.
574
- *
575
- * @param name - Helper name
576
- * @param fn - Helper function
577
- */
578
- registerHelper(name, fn) {
579
- if (this.hbs) {
580
- this.hbs.registerHelper(name, fn);
581
- }
582
- if (!this.options.helpers) {
583
- this.options.helpers = {};
584
- }
585
- this.options.helpers[name] = fn;
586
- }
587
- /**
588
- * Register a partial template.
589
- *
590
- * @param name - Partial name
591
- * @param template - Partial template string
592
- */
593
- registerPartial(name, template) {
594
- if (this.hbs) {
595
- this.hbs.registerPartial(name, template);
596
- }
597
- if (!this.options.partials) {
598
- this.options.partials = {};
599
- }
600
- this.options.partials[name] = template;
601
- }
602
- /**
603
- * Clear compiled template cache.
604
- */
605
- clearCache() {
606
- this.compiledTemplates.clear();
607
- }
608
- /**
609
- * Check if a template string contains Handlebars syntax.
610
- *
611
- * @param template - Template string to check
612
- * @returns true if contains {{...}} syntax
613
- */
614
- static containsHandlebars(template) {
615
- return /\{\{(?!!)[\s\S]*?\}\}/.test(template);
616
- }
617
- /**
618
- * Check if the renderer is initialized.
619
- */
620
- get isInitialized() {
621
- return this.initialized;
622
- }
623
- };
624
- }
625
- });
626
-
627
- // libs/uipack/src/renderers/utils/hash.ts
628
- function hashString(source) {
629
- let hash = 2166136261;
630
- for (let i = 0; i < source.length; i++) {
631
- hash ^= source.charCodeAt(i);
632
- hash = hash * 16777619 >>> 0;
633
- }
634
- return hash.toString(36);
635
- }
636
- function hashCombined(...values) {
637
- const combined = values.map((v) => {
638
- if (typeof v === "string") return v;
639
- if (v === null) return "null";
640
- if (v === void 0) return "undefined";
641
- try {
642
- return JSON.stringify(v);
643
- } catch {
644
- return String(v);
645
- }
646
- }).join("|");
647
- return hashString(combined);
648
- }
649
- function isHash(value) {
650
- return /^[0-9a-z]{5,10}$/i.test(value);
651
- }
652
-
653
- // libs/uipack/src/renderers/cache.ts
654
- var TranspileCache = class {
655
- cache = /* @__PURE__ */ new Map();
656
- maxSize;
657
- ttl;
658
- /** Cache statistics */
659
- stats = {
660
- hits: 0,
661
- misses: 0,
662
- evictions: 0
663
- };
664
- constructor(options = {}) {
665
- this.maxSize = options.maxSize ?? 500;
666
- this.ttl = options.ttl ?? 0;
667
- }
668
- /**
669
- * Get a cached transpile result by source content.
670
- *
671
- * @param source - Source code to look up
672
- * @returns Cached result or undefined if not found/expired
673
- */
674
- get(source) {
675
- const key = hashString(source);
676
- return this.getByKey(key);
677
- }
678
- /**
679
- * Get a cached transpile result by hash key.
680
- *
681
- * @param key - Hash key
682
- * @returns Cached result or undefined if not found/expired
683
- */
684
- getByKey(key) {
685
- const entry = this.cache.get(key);
686
- if (!entry) {
687
- this.stats.misses++;
688
- return void 0;
689
- }
690
- if (this.ttl > 0 && Date.now() - entry.timestamp > this.ttl) {
691
- this.cache.delete(key);
692
- this.stats.misses++;
693
- return void 0;
694
- }
695
- this.cache.delete(key);
696
- entry.accessCount++;
697
- this.cache.set(key, entry);
698
- this.stats.hits++;
699
- return entry.value;
700
- }
701
- /**
702
- * Store a transpile result.
703
- *
704
- * @param source - Source code (used to generate key)
705
- * @param value - Transpile result to cache
706
- * @returns The hash key used for storage
707
- */
708
- set(source, value) {
709
- const key = hashString(source);
710
- this.setByKey(key, value);
711
- return key;
712
- }
713
- /**
714
- * Store a transpile result by hash key.
715
- *
716
- * @param key - Hash key
717
- * @param value - Transpile result to cache
718
- */
719
- setByKey(key, value) {
720
- if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
721
- const oldestKey = this.cache.keys().next().value;
722
- if (oldestKey) {
723
- this.cache.delete(oldestKey);
724
- this.stats.evictions++;
725
- }
726
- }
727
- this.cache.set(key, {
728
- value,
729
- timestamp: Date.now(),
730
- accessCount: 1
731
- });
732
- }
733
- /**
734
- * Check if a source is cached.
735
- *
736
- * @param source - Source code to check
737
- * @returns True if cached and not expired
738
- */
739
- has(source) {
740
- const key = hashString(source);
741
- return this.hasByKey(key);
742
- }
743
- /**
744
- * Check if a key is cached.
745
- *
746
- * @param key - Hash key to check
747
- * @returns True if cached and not expired
748
- */
749
- hasByKey(key) {
750
- const entry = this.cache.get(key);
751
- if (!entry) return false;
752
- if (this.ttl > 0 && Date.now() - entry.timestamp > this.ttl) {
753
- this.cache.delete(key);
754
- return false;
755
- }
756
- return true;
757
- }
758
- /**
759
- * Delete a cached entry by source.
760
- *
761
- * @param source - Source code to delete
762
- * @returns True if entry was deleted
763
- */
764
- delete(source) {
765
- const key = hashString(source);
766
- return this.cache.delete(key);
767
- }
768
- /**
769
- * Clear all cached entries.
770
- */
771
- clear() {
772
- this.cache.clear();
773
- this.stats = { hits: 0, misses: 0, evictions: 0 };
774
- }
775
- /**
776
- * Get current cache size.
777
- */
778
- get size() {
779
- return this.cache.size;
780
- }
781
- /**
782
- * Get cache statistics.
783
- */
784
- getStats() {
785
- const total = this.stats.hits + this.stats.misses;
786
- return {
787
- ...this.stats,
788
- size: this.cache.size,
789
- hitRate: total > 0 ? this.stats.hits / total : 0
790
- };
791
- }
792
- };
793
- var transpileCache = new TranspileCache({ maxSize: 500 });
794
- var renderCache = new TranspileCache({
795
- maxSize: 1e3,
796
- ttl: 5 * 60 * 1e3
797
- // 5 minutes
798
- });
799
- var ComponentCache = class {
800
- cache = /* @__PURE__ */ new Map();
801
- maxSize;
802
- constructor(maxSize = 200) {
803
- this.maxSize = maxSize;
804
- }
805
- get(key) {
806
- const entry = this.cache.get(key);
807
- if (!entry) return void 0;
808
- this.cache.delete(key);
809
- this.cache.set(key, entry);
810
- return entry.value;
811
- }
812
- set(key, value) {
813
- if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
814
- const oldestKey = this.cache.keys().next().value;
815
- if (oldestKey) {
816
- this.cache.delete(oldestKey);
817
- }
818
- }
819
- this.cache.set(key, { value, timestamp: Date.now() });
820
- }
821
- has(key) {
822
- return this.cache.has(key);
823
- }
824
- delete(key) {
825
- return this.cache.delete(key);
826
- }
827
- clear() {
828
- this.cache.clear();
829
- }
830
- get size() {
831
- return this.cache.size;
832
- }
833
- };
834
- var componentCache = new ComponentCache();
835
-
836
- // libs/uipack/src/theme/platforms.ts
837
- var OPENAI_PLATFORM = {
838
- id: "openai",
839
- name: "OpenAI",
840
- supportsWidgets: true,
841
- supportsTailwind: true,
842
- supportsHtmx: true,
843
- networkMode: "full",
844
- scriptStrategy: "cdn",
845
- options: {
846
- sdk: "apps-sdk",
847
- version: "1.0"
848
- }
849
- };
850
- var CLAUDE_PLATFORM = {
851
- id: "claude",
852
- name: "Claude (Artifacts)",
853
- supportsWidgets: true,
854
- // Claude Artifacts support interactive widgets
855
- supportsTailwind: true,
856
- supportsHtmx: false,
857
- // Network blocked, HTMX won't work for API calls
858
- networkMode: "limited",
859
- scriptStrategy: "cdn",
860
- maxInlineSize: 100 * 1024,
861
- // 100KB limit for artifacts
862
- cspRestrictions: ["script-src 'unsafe-inline'", "connect-src 'none'"],
863
- options: {
864
- mode: "artifacts",
865
- framework: "react"
866
- // Claude artifacts prefer React
867
- }
868
- };
869
-
870
- // libs/uipack/src/renderers/utils/detect.ts
871
- var MAX_TEMPLATE_LENGTH = 5e4;
872
- function isReactComponent(value) {
873
- if (typeof value !== "function") {
874
- return false;
875
- }
876
- const fn = value;
877
- const typeofSymbol = fn.$$typeof;
878
- if (typeofSymbol) {
879
- const symbolString = typeofSymbol.toString();
880
- return symbolString.includes("react.memo") || symbolString.includes("react.forward_ref") || symbolString.includes("react.lazy");
881
- }
882
- if (fn.prototype?.isReactComponent) {
883
- return true;
884
- }
885
- if (fn.name && /^[A-Z]/.test(fn.name)) {
886
- return true;
887
- }
888
- return false;
889
- }
890
- function isTemplateBuilderFunction(fn) {
891
- if (isReactComponent(fn)) {
892
- return false;
893
- }
894
- if (fn.name && /^[A-Z]/.test(fn.name)) {
895
- return false;
896
- }
897
- return true;
898
- }
899
- function containsJsx(source) {
900
- if (source.length > MAX_TEMPLATE_LENGTH) {
901
- return false;
902
- }
903
- if (/<[A-Z][a-zA-Z0-9]*(\s|>|\/)/.test(source)) {
904
- return true;
905
- }
906
- if (/<[A-Z][a-zA-Z0-9]*[^>]*\/>/.test(source)) {
907
- return true;
908
- }
909
- if (/<[a-z]+[^>]*\{[^}]+\}/.test(source)) {
910
- return true;
911
- }
912
- if (/\s(className|onClick|onChange|onSubmit|htmlFor)=/.test(source)) {
913
- return true;
914
- }
915
- if (/<>|<\/>|<React\.Fragment>/.test(source)) {
916
- return true;
917
- }
918
- if (/=>\s*\(?\s*</.test(source)) {
919
- return true;
920
- }
921
- if (/return\s*\(?\s*</.test(source)) {
922
- return true;
923
- }
924
- return false;
925
- }
926
- function containsMdxSyntax(source) {
927
- if (source.length > MAX_TEMPLATE_LENGTH) {
928
- return false;
929
- }
930
- if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
931
- return true;
932
- }
933
- if (/^(import|export)\s/m.test(source)) {
934
- return true;
935
- }
936
- if (/\s(className|onClick|onChange|onSubmit|htmlFor|dangerouslySetInnerHTML)=/.test(source)) {
937
- return true;
938
- }
939
- if (/\{[^}"'\n]*\}/.test(source) && !/=\s*["'][^"']*\{/.test(source)) {
940
- return true;
941
- }
942
- if (/^---[\s\S]*?---/m.test(source)) {
943
- return true;
944
- }
945
- if (/<>|<\/>/.test(source)) {
946
- return true;
947
- }
948
- return false;
949
- }
950
- function isPlainHtml(source) {
951
- return !containsJsx(source) && !containsMdxSyntax(source);
952
- }
953
- function detectTemplateType(template) {
954
- if (typeof template === "function") {
955
- if (isReactComponent(template)) {
956
- return {
957
- type: "react",
958
- confidence: 0.9,
959
- reason: "Function detected as React component (PascalCase name or React symbols)"
960
- };
961
- }
962
- return {
963
- type: "html-function",
964
- confidence: 0.8,
965
- reason: "Function assumed to be HTML template builder"
966
- };
967
- }
968
- if (typeof template === "string") {
969
- if (containsMdxSyntax(template)) {
970
- const hasMarkdown = /^#{1,6}\s|^\*\s|^\d+\.\s|^-\s/m.test(template);
971
- if (hasMarkdown) {
972
- return {
973
- type: "mdx",
974
- confidence: 0.9,
975
- reason: "String contains Markdown with JSX components"
976
- };
977
- }
978
- return {
979
- type: "jsx-string",
980
- confidence: 0.8,
981
- reason: "String contains JSX syntax"
982
- };
983
- }
984
- if (containsJsx(template)) {
985
- return {
986
- type: "jsx-string",
987
- confidence: 0.85,
988
- reason: "String contains JSX component tags or expressions"
989
- };
990
- }
991
- return {
992
- type: "html-string",
993
- confidence: 1,
994
- reason: "Plain HTML string"
995
- };
996
- }
997
- return {
998
- type: "html-string",
999
- confidence: 0.5,
1000
- reason: "Unknown template type, defaulting to HTML"
1001
- };
1002
- }
1003
-
1004
- // libs/uipack/src/renderers/html.renderer.ts
1005
- var handlebarsRenderer = null;
1006
- async function loadHandlebarsRenderer() {
1007
- if (handlebarsRenderer !== null) {
1008
- return handlebarsRenderer;
1009
- }
1010
- try {
1011
- const handlebarsModule = await Promise.resolve().then(() => (init_handlebars(), handlebars_exports));
1012
- const { HandlebarsRenderer: HandlebarsRenderer2 } = handlebarsModule;
1013
- const renderer = new HandlebarsRenderer2();
1014
- handlebarsRenderer = {
1015
- render: (template, context) => renderer.render(template, {
1016
- input: context.input ?? {},
1017
- output: context.output,
1018
- structuredContent: context.structuredContent
1019
- }),
1020
- containsHandlebars: (template) => HandlebarsRenderer2.containsHandlebars(template)
1021
- };
1022
- return handlebarsRenderer;
1023
- } catch {
1024
- return null;
1025
- }
1026
- }
1027
- function containsHandlebars2(template) {
1028
- return /\{\{(?!!)[\s\S]*?\}\}/.test(template);
1029
- }
1030
- var HtmlRenderer = class {
1031
- type = "html";
1032
- priority = 0;
1033
- // Lowest priority - fallback renderer
1034
- /**
1035
- * Check if this renderer can handle the given template.
1036
- *
1037
- * Accepts:
1038
- * - Any string (assumed to be HTML, with or without Handlebars)
1039
- * - Functions that are template builders (not React components)
1040
- */
1041
- canHandle(template) {
1042
- if (typeof template === "string") {
1043
- return true;
1044
- }
1045
- if (typeof template === "function") {
1046
- return isTemplateBuilderFunction(template);
1047
- }
1048
- return false;
1049
- }
1050
- /**
1051
- * Check if a template uses Handlebars syntax.
1052
- *
1053
- * @param template - Template string to check
1054
- * @returns true if template contains {{...}} syntax
1055
- */
1056
- usesHandlebars(template) {
1057
- return containsHandlebars2(template);
1058
- }
1059
- /**
1060
- * Transpile the template.
1061
- *
1062
- * For HTML templates, no transpilation is needed.
1063
- * This method returns a dummy result for consistency.
1064
- */
1065
- async transpile(template, _options) {
1066
- const source = typeof template === "string" ? template : template.toString();
1067
- const hash = hashString(source);
1068
- return {
1069
- code: "",
1070
- // No transpiled code needed
1071
- hash,
1072
- cached: true
1073
- // Always "cached" since no work is done
1074
- };
1075
- }
1076
- /**
1077
- * Render the template to HTML string.
1078
- *
1079
- * For static strings without Handlebars, returns the string directly.
1080
- * For strings with Handlebars syntax, processes with HandlebarsRenderer.
1081
- * For functions, calls the function with the context.
1082
- */
1083
- async render(template, context, _options) {
1084
- if (typeof template === "string") {
1085
- if (containsHandlebars2(template)) {
1086
- return this.renderHandlebars(template, context);
1087
- }
1088
- return template;
1089
- }
1090
- if (typeof template === "function") {
1091
- const result = template(context);
1092
- if (typeof result === "string" && containsHandlebars2(result)) {
1093
- return this.renderHandlebars(result, context);
1094
- }
1095
- return result;
1096
- }
1097
- return String(template);
1098
- }
1099
- /**
1100
- * Render Handlebars template with context.
1101
- */
1102
- async renderHandlebars(template, context) {
1103
- const renderer = await loadHandlebarsRenderer();
1104
- if (!renderer) {
1105
- console.warn(
1106
- "[@frontmcp/ui] Template contains Handlebars syntax but handlebars is not installed. Install it for template interpolation: npm install handlebars"
1107
- );
1108
- return template;
1109
- }
1110
- return renderer.render(template, {
1111
- input: context.input,
1112
- output: context.output,
1113
- structuredContent: context.structuredContent
1114
- });
1115
- }
1116
- /**
1117
- * Get runtime scripts for client-side functionality.
1118
- *
1119
- * HTML templates don't need additional runtime scripts.
1120
- */
1121
- getRuntimeScripts(_platform) {
1122
- return {
1123
- headScripts: "",
1124
- isInline: false
1125
- };
1126
- }
1127
- };
1128
- var htmlRenderer = new HtmlRenderer();
1129
-
1130
- // libs/uipack/src/renderers/registry.ts
1131
- var RendererRegistry = class {
1132
- renderers = /* @__PURE__ */ new Map();
1133
- sortedRenderers = [];
1134
- defaultRenderer = "html";
1135
- debug;
1136
- constructor(options = {}) {
1137
- this.debug = options.debug ?? false;
1138
- this.register(htmlRenderer);
1139
- }
1140
- /**
1141
- * Register a renderer.
1142
- *
1143
- * Renderers are sorted by priority (highest first) for detection.
1144
- *
1145
- * @param renderer - Renderer to register
1146
- */
1147
- register(renderer) {
1148
- this.renderers.set(renderer.type, renderer);
1149
- this.updateSortedList();
1150
- if (this.debug) {
1151
- console.log(`[RendererRegistry] Registered renderer: ${renderer.type} (priority: ${renderer.priority})`);
1152
- }
1153
- }
1154
- /**
1155
- * Unregister a renderer.
1156
- *
1157
- * @param type - Type of renderer to remove
1158
- * @returns True if renderer was removed
1159
- */
1160
- unregister(type) {
1161
- const removed = this.renderers.delete(type);
1162
- if (removed) {
1163
- this.updateSortedList();
1164
- }
1165
- return removed;
1166
- }
1167
- /**
1168
- * Get a renderer by type.
1169
- *
1170
- * @param type - Renderer type
1171
- * @returns Renderer or undefined if not found
1172
- */
1173
- get(type) {
1174
- return this.renderers.get(type);
1175
- }
1176
- /**
1177
- * Check if a renderer type is registered.
1178
- *
1179
- * @param type - Renderer type
1180
- * @returns True if registered
1181
- */
1182
- has(type) {
1183
- return this.renderers.has(type);
1184
- }
1185
- /**
1186
- * Get all registered renderer types.
1187
- *
1188
- * @returns Array of renderer types
1189
- */
1190
- getTypes() {
1191
- return Array.from(this.renderers.keys());
1192
- }
1193
- /**
1194
- * Auto-detect the renderer for a template.
1195
- *
1196
- * Checks renderers in priority order (highest first).
1197
- * Returns HTML renderer as fallback.
1198
- *
1199
- * @param template - Template to detect
1200
- * @returns Detection result with renderer and confidence
1201
- */
1202
- detect(template) {
1203
- for (const renderer of this.sortedRenderers) {
1204
- if (renderer.canHandle(template)) {
1205
- const result = {
1206
- renderer,
1207
- confidence: renderer.priority / 100,
1208
- // Normalize to 0-1
1209
- reason: `Matched by ${renderer.type} renderer`
1210
- };
1211
- if (this.debug) {
1212
- console.log(`[RendererRegistry] Detected template as ${renderer.type} (confidence: ${result.confidence})`);
1213
- }
1214
- return result;
1215
- }
1216
- }
1217
- const fallback = this.renderers.get(this.defaultRenderer);
1218
- if (!fallback) {
1219
- throw new Error(`Default renderer '${this.defaultRenderer}' not found`);
1220
- }
1221
- return {
1222
- renderer: fallback,
1223
- confidence: 0.5,
1224
- reason: "Fallback to default HTML renderer"
1225
- };
1226
- }
1227
- /**
1228
- * Render a template with auto-detection.
1229
- *
1230
- * @param template - Template to render (React, MDX, or HTML)
1231
- * @param context - Template context with input/output
1232
- * @param options - Render options
1233
- * @returns Rendered result with HTML and metadata
1234
- */
1235
- async render(template, context, options = {}) {
1236
- const platform = options.platform ?? OPENAI_PLATFORM;
1237
- const detection = this.detect(template);
1238
- const renderer = detection.renderer;
1239
- if (this.debug) {
1240
- console.log(`[RendererRegistry] Rendering with ${renderer.type} renderer`);
1241
- }
1242
- const transpileResult = await renderer.transpile(template);
1243
- const html = await renderer.render(template, context, options);
1244
- const runtimeScripts = renderer.getRuntimeScripts(platform);
1245
- return {
1246
- html,
1247
- rendererType: renderer.type,
1248
- transpileCached: transpileResult.cached,
1249
- runtimeScripts
1250
- };
1251
- }
1252
- /**
1253
- * Render with a specific renderer type.
1254
- *
1255
- * @param type - Renderer type to use
1256
- * @param template - Template to render
1257
- * @param context - Template context
1258
- * @param options - Render options
1259
- * @returns Rendered result
1260
- */
1261
- async renderWith(type, template, context, options = {}) {
1262
- const renderer = this.renderers.get(type);
1263
- if (!renderer) {
1264
- throw new Error(`Renderer '${type}' not registered`);
1265
- }
1266
- const platform = options.platform ?? OPENAI_PLATFORM;
1267
- const transpileResult = await renderer.transpile(template);
1268
- const html = await renderer.render(template, context, options);
1269
- const runtimeScripts = renderer.getRuntimeScripts(platform);
1270
- return {
1271
- html,
1272
- rendererType: type,
1273
- transpileCached: transpileResult.cached,
1274
- runtimeScripts
1275
- };
1276
- }
1277
- /**
1278
- * Update the sorted renderer list by priority.
1279
- */
1280
- updateSortedList() {
1281
- this.sortedRenderers = Array.from(this.renderers.values()).sort((a, b) => b.priority - a.priority);
1282
- }
1283
- /**
1284
- * Set the default renderer type.
1285
- *
1286
- * @param type - Renderer type to use as default
1287
- */
1288
- setDefault(type) {
1289
- if (!this.renderers.has(type)) {
1290
- throw new Error(`Cannot set default to unregistered renderer '${type}'`);
1291
- }
1292
- this.defaultRenderer = type;
1293
- }
1294
- /**
1295
- * Get registry statistics.
1296
- */
1297
- getStats() {
1298
- return {
1299
- registeredRenderers: this.getTypes(),
1300
- defaultRenderer: this.defaultRenderer,
1301
- priorityOrder: this.sortedRenderers.map((r) => ({
1302
- type: r.type,
1303
- priority: r.priority
1304
- }))
1305
- };
1306
- }
1307
- };
1308
- var rendererRegistry = new RendererRegistry();
1309
-
1310
- // libs/uipack/src/renderers/mdx-client.renderer.ts
1311
- init_utils();
1312
- function buildReactCdnUrls(version = "19") {
1313
- return {
1314
- react: `https://esm.sh/react@${version}`,
1315
- reactDom: `https://esm.sh/react-dom@${version}/client`,
1316
- jsxRuntime: `https://esm.sh/react@${version}/jsx-runtime`
1317
- };
1318
- }
1319
- var DEFAULT_CDN = {
1320
- mdx: "https://esm.sh/@mdx-js/mdx@3",
1321
- ...buildReactCdnUrls("19")
1322
- };
1323
- var MdxClientRenderer = class {
1324
- type = "mdx-client";
1325
- priority = 8;
1326
- // Lower than server-side MDX (10)
1327
- /**
1328
- * Check if this renderer can handle the given template.
1329
- */
1330
- canHandle(template) {
1331
- if (typeof template !== "string") {
1332
- return false;
1333
- }
1334
- return containsMdxSyntax(template);
1335
- }
1336
- /**
1337
- * Prepare MDX template for rendering.
1338
- * Caches the template hash for deduplication. Actual MDX compilation
1339
- * happens client-side via CDN-loaded @mdx-js/mdx in the browser.
1340
- */
1341
- async transpile(template, _options) {
1342
- const hash = hashString(template);
1343
- const cached = transpileCache.getByKey(hash);
1344
- if (cached) {
1345
- return { ...cached, cached: true };
1346
- }
1347
- const transpileResult = {
1348
- code: template,
1349
- hash,
1350
- cached: false
1351
- };
1352
- transpileCache.setByKey(hash, transpileResult);
1353
- return transpileResult;
1354
- }
1355
- /**
1356
- * Render MDX template to HTML with CDN scripts.
1357
- *
1358
- * The returned HTML includes:
1359
- * - A container div for the rendered content
1360
- * - Script tags that load React and MDX from CDN
1361
- * - Inline script that compiles and renders the MDX
1362
- */
1363
- async render(template, context, options) {
1364
- const containerId = options?.containerId || "mdx-content";
1365
- const showLoading = options?.showLoading !== false;
1366
- const loadingMessage = options?.loadingMessage || "Loading...";
1367
- const cdn = {
1368
- ...DEFAULT_CDN,
1369
- ...options?.cdn
1370
- };
1371
- const props = {
1372
- input: context.input,
1373
- output: context.output,
1374
- structuredContent: context.structuredContent,
1375
- helpers: context.helpers
1376
- };
1377
- const reservedProps = /* @__PURE__ */ new Set(["input", "output", "structuredContent", "helpers", "components"]);
1378
- const outputProps = typeof context.output === "object" && context.output !== null ? Object.fromEntries(Object.entries(context.output).filter(([key]) => !reservedProps.has(key))) : {};
1379
- const spreadProps = {
1380
- ...outputProps,
1381
- ...props
1382
- };
1383
- const escapedMdx = escapeScriptClose(JSON.stringify(template));
1384
- const escapedProps = escapeScriptClose(JSON.stringify(spreadProps));
1385
- const safeContainerId = escapeJsString(containerId);
1386
- const loadingHtml = showLoading ? `<div class="mdx-loading">${escapeHtml(loadingMessage)}</div>` : "";
1387
- return `
1388
- <div id="${escapeHtml(containerId)}">${loadingHtml}</div>
1389
- <script type="module">
1390
- (async function() {
1391
- try {
1392
- // Load dependencies from CDN
1393
- const [
1394
- { evaluate },
1395
- runtime,
1396
- React,
1397
- { createRoot }
1398
- ] = await Promise.all([
1399
- import('${cdn.mdx}'),
1400
- import('${cdn.jsxRuntime}'),
1401
- import('${cdn.react}'),
1402
- import('${cdn.reactDom}')
1403
- ]);
1404
-
1405
- // MDX content and props
1406
- const mdxSource = ${escapedMdx};
1407
- const props = ${escapedProps};
1408
-
1409
- // Compile and evaluate MDX
1410
- const { default: Content } = await evaluate(mdxSource, {
1411
- ...runtime,
1412
- Fragment: React.Fragment,
1413
- development: false
1414
- });
1415
-
1416
- // Render to DOM
1417
- const container = document.getElementById('${safeContainerId}');
1418
- if (container) {
1419
- const root = createRoot(container);
1420
- root.render(React.createElement(Content, props));
1421
- }
1422
- } catch (error) {
1423
- console.error('[FrontMCP] MDX client rendering failed:', error);
1424
- const container = document.getElementById('${safeContainerId}');
1425
- if (container) {
1426
- container.innerHTML = '<div class="mdx-error">Failed to render MDX content</div>';
1427
- }
1428
- }
1429
- })();
1430
- </script>
1431
- `;
1432
- }
1433
- /**
1434
- * Get runtime scripts - not needed for client renderer since scripts are inline.
1435
- */
1436
- getRuntimeScripts(platform) {
1437
- if (platform.networkMode === "blocked") {
1438
- return {
1439
- headScripts: "",
1440
- inlineScripts: `console.warn('[FrontMCP] Client-side MDX rendering requires network access. Use @frontmcp/ui for SSR.');`,
1441
- isInline: true
1442
- };
1443
- }
1444
- return {
1445
- headScripts: "",
1446
- isInline: false
1447
- };
1448
- }
1449
- };
1450
- var mdxClientRenderer = new MdxClientRenderer();
1451
-
1452
- // libs/uipack/src/renderers/utils/transpiler.ts
1453
- var DEFAULT_SWC_OPTIONS = {
1454
- typescript: true,
1455
- jsx: true,
1456
- jsxRuntime: "automatic",
1457
- development: false
1458
- };
1459
- var swcTransform = null;
1460
- async function loadSwcTransform() {
1461
- if (swcTransform !== null) {
1462
- return swcTransform;
1463
- }
1464
- try {
1465
- const swc = await import(
1466
- /* webpackIgnore: true */
1467
- "@swc/core"
1468
- );
1469
- swcTransform = swc.transform;
1470
- return swcTransform;
1471
- } catch {
1472
- console.warn(
1473
- "[@frontmcp/ui] @swc/core not available. Runtime JSX transpilation disabled. Install @swc/core to enable: npm install @swc/core"
1474
- );
1475
- return null;
1476
- }
1477
- }
1478
- async function transpileJsx(source, options = {}) {
1479
- const hash = hashString(source);
1480
- const cached = transpileCache.getByKey(hash);
1481
- if (cached) {
1482
- return { ...cached, cached: true };
1483
- }
1484
- const transform = await loadSwcTransform();
1485
- if (!transform) {
1486
- throw new Error(
1487
- "Runtime JSX transpilation requires @swc/core. Either install @swc/core or use pre-compiled React components."
1488
- );
1489
- }
1490
- const opts = { ...DEFAULT_SWC_OPTIONS, ...options };
1491
- const swcOptions = {
1492
- jsc: {
1493
- parser: {
1494
- syntax: opts.typescript ? "typescript" : "ecmascript",
1495
- tsx: opts.jsx,
1496
- jsx: opts.jsx
1497
- },
1498
- transform: {
1499
- react: {
1500
- runtime: opts.jsxRuntime,
1501
- development: opts.development
1502
- }
1503
- },
1504
- target: "es2020"
1505
- },
1506
- module: {
1507
- type: "commonjs"
1508
- }
1509
- };
1510
- const result = await transform(source, swcOptions);
1511
- const transpileResult = {
1512
- code: result.code,
1513
- hash,
1514
- cached: false
1515
- };
1516
- transpileCache.setByKey(hash, transpileResult);
1517
- return transpileResult;
1518
- }
1519
- async function isSwcAvailable() {
1520
- const transform = await loadSwcTransform();
1521
- return transform !== null;
1522
- }
1523
- async function executeTranspiledCode(_code, _context = {}) {
1524
- throw new Error(
1525
- 'executeTranspiledCode has been moved to @frontmcp/ui/renderers. Install @frontmcp/ui and import from there: import { executeTranspiledCode } from "@frontmcp/ui/renderers"'
1526
- );
1527
- }
1528
- async function transpileAndExecute(_source, _context = {}) {
1529
- throw new Error(
1530
- 'transpileAndExecute has been moved to @frontmcp/ui/renderers. Install @frontmcp/ui and import from there: import { transpileAndExecute } from "@frontmcp/ui/renderers"'
1531
- );
1532
- }
1533
- export {
1534
- HtmlRenderer,
1535
- MdxClientRenderer,
1536
- RendererRegistry,
1537
- TranspileCache,
1538
- buildReactCdnUrls,
1539
- componentCache,
1540
- containsJsx,
1541
- containsMdxSyntax,
1542
- detectTemplateType,
1543
- executeTranspiledCode,
1544
- hashCombined,
1545
- hashString,
1546
- htmlRenderer,
1547
- isHash,
1548
- isPlainHtml,
1549
- isReactComponent,
1550
- isSwcAvailable,
1551
- isTemplateBuilderFunction,
1552
- mdxClientRenderer,
1553
- rendererRegistry,
1554
- transpileAndExecute,
1555
- transpileCache,
1556
- transpileJsx
1557
- };