@frontmcp/uipack 0.6.3 → 0.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/CLAUDE.md +0 -14
  2. package/adapters/index.js +50 -47
  3. package/adapters/platform-meta.d.ts.map +1 -1
  4. package/adapters/response-builder.d.ts +16 -3
  5. package/adapters/response-builder.d.ts.map +1 -1
  6. package/bridge-runtime/iife-generator.d.ts.map +1 -1
  7. package/bridge-runtime/index.js +4 -0
  8. package/build/index.d.ts +1 -1
  9. package/build/index.d.ts.map +1 -1
  10. package/build/index.js +61 -69
  11. package/bundler/index.js +35 -34
  12. package/dependency/import-map.d.ts.map +1 -1
  13. package/dependency/index.js +22 -29
  14. package/esm/adapters/index.mjs +52 -42
  15. package/esm/bridge-runtime/index.mjs +4 -0
  16. package/esm/build/index.mjs +30 -32
  17. package/esm/bundler/index.mjs +19 -11
  18. package/esm/dependency/index.mjs +18 -18
  19. package/esm/handlebars/index.mjs +9 -8
  20. package/esm/index.mjs +107 -126
  21. package/esm/package.json +3 -2
  22. package/esm/registry/index.mjs +53 -49
  23. package/esm/renderers/index.mjs +15 -21
  24. package/esm/runtime/index.mjs +16 -15
  25. package/esm/theme/index.mjs +8 -0
  26. package/esm/tool-template/index.mjs +23 -15
  27. package/esm/typings/index.mjs +4 -0
  28. package/esm/utils/index.mjs +9 -56
  29. package/esm/validation/index.mjs +9 -8
  30. package/handlebars/index.js +4 -10
  31. package/index.js +186 -211
  32. package/package.json +3 -2
  33. package/preview/generic-preview.d.ts +4 -5
  34. package/preview/generic-preview.d.ts.map +1 -1
  35. package/preview/types.d.ts +15 -1
  36. package/preview/types.d.ts.map +1 -1
  37. package/registry/index.js +61 -63
  38. package/registry/render-template.d.ts.map +1 -1
  39. package/renderers/index.js +16 -28
  40. package/renderers/utils/detect.d.ts.map +1 -1
  41. package/runtime/index.js +20 -25
  42. package/runtime/sanitizer.d.ts.map +1 -1
  43. package/theme/css-to-theme.d.ts +0 -27
  44. package/theme/css-to-theme.d.ts.map +1 -1
  45. package/theme/index.js +8 -0
  46. package/tool-template/index.js +30 -28
  47. package/typings/dts-parser.d.ts.map +1 -1
  48. package/typings/index.js +4 -0
  49. package/utils/index.d.ts +2 -3
  50. package/utils/index.d.ts.map +1 -1
  51. package/utils/index.js +7 -63
  52. package/validation/index.js +6 -12
  53. package/utils/escape-html.d.ts +0 -102
  54. package/utils/escape-html.d.ts.map +0 -1
  55. package/utils/safe-stringify.d.ts +0 -30
  56. package/utils/safe-stringify.d.ts.map +0 -1
package/build/index.js CHANGED
@@ -30,34 +30,12 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
30
30
  ));
31
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
32
 
33
- // libs/uipack/src/utils/escape-html.ts
34
- function escapeHtml(str) {
35
- if (str === null || str === void 0) {
36
- return "";
37
- }
38
- const s = String(str);
39
- return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
40
- }
41
- function escapeHtmlAttr(str) {
42
- return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
43
- }
44
- function escapeJsString(str) {
45
- return str.replace(/\\/g, "\\\\").replace(/'/g, "\\'").replace(/"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r").replace(/\t/g, "\\t").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
46
- }
47
- function escapeScriptClose(jsonString) {
48
- return jsonString.replace(/<\//g, "<\\/");
49
- }
50
- var init_escape_html = __esm({
51
- "libs/uipack/src/utils/escape-html.ts"() {
52
- "use strict";
53
- }
54
- });
55
-
56
33
  // libs/uipack/src/utils/index.ts
34
+ var import_utils;
57
35
  var init_utils = __esm({
58
36
  "libs/uipack/src/utils/index.ts"() {
59
37
  "use strict";
60
- init_escape_html();
38
+ import_utils = require("@frontmcp/utils");
61
39
  }
62
40
  });
63
41
 
@@ -247,7 +225,7 @@ var init_helpers = __esm({
247
225
  idCounter = 0;
248
226
  builtinHelpers = {
249
227
  // Escaping
250
- escapeHtml,
228
+ escapeHtml: import_utils.escapeHtml,
251
229
  // Formatting
252
230
  formatDate,
253
231
  formatCurrency,
@@ -418,7 +396,7 @@ __export(handlebars_exports, {
418
396
  createHandlebarsRenderer: () => createHandlebarsRenderer,
419
397
  defaultValue: () => defaultValue,
420
398
  eq: () => eq,
421
- escapeHtml: () => escapeHtml,
399
+ escapeHtml: () => import_utils.escapeHtml,
422
400
  extractAll: () => extractAll,
423
401
  extractExpressions: () => extractExpressions,
424
402
  extractInputPaths: () => extractInputPaths,
@@ -671,7 +649,7 @@ function sha256Buffer(buffer) {
671
649
  }
672
650
  async function hashFile(filePath) {
673
651
  try {
674
- const content = await (0, import_promises.readFile)(filePath);
652
+ const content = await (0, import_utils6.readFileBuffer)(filePath);
675
653
  return sha256Buffer(content);
676
654
  } catch {
677
655
  return void 0;
@@ -717,7 +695,7 @@ async function collectLocalDependencies(filePath, baseDir, collected, maxDepth,
717
695
  if (!(0, import_fs.existsSync)(filePath)) return;
718
696
  collected.add(filePath);
719
697
  try {
720
- const content = await (0, import_promises.readFile)(filePath, "utf8");
698
+ const content = await (0, import_utils6.readFile)(filePath);
721
699
  const imports = extractImportPaths(content);
722
700
  for (const importPath of imports) {
723
701
  if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
@@ -781,14 +759,14 @@ function sortedObject(obj) {
781
759
  }
782
760
  return sorted;
783
761
  }
784
- var import_crypto, import_promises, import_fs, import_path;
762
+ var import_crypto, import_fs, import_path, import_utils6;
785
763
  var init_hash_calculator = __esm({
786
764
  "libs/uipack/src/bundler/file-cache/hash-calculator.ts"() {
787
765
  "use strict";
788
766
  import_crypto = require("crypto");
789
- import_promises = require("fs/promises");
790
767
  import_fs = require("fs");
791
768
  import_path = require("path");
769
+ import_utils6 = require("@frontmcp/utils");
792
770
  }
793
771
  });
794
772
 
@@ -1610,13 +1588,16 @@ function generateUMDShim(dependencies, options = {}) {
1610
1588
  console.warn('UMD shim failed:', e);
1611
1589
  }
1612
1590
  })();` : `window.__esm_shim = ${shimObject};`;
1613
- return minify ? code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1") : code;
1591
+ if (minify && code.length <= 1e5) {
1592
+ return code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1");
1593
+ }
1594
+ return code;
1614
1595
  }
1615
1596
  function generateCDNScriptTags(dependencies) {
1616
1597
  return dependencies.filter((dep) => !dep.esm).map((dep) => {
1617
- const attrs = [`src="${escapeHtmlAttr(dep.cdnUrl)}"`];
1598
+ const attrs = [`src="${(0, import_utils.escapeHtmlAttr)(dep.cdnUrl)}"`];
1618
1599
  if (dep.integrity) {
1619
- attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
1600
+ attrs.push(`integrity="${(0, import_utils.escapeHtmlAttr)(dep.integrity)}"`);
1620
1601
  }
1621
1602
  attrs.push('crossorigin="anonymous"');
1622
1603
  return `<script ${attrs.join(" ")}></script>`;
@@ -1624,9 +1605,9 @@ function generateCDNScriptTags(dependencies) {
1624
1605
  }
1625
1606
  function generateESMScriptTags(dependencies) {
1626
1607
  return dependencies.filter((dep) => dep.esm).map((dep) => {
1627
- const attrs = ['type="module"', `src="${escapeHtmlAttr(dep.cdnUrl)}"`];
1608
+ const attrs = ['type="module"', `src="${(0, import_utils.escapeHtmlAttr)(dep.cdnUrl)}"`];
1628
1609
  if (dep.integrity) {
1629
- attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
1610
+ attrs.push(`integrity="${(0, import_utils.escapeHtmlAttr)(dep.integrity)}"`);
1630
1611
  }
1631
1612
  attrs.push('crossorigin="anonymous"');
1632
1613
  return `<script ${attrs.join(" ")}></script>`;
@@ -1891,14 +1872,14 @@ __export(filesystem_exports, {
1891
1872
  function createFilesystemStorage(options) {
1892
1873
  return new FilesystemStorage(options);
1893
1874
  }
1894
- var import_promises2, import_path3, import_fs3, import_crypto2, CacheInitializationError, CacheOperationError, StorageNotInitializedError, DEFAULT_FS_OPTIONS, FilesystemStorage;
1875
+ var import_path3, import_fs3, import_crypto2, import_utils9, CacheInitializationError, CacheOperationError, StorageNotInitializedError, DEFAULT_FS_OPTIONS, FilesystemStorage;
1895
1876
  var init_filesystem = __esm({
1896
1877
  "libs/uipack/src/bundler/file-cache/storage/filesystem.ts"() {
1897
1878
  "use strict";
1898
- import_promises2 = require("fs/promises");
1899
1879
  import_path3 = require("path");
1900
1880
  import_fs3 = require("fs");
1901
1881
  import_crypto2 = require("crypto");
1882
+ import_utils9 = require("@frontmcp/utils");
1902
1883
  init_interface();
1903
1884
  CacheInitializationError = class extends Error {
1904
1885
  cause;
@@ -1950,7 +1931,7 @@ var init_filesystem = __esm({
1950
1931
  async initialize() {
1951
1932
  if (this.initialized) return;
1952
1933
  try {
1953
- await (0, import_promises2.mkdir)(this.options.cacheDir, { recursive: true });
1934
+ await (0, import_utils9.mkdir)(this.options.cacheDir, { recursive: true });
1954
1935
  await this.loadStats();
1955
1936
  this.initialized = true;
1956
1937
  } catch (error) {
@@ -1969,7 +1950,7 @@ var init_filesystem = __esm({
1969
1950
  this.updateHitRate();
1970
1951
  return void 0;
1971
1952
  }
1972
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
1953
+ const content = await (0, import_utils9.readFile)(filePath, "utf8");
1973
1954
  const entry = JSON.parse(content);
1974
1955
  if (Date.now() > entry.metadata.expiresAt) {
1975
1956
  await this.delete(key);
@@ -2025,7 +2006,7 @@ var init_filesystem = __esm({
2025
2006
  const filePath = this.getFilePath(key);
2026
2007
  try {
2027
2008
  if (!(0, import_fs3.existsSync)(filePath)) return false;
2028
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
2009
+ const content = await (0, import_utils9.readFile)(filePath, "utf8");
2029
2010
  const entry = JSON.parse(content);
2030
2011
  if (Date.now() > entry.metadata.expiresAt) {
2031
2012
  await this.delete(key);
@@ -2044,9 +2025,9 @@ var init_filesystem = __esm({
2044
2025
  const filePath = this.getFilePath(key);
2045
2026
  try {
2046
2027
  if (!(0, import_fs3.existsSync)(filePath)) return false;
2047
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
2028
+ const content = await (0, import_utils9.readFile)(filePath, "utf8");
2048
2029
  const entry = JSON.parse(content);
2049
- await (0, import_promises2.unlink)(filePath);
2030
+ await (0, import_utils9.unlink)(filePath);
2050
2031
  this.stats.entries = Math.max(0, this.stats.entries - 1);
2051
2032
  this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
2052
2033
  return true;
@@ -2060,8 +2041,8 @@ var init_filesystem = __esm({
2060
2041
  async clear() {
2061
2042
  this.ensureInitialized();
2062
2043
  try {
2063
- await (0, import_promises2.rm)(this.options.cacheDir, { recursive: true, force: true });
2064
- await (0, import_promises2.mkdir)(this.options.cacheDir, { recursive: true });
2044
+ await (0, import_utils9.rm)(this.options.cacheDir, { recursive: true, force: true });
2045
+ await (0, import_utils9.mkdir)(this.options.cacheDir, { recursive: true });
2065
2046
  this.stats = {
2066
2047
  entries: 0,
2067
2048
  totalSize: 0,
@@ -2086,21 +2067,21 @@ var init_filesystem = __esm({
2086
2067
  this.ensureInitialized();
2087
2068
  let removed = 0;
2088
2069
  try {
2089
- const files = await (0, import_promises2.readdir)(this.options.cacheDir);
2070
+ const files = await (0, import_utils9.readdir)(this.options.cacheDir);
2090
2071
  for (const file of files) {
2091
2072
  if (!file.endsWith(this.options.extension)) continue;
2092
2073
  const filePath = (0, import_path3.join)(this.options.cacheDir, file);
2093
2074
  try {
2094
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
2075
+ const content = await (0, import_utils9.readFile)(filePath, "utf8");
2095
2076
  const entry = JSON.parse(content);
2096
2077
  if (Date.now() > entry.metadata.expiresAt) {
2097
- await (0, import_promises2.unlink)(filePath);
2078
+ await (0, import_utils9.unlink)(filePath);
2098
2079
  this.stats.entries = Math.max(0, this.stats.entries - 1);
2099
2080
  this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
2100
2081
  removed++;
2101
2082
  }
2102
2083
  } catch {
2103
- await (0, import_promises2.unlink)(filePath).catch(() => {
2084
+ await (0, import_utils9.unlink)(filePath).catch(() => {
2104
2085
  });
2105
2086
  removed++;
2106
2087
  }
@@ -2126,8 +2107,8 @@ var init_filesystem = __esm({
2126
2107
  * Write a cache entry to disk.
2127
2108
  */
2128
2109
  async writeEntry(filePath, entry) {
2129
- await (0, import_promises2.mkdir)((0, import_path3.dirname)(filePath), { recursive: true });
2130
- await (0, import_promises2.writeFile)(filePath, JSON.stringify(entry, null, 2), "utf8");
2110
+ await (0, import_utils9.mkdir)((0, import_path3.dirname)(filePath), { recursive: true });
2111
+ await (0, import_utils9.writeFile)(filePath, JSON.stringify(entry, null, 2));
2131
2112
  }
2132
2113
  /**
2133
2114
  * Ensure the storage is initialized.
@@ -2143,14 +2124,14 @@ var init_filesystem = __esm({
2143
2124
  */
2144
2125
  async loadStats() {
2145
2126
  try {
2146
- const files = await (0, import_promises2.readdir)(this.options.cacheDir);
2127
+ const files = await (0, import_utils9.readdir)(this.options.cacheDir);
2147
2128
  let entries = 0;
2148
2129
  let totalSize = 0;
2149
2130
  for (const file of files) {
2150
2131
  if (!file.endsWith(this.options.extension)) continue;
2151
2132
  const filePath = (0, import_path3.join)(this.options.cacheDir, file);
2152
2133
  try {
2153
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
2134
+ const content = await (0, import_utils9.readFile)(filePath, "utf8");
2154
2135
  const entry = JSON.parse(content);
2155
2136
  entries++;
2156
2137
  totalSize += entry.metadata.size;
@@ -2179,7 +2160,7 @@ var init_filesystem = __esm({
2179
2160
  */
2180
2161
  async evictLRU() {
2181
2162
  try {
2182
- const files = await (0, import_promises2.readdir)(this.options.cacheDir);
2163
+ const files = await (0, import_utils9.readdir)(this.options.cacheDir);
2183
2164
  let oldestKey = null;
2184
2165
  let oldestTime = Infinity;
2185
2166
  let corruptedFile = null;
@@ -2187,7 +2168,7 @@ var init_filesystem = __esm({
2187
2168
  if (!file.endsWith(this.options.extension)) continue;
2188
2169
  const filePath = (0, import_path3.join)(this.options.cacheDir, file);
2189
2170
  try {
2190
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
2171
+ const content = await (0, import_utils9.readFile)(filePath, "utf8");
2191
2172
  const entry = JSON.parse(content);
2192
2173
  if (entry.metadata.lastAccessedAt < oldestTime) {
2193
2174
  oldestTime = entry.metadata.lastAccessedAt;
@@ -2199,7 +2180,7 @@ var init_filesystem = __esm({
2199
2180
  }
2200
2181
  if (corruptedFile) {
2201
2182
  try {
2202
- await (0, import_promises2.unlink)(corruptedFile);
2183
+ await (0, import_utils9.unlink)(corruptedFile);
2203
2184
  this.stats.entries = Math.max(0, this.stats.entries - 1);
2204
2185
  return true;
2205
2186
  } catch {
@@ -2505,14 +2486,14 @@ async function createRedisBuilder(redisClient, keyPrefix = "frontmcp:ui:build:")
2505
2486
  await storage.initialize();
2506
2487
  return new ComponentBuilder(storage);
2507
2488
  }
2508
- var import_promises3, import_fs4, import_path4, import_crypto3, ComponentBuilder;
2489
+ var import_fs4, import_path4, import_crypto3, import_utils10, ComponentBuilder;
2509
2490
  var init_component_builder = __esm({
2510
2491
  "libs/uipack/src/bundler/file-cache/component-builder.ts"() {
2511
2492
  "use strict";
2512
- import_promises3 = require("fs/promises");
2513
2493
  import_fs4 = require("fs");
2514
2494
  import_path4 = require("path");
2515
2495
  import_crypto3 = require("crypto");
2496
+ import_utils10 = require("@frontmcp/utils");
2516
2497
  init_hash_calculator();
2517
2498
  init_resolver();
2518
2499
  init_import_map();
@@ -2559,7 +2540,7 @@ var init_component_builder = __esm({
2559
2540
  };
2560
2541
  }
2561
2542
  }
2562
- const source = await (0, import_promises3.readFile)(absoluteEntryPath, "utf8");
2543
+ const source = await (0, import_utils10.readFile)(absoluteEntryPath, "utf8");
2563
2544
  const resolver = new DependencyResolver({ platform });
2564
2545
  const resolvedDeps = [];
2565
2546
  for (const pkg of externals) {
@@ -3664,7 +3645,11 @@ FrontMcpBridge.prototype._setupDataToolCallHandler = function() {
3664
3645
  };
3665
3646
  `.trim();
3666
3647
  }
3648
+ var MAX_MINIFY_CODE_LENGTH = 5e5;
3667
3649
  function minifyJS(code) {
3650
+ if (code.length > MAX_MINIFY_CODE_LENGTH) {
3651
+ return code;
3652
+ }
3668
3653
  return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/\s+/g, " ").replace(/\s*([{};,:()[\]])\s*/g, "$1").replace(/;\}/g, "}").trim();
3669
3654
  }
3670
3655
  function generatePlatformBundle(platform, options = {}) {
@@ -4267,7 +4252,7 @@ function createTemplateHelpers() {
4267
4252
  /**
4268
4253
  * Escape HTML special characters to prevent XSS
4269
4254
  */
4270
- escapeHtml,
4255
+ escapeHtml: import_utils.escapeHtml,
4271
4256
  /**
4272
4257
  * Format a date for display
4273
4258
  */
@@ -4384,7 +4369,7 @@ function wrapToolUIUniversal(options) {
4384
4369
  resourceMode
4385
4370
  });
4386
4371
  const bridgeScript = includeBridge ? BRIDGE_SCRIPT_TAGS.universal : "";
4387
- const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
4372
+ const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
4388
4373
  return `<!DOCTYPE html>
4389
4374
  <html lang="en">
4390
4375
  <head>
@@ -4477,6 +4462,7 @@ function buildFrameworkRuntimeScriptsUniversal(options) {
4477
4462
  }
4478
4463
 
4479
4464
  // libs/uipack/src/renderers/utils/detect.ts
4465
+ var MAX_TEMPLATE_LENGTH = 5e4;
4480
4466
  function isReactComponent(value) {
4481
4467
  if (typeof value !== "function") {
4482
4468
  return false;
@@ -4505,6 +4491,9 @@ function isTemplateBuilderFunction(fn) {
4505
4491
  return true;
4506
4492
  }
4507
4493
  function containsJsx(source) {
4494
+ if (source.length > MAX_TEMPLATE_LENGTH) {
4495
+ return false;
4496
+ }
4508
4497
  if (/<[A-Z][a-zA-Z0-9]*(\s|>|\/)/.test(source)) {
4509
4498
  return true;
4510
4499
  }
@@ -4529,6 +4518,9 @@ function containsJsx(source) {
4529
4518
  return false;
4530
4519
  }
4531
4520
  function containsMdxSyntax(source) {
4521
+ if (source.length > MAX_TEMPLATE_LENGTH) {
4522
+ return false;
4523
+ }
4532
4524
  if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
4533
4525
  return true;
4534
4526
  }
@@ -5172,12 +5164,12 @@ var MdxClientRenderer = class {
5172
5164
  ...outputProps,
5173
5165
  ...props
5174
5166
  };
5175
- const escapedMdx = escapeScriptClose(JSON.stringify(template));
5176
- const escapedProps = escapeScriptClose(JSON.stringify(spreadProps));
5177
- const safeContainerId = escapeJsString(containerId);
5178
- const loadingHtml = showLoading ? `<div class="mdx-loading">${escapeHtml(loadingMessage)}</div>` : "";
5167
+ const escapedMdx = (0, import_utils.escapeScriptClose)(JSON.stringify(template));
5168
+ const escapedProps = (0, import_utils.escapeScriptClose)(JSON.stringify(spreadProps));
5169
+ const safeContainerId = (0, import_utils.escapeJsString)(containerId);
5170
+ const loadingHtml = showLoading ? `<div class="mdx-loading">${(0, import_utils.escapeHtml)(loadingMessage)}</div>` : "";
5179
5171
  return `
5180
- <div id="${escapeHtml(containerId)}">${loadingHtml}</div>
5172
+ <div id="${(0, import_utils.escapeHtml)(containerId)}">${loadingHtml}</div>
5181
5173
  <script type="module">
5182
5174
  (async function() {
5183
5175
  try {
@@ -5670,7 +5662,7 @@ function getSchemaPathStrings(schema, prefix = "output") {
5670
5662
  }
5671
5663
 
5672
5664
  // libs/uipack/src/validation/template-validator.ts
5673
- init_expression_extractor();
5665
+ init_handlebars();
5674
5666
  function validateTemplate(template, outputSchema, options = {}) {
5675
5667
  const { inputSchema, warnOnOptional = true, suggestSimilar = true, maxSuggestionDistance = 3 } = options;
5676
5668
  const errors = [];
@@ -6019,7 +6011,7 @@ function safeInputToRecord(input) {
6019
6011
  return {};
6020
6012
  }
6021
6013
  var defaultHelpers = {
6022
- escapeHtml,
6014
+ escapeHtml: import_utils.escapeHtml,
6023
6015
  formatDate: (date, format) => {
6024
6016
  const d = date instanceof Date ? date : new Date(date);
6025
6017
  if (format === "iso") return d.toISOString();
@@ -7457,7 +7449,7 @@ var BaseBuilder = class {
7457
7449
  "<head>",
7458
7450
  '<meta charset="UTF-8">',
7459
7451
  '<meta name="viewport" content="width=device-width, initial-scale=1.0">',
7460
- `<title>${escapeHtml(title)}</title>`
7452
+ `<title>${(0, import_utils.escapeHtml)(title)}</title>`
7461
7453
  ];
7462
7454
  parts.push(buildFontPreconnect());
7463
7455
  parts.push(buildFontStylesheets({ inter: true }));
@@ -7574,7 +7566,7 @@ ${body}
7574
7566
  input,
7575
7567
  output,
7576
7568
  helpers: {
7577
- escapeHtml,
7569
+ escapeHtml: import_utils.escapeHtml,
7578
7570
  formatDate: (date, format) => {
7579
7571
  const d = typeof date === "string" ? new Date(date) : date;
7580
7572
  if (isNaN(d.getTime())) return String(date);
package/bundler/index.js CHANGED
@@ -65,14 +65,14 @@ __export(filesystem_exports, {
65
65
  function createFilesystemStorage(options) {
66
66
  return new FilesystemStorage(options);
67
67
  }
68
- var import_promises, import_path, import_fs, import_crypto, CacheInitializationError, CacheOperationError, StorageNotInitializedError, DEFAULT_FS_OPTIONS, FilesystemStorage;
68
+ var import_path, import_fs, import_crypto, import_utils, CacheInitializationError, CacheOperationError, StorageNotInitializedError, DEFAULT_FS_OPTIONS, FilesystemStorage;
69
69
  var init_filesystem = __esm({
70
70
  "libs/uipack/src/bundler/file-cache/storage/filesystem.ts"() {
71
71
  "use strict";
72
- import_promises = require("fs/promises");
73
72
  import_path = require("path");
74
73
  import_fs = require("fs");
75
74
  import_crypto = require("crypto");
75
+ import_utils = require("@frontmcp/utils");
76
76
  init_interface();
77
77
  CacheInitializationError = class extends Error {
78
78
  cause;
@@ -124,7 +124,7 @@ var init_filesystem = __esm({
124
124
  async initialize() {
125
125
  if (this.initialized) return;
126
126
  try {
127
- await (0, import_promises.mkdir)(this.options.cacheDir, { recursive: true });
127
+ await (0, import_utils.mkdir)(this.options.cacheDir, { recursive: true });
128
128
  await this.loadStats();
129
129
  this.initialized = true;
130
130
  } catch (error) {
@@ -143,7 +143,7 @@ var init_filesystem = __esm({
143
143
  this.updateHitRate();
144
144
  return void 0;
145
145
  }
146
- const content = await (0, import_promises.readFile)(filePath, "utf8");
146
+ const content = await (0, import_utils.readFile)(filePath, "utf8");
147
147
  const entry = JSON.parse(content);
148
148
  if (Date.now() > entry.metadata.expiresAt) {
149
149
  await this.delete(key);
@@ -199,7 +199,7 @@ var init_filesystem = __esm({
199
199
  const filePath = this.getFilePath(key);
200
200
  try {
201
201
  if (!(0, import_fs.existsSync)(filePath)) return false;
202
- const content = await (0, import_promises.readFile)(filePath, "utf8");
202
+ const content = await (0, import_utils.readFile)(filePath, "utf8");
203
203
  const entry = JSON.parse(content);
204
204
  if (Date.now() > entry.metadata.expiresAt) {
205
205
  await this.delete(key);
@@ -218,9 +218,9 @@ var init_filesystem = __esm({
218
218
  const filePath = this.getFilePath(key);
219
219
  try {
220
220
  if (!(0, import_fs.existsSync)(filePath)) return false;
221
- const content = await (0, import_promises.readFile)(filePath, "utf8");
221
+ const content = await (0, import_utils.readFile)(filePath, "utf8");
222
222
  const entry = JSON.parse(content);
223
- await (0, import_promises.unlink)(filePath);
223
+ await (0, import_utils.unlink)(filePath);
224
224
  this.stats.entries = Math.max(0, this.stats.entries - 1);
225
225
  this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
226
226
  return true;
@@ -234,8 +234,8 @@ var init_filesystem = __esm({
234
234
  async clear() {
235
235
  this.ensureInitialized();
236
236
  try {
237
- await (0, import_promises.rm)(this.options.cacheDir, { recursive: true, force: true });
238
- await (0, import_promises.mkdir)(this.options.cacheDir, { recursive: true });
237
+ await (0, import_utils.rm)(this.options.cacheDir, { recursive: true, force: true });
238
+ await (0, import_utils.mkdir)(this.options.cacheDir, { recursive: true });
239
239
  this.stats = {
240
240
  entries: 0,
241
241
  totalSize: 0,
@@ -260,21 +260,21 @@ var init_filesystem = __esm({
260
260
  this.ensureInitialized();
261
261
  let removed = 0;
262
262
  try {
263
- const files = await (0, import_promises.readdir)(this.options.cacheDir);
263
+ const files = await (0, import_utils.readdir)(this.options.cacheDir);
264
264
  for (const file of files) {
265
265
  if (!file.endsWith(this.options.extension)) continue;
266
266
  const filePath = (0, import_path.join)(this.options.cacheDir, file);
267
267
  try {
268
- const content = await (0, import_promises.readFile)(filePath, "utf8");
268
+ const content = await (0, import_utils.readFile)(filePath, "utf8");
269
269
  const entry = JSON.parse(content);
270
270
  if (Date.now() > entry.metadata.expiresAt) {
271
- await (0, import_promises.unlink)(filePath);
271
+ await (0, import_utils.unlink)(filePath);
272
272
  this.stats.entries = Math.max(0, this.stats.entries - 1);
273
273
  this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
274
274
  removed++;
275
275
  }
276
276
  } catch {
277
- await (0, import_promises.unlink)(filePath).catch(() => {
277
+ await (0, import_utils.unlink)(filePath).catch(() => {
278
278
  });
279
279
  removed++;
280
280
  }
@@ -300,8 +300,8 @@ var init_filesystem = __esm({
300
300
  * Write a cache entry to disk.
301
301
  */
302
302
  async writeEntry(filePath, entry) {
303
- await (0, import_promises.mkdir)((0, import_path.dirname)(filePath), { recursive: true });
304
- await (0, import_promises.writeFile)(filePath, JSON.stringify(entry, null, 2), "utf8");
303
+ await (0, import_utils.mkdir)((0, import_path.dirname)(filePath), { recursive: true });
304
+ await (0, import_utils.writeFile)(filePath, JSON.stringify(entry, null, 2));
305
305
  }
306
306
  /**
307
307
  * Ensure the storage is initialized.
@@ -317,14 +317,14 @@ var init_filesystem = __esm({
317
317
  */
318
318
  async loadStats() {
319
319
  try {
320
- const files = await (0, import_promises.readdir)(this.options.cacheDir);
320
+ const files = await (0, import_utils.readdir)(this.options.cacheDir);
321
321
  let entries = 0;
322
322
  let totalSize = 0;
323
323
  for (const file of files) {
324
324
  if (!file.endsWith(this.options.extension)) continue;
325
325
  const filePath = (0, import_path.join)(this.options.cacheDir, file);
326
326
  try {
327
- const content = await (0, import_promises.readFile)(filePath, "utf8");
327
+ const content = await (0, import_utils.readFile)(filePath, "utf8");
328
328
  const entry = JSON.parse(content);
329
329
  entries++;
330
330
  totalSize += entry.metadata.size;
@@ -353,7 +353,7 @@ var init_filesystem = __esm({
353
353
  */
354
354
  async evictLRU() {
355
355
  try {
356
- const files = await (0, import_promises.readdir)(this.options.cacheDir);
356
+ const files = await (0, import_utils.readdir)(this.options.cacheDir);
357
357
  let oldestKey = null;
358
358
  let oldestTime = Infinity;
359
359
  let corruptedFile = null;
@@ -361,7 +361,7 @@ var init_filesystem = __esm({
361
361
  if (!file.endsWith(this.options.extension)) continue;
362
362
  const filePath = (0, import_path.join)(this.options.cacheDir, file);
363
363
  try {
364
- const content = await (0, import_promises.readFile)(filePath, "utf8");
364
+ const content = await (0, import_utils.readFile)(filePath, "utf8");
365
365
  const entry = JSON.parse(content);
366
366
  if (entry.metadata.lastAccessedAt < oldestTime) {
367
367
  oldestTime = entry.metadata.lastAccessedAt;
@@ -373,7 +373,7 @@ var init_filesystem = __esm({
373
373
  }
374
374
  if (corruptedFile) {
375
375
  try {
376
- await (0, import_promises.unlink)(corruptedFile);
376
+ await (0, import_utils.unlink)(corruptedFile);
377
377
  this.stats.entries = Math.max(0, this.stats.entries - 1);
378
378
  return true;
379
379
  } catch {
@@ -1462,9 +1462,9 @@ init_redis();
1462
1462
 
1463
1463
  // libs/uipack/src/bundler/file-cache/hash-calculator.ts
1464
1464
  var import_crypto2 = require("crypto");
1465
- var import_promises2 = require("fs/promises");
1466
1465
  var import_fs2 = require("fs");
1467
1466
  var import_path2 = require("path");
1467
+ var import_utils2 = require("@frontmcp/utils");
1468
1468
  function sha256(content) {
1469
1469
  return (0, import_crypto2.createHash)("sha256").update(content, "utf8").digest("hex");
1470
1470
  }
@@ -1473,7 +1473,7 @@ function sha256Buffer(buffer) {
1473
1473
  }
1474
1474
  async function hashFile(filePath) {
1475
1475
  try {
1476
- const content = await (0, import_promises2.readFile)(filePath);
1476
+ const content = await (0, import_utils2.readFileBuffer)(filePath);
1477
1477
  return sha256Buffer(content);
1478
1478
  } catch {
1479
1479
  return void 0;
@@ -1534,7 +1534,7 @@ async function collectLocalDependencies(filePath, baseDir, collected, maxDepth,
1534
1534
  if (!(0, import_fs2.existsSync)(filePath)) return;
1535
1535
  collected.add(filePath);
1536
1536
  try {
1537
- const content = await (0, import_promises2.readFile)(filePath, "utf8");
1537
+ const content = await (0, import_utils2.readFile)(filePath);
1538
1538
  const imports = extractImportPaths(content);
1539
1539
  for (const importPath of imports) {
1540
1540
  if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
@@ -1608,10 +1608,10 @@ function buildIdFromHash(hash) {
1608
1608
  }
1609
1609
 
1610
1610
  // libs/uipack/src/bundler/file-cache/component-builder.ts
1611
- var import_promises3 = require("fs/promises");
1612
1611
  var import_fs3 = require("fs");
1613
1612
  var import_path3 = require("path");
1614
1613
  var import_crypto3 = require("crypto");
1614
+ var import_utils5 = require("@frontmcp/utils");
1615
1615
 
1616
1616
  // libs/uipack/src/dependency/cdn-registry.ts
1617
1617
  var DEFAULT_CDN_REGISTRY = {
@@ -2374,10 +2374,8 @@ function parseImports(source) {
2374
2374
  };
2375
2375
  }
2376
2376
 
2377
- // libs/uipack/src/utils/escape-html.ts
2378
- function escapeHtmlAttr(str) {
2379
- return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
2380
- }
2377
+ // libs/uipack/src/utils/index.ts
2378
+ var import_utils3 = require("@frontmcp/utils");
2381
2379
 
2382
2380
  // libs/uipack/src/dependency/import-map.ts
2383
2381
  function createImportMap(dependencies) {
@@ -2424,13 +2422,16 @@ function generateUMDShim(dependencies, options = {}) {
2424
2422
  console.warn('UMD shim failed:', e);
2425
2423
  }
2426
2424
  })();` : `window.__esm_shim = ${shimObject};`;
2427
- return minify ? code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1") : code;
2425
+ if (minify && code.length <= 1e5) {
2426
+ return code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1");
2427
+ }
2428
+ return code;
2428
2429
  }
2429
2430
  function generateCDNScriptTags(dependencies) {
2430
2431
  return dependencies.filter((dep) => !dep.esm).map((dep) => {
2431
- const attrs = [`src="${escapeHtmlAttr(dep.cdnUrl)}"`];
2432
+ const attrs = [`src="${(0, import_utils3.escapeHtmlAttr)(dep.cdnUrl)}"`];
2432
2433
  if (dep.integrity) {
2433
- attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
2434
+ attrs.push(`integrity="${(0, import_utils3.escapeHtmlAttr)(dep.integrity)}"`);
2434
2435
  }
2435
2436
  attrs.push('crossorigin="anonymous"');
2436
2437
  return `<script ${attrs.join(" ")}></script>`;
@@ -2438,9 +2439,9 @@ function generateCDNScriptTags(dependencies) {
2438
2439
  }
2439
2440
  function generateESMScriptTags(dependencies) {
2440
2441
  return dependencies.filter((dep) => dep.esm).map((dep) => {
2441
- const attrs = ['type="module"', `src="${escapeHtmlAttr(dep.cdnUrl)}"`];
2442
+ const attrs = ['type="module"', `src="${(0, import_utils3.escapeHtmlAttr)(dep.cdnUrl)}"`];
2442
2443
  if (dep.integrity) {
2443
- attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
2444
+ attrs.push(`integrity="${(0, import_utils3.escapeHtmlAttr)(dep.integrity)}"`);
2444
2445
  }
2445
2446
  attrs.push('crossorigin="anonymous"');
2446
2447
  return `<script ${attrs.join(" ")}></script>`;
@@ -2699,7 +2700,7 @@ var ComponentBuilder = class {
2699
2700
  };
2700
2701
  }
2701
2702
  }
2702
- const source = await (0, import_promises3.readFile)(absoluteEntryPath, "utf8");
2703
+ const source = await (0, import_utils5.readFile)(absoluteEntryPath, "utf8");
2703
2704
  const resolver = new DependencyResolver({ platform });
2704
2705
  const resolvedDeps = [];
2705
2706
  for (const pkg of externals) {
@@ -1 +1 @@
1
- {"version":3,"file":"import-map.d.ts","sourceRoot":"","sources":["../../src/dependency/import-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAO5E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAgB7E;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,CAgBnG;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,SAAS,CAwB/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAQtG;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAIjE;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAIzE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,kBAAkB,EAAE,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CA4BxG;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAclF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAclF;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,kBAAkB,EAAE,EAClC,OAAO,GAAE,qBAA0B,GAClC,MAAM,CA2BR;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAiDpF"}
1
+ {"version":3,"file":"import-map.d.ts","sourceRoot":"","sources":["../../src/dependency/import-map.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAO5E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,SAAS,CAgB7E;AAED;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,SAAS,CAgBnG;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,GAAG,IAAI,EAAE,SAAS,EAAE,GAAG,SAAS,CAwB/D;AAED;;;;;;;;;GASG;AACH,wBAAgB,QAAQ,CAAC,GAAG,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAQtG;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAIjE;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAAC,GAAG,EAAE,SAAS,GAAG,MAAM,CAIzE;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,YAAY,EAAE,kBAAkB,EAAE,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CAgCxG;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAclF;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,kBAAkB,EAAE,GAAG,MAAM,EAAE,CAclF;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;OAGG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,kBAAkB,EAAE,EAClC,OAAO,GAAE,qBAA0B,GAClC,MAAM,CA2BR;AAMD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAiDpF"}