@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
@@ -1 +1 @@
1
- {"version":3,"file":"css-to-theme.d.ts","sourceRoot":"","sources":["../../src/theme/css-to-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA2BpE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAU/D"}
1
+ {"version":3,"file":"css-to-theme.d.ts","sourceRoot":"","sources":["../../src/theme/css-to-theme.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;;OAIG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAwCD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAoCpE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAU/D"}
package/theme/index.js CHANGED
@@ -736,7 +736,15 @@ function buildStyleBlock(theme) {
736
736
 
737
737
  // libs/uipack/src/theme/css-to-theme.ts
738
738
  var COLOR_VAR_REGEX = /--(color-[\w-]+):\s*([^;]+);/g;
739
+ var MAX_CSS_INPUT_LENGTH = 1e5;
739
740
  function cssToTailwindTheme(userCss) {
741
+ if (userCss.length > MAX_CSS_INPUT_LENGTH) {
742
+ return {
743
+ themeBlock: "",
744
+ remainingCss: userCss,
745
+ colorVars: /* @__PURE__ */ new Map()
746
+ };
747
+ }
740
748
  const colorVars = /* @__PURE__ */ new Map();
741
749
  const regex = new RegExp(COLOR_VAR_REGEX.source, "g");
742
750
  let match;
@@ -30,25 +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
- var init_escape_html = __esm({
42
- "libs/uipack/src/utils/escape-html.ts"() {
43
- "use strict";
44
- }
45
- });
46
-
47
33
  // libs/uipack/src/utils/index.ts
34
+ var import_utils;
48
35
  var init_utils = __esm({
49
36
  "libs/uipack/src/utils/index.ts"() {
50
37
  "use strict";
51
- init_escape_html();
38
+ import_utils = require("@frontmcp/utils");
52
39
  }
53
40
  });
54
41
 
@@ -238,7 +225,7 @@ var init_helpers = __esm({
238
225
  idCounter = 0;
239
226
  builtinHelpers = {
240
227
  // Escaping
241
- escapeHtml,
228
+ escapeHtml: import_utils.escapeHtml,
242
229
  // Formatting
243
230
  formatDate,
244
231
  formatCurrency,
@@ -409,7 +396,7 @@ __export(handlebars_exports, {
409
396
  createHandlebarsRenderer: () => createHandlebarsRenderer,
410
397
  defaultValue: () => defaultValue,
411
398
  eq: () => eq,
412
- escapeHtml: () => escapeHtml,
399
+ escapeHtml: () => import_utils.escapeHtml,
413
400
  extractAll: () => extractAll,
414
401
  extractExpressions: () => extractExpressions,
415
402
  extractInputPaths: () => extractInputPaths,
@@ -1499,7 +1486,11 @@ FrontMcpBridge.prototype._setupDataToolCallHandler = function() {
1499
1486
  };
1500
1487
  `.trim();
1501
1488
  }
1489
+ var MAX_MINIFY_CODE_LENGTH = 5e5;
1502
1490
  function minifyJS(code) {
1491
+ if (code.length > MAX_MINIFY_CODE_LENGTH) {
1492
+ return code;
1493
+ }
1503
1494
  return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/\s+/g, " ").replace(/\s*([{};,:()[\]])\s*/g, "$1").replace(/;\}/g, "}").trim();
1504
1495
  }
1505
1496
  function generatePlatformBundle(platform, options = {}) {
@@ -2624,7 +2615,11 @@ function detectPIIType(value) {
2624
2615
  if (isIPv4(value)) return "IP";
2625
2616
  return null;
2626
2617
  }
2618
+ var MAX_PII_TEXT_LENGTH = 1e5;
2627
2619
  function redactPIIFromText(text) {
2620
+ if (text.length > MAX_PII_TEXT_LENGTH) {
2621
+ return text;
2622
+ }
2628
2623
  let result = text;
2629
2624
  result = result.replace(PII_PATTERNS.creditCardInText, REDACTION_TOKENS.CARD);
2630
2625
  result = result.replace(PII_PATTERNS.ssnInText, REDACTION_TOKENS.ID);
@@ -2707,7 +2702,7 @@ function createTemplateHelpers() {
2707
2702
  /**
2708
2703
  * Escape HTML special characters to prevent XSS
2709
2704
  */
2710
- escapeHtml,
2705
+ escapeHtml: import_utils.escapeHtml,
2711
2706
  /**
2712
2707
  * Format a date for display
2713
2708
  */
@@ -2811,7 +2806,7 @@ function wrapToolUI(options) {
2811
2806
  widgetAccessible,
2812
2807
  hostContext
2813
2808
  });
2814
- const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
2809
+ const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
2815
2810
  return `<!DOCTYPE html>
2816
2811
  <html lang="en">
2817
2812
  <head>
@@ -2916,6 +2911,7 @@ function buildDataInjectionScript(options) {
2916
2911
  init_utils();
2917
2912
 
2918
2913
  // libs/uipack/src/renderers/utils/detect.ts
2914
+ var MAX_TEMPLATE_LENGTH = 5e4;
2919
2915
  function isReactComponent(value) {
2920
2916
  if (typeof value !== "function") {
2921
2917
  return false;
@@ -2944,6 +2940,9 @@ function isTemplateBuilderFunction(fn) {
2944
2940
  return true;
2945
2941
  }
2946
2942
  function containsJsx(source) {
2943
+ if (source.length > MAX_TEMPLATE_LENGTH) {
2944
+ return false;
2945
+ }
2947
2946
  if (/<[A-Z][a-zA-Z0-9]*(\s|>|\/)/.test(source)) {
2948
2947
  return true;
2949
2948
  }
@@ -2968,6 +2967,9 @@ function containsJsx(source) {
2968
2967
  return false;
2969
2968
  }
2970
2969
  function containsMdxSyntax(source) {
2970
+ if (source.length > MAX_TEMPLATE_LENGTH) {
2971
+ return false;
2972
+ }
2971
2973
  if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
2972
2974
  return true;
2973
2975
  }
@@ -3500,16 +3502,16 @@ function heading(text, level = 2) {
3500
3502
  3: "text-lg font-medium text-text-primary mb-2",
3501
3503
  4: "text-base font-medium text-text-secondary mb-2"
3502
3504
  }[level] || "";
3503
- return `<${tag} class="${classes}">${escapeHtml(text)}</${tag}>`;
3505
+ return `<${tag} class="${classes}">${(0, import_utils.escapeHtml)(text)}</${tag}>`;
3504
3506
  }
3505
3507
  function paragraph(text, className = "") {
3506
- return `<p class="text-text-secondary ${className}">${escapeHtml(text)}</p>`;
3508
+ return `<p class="text-text-secondary ${className}">${(0, import_utils.escapeHtml)(text)}</p>`;
3507
3509
  }
3508
3510
  function keyValue(key, value, className = "") {
3509
3511
  const displayValue = typeof value === "boolean" ? value ? "Yes" : "No" : String(value);
3510
3512
  return `<div class="flex justify-between items-center py-2 border-b border-border ${className}">
3511
- <span class="text-text-secondary">${escapeHtml(key)}</span>
3512
- <span class="text-text-primary font-medium">${escapeHtml(displayValue)}</span>
3513
+ <span class="text-text-secondary">${(0, import_utils.escapeHtml)(key)}</span>
3514
+ <span class="text-text-primary font-medium">${(0, import_utils.escapeHtml)(displayValue)}</span>
3513
3515
  </div>`;
3514
3516
  }
3515
3517
  function dataList(items) {
@@ -3522,9 +3524,9 @@ function errorDisplay(message, details) {
3522
3524
  <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
3523
3525
  <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"/>
3524
3526
  </svg>
3525
- <span class="font-medium">${escapeHtml(message)}</span>
3527
+ <span class="font-medium">${(0, import_utils.escapeHtml)(message)}</span>
3526
3528
  </div>
3527
- ${details ? `<p class="mt-2 text-sm text-text-secondary">${escapeHtml(details)}</p>` : ""}
3529
+ ${details ? `<p class="mt-2 text-sm text-text-secondary">${(0, import_utils.escapeHtml)(details)}</p>` : ""}
3528
3530
  </div>`;
3529
3531
  }
3530
3532
  function successDisplay(message, details) {
@@ -3533,9 +3535,9 @@ function successDisplay(message, details) {
3533
3535
  <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
3534
3536
  <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"/>
3535
3537
  </svg>
3536
- <span class="font-medium">${escapeHtml(message)}</span>
3538
+ <span class="font-medium">${(0, import_utils.escapeHtml)(message)}</span>
3537
3539
  </div>
3538
- ${details ? `<p class="mt-2 text-sm text-text-secondary">${escapeHtml(details)}</p>` : ""}
3540
+ ${details ? `<p class="mt-2 text-sm text-text-secondary">${(0, import_utils.escapeHtml)(details)}</p>` : ""}
3539
3541
  </div>`;
3540
3542
  }
3541
3543
  function loadingDisplay(message = "Loading...") {
@@ -3545,7 +3547,7 @@ function loadingDisplay(message = "Loading...") {
3545
3547
  <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
3546
3548
  <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
3547
3549
  </svg>
3548
- <span>${escapeHtml(message)}</span>
3550
+ <span>${(0, import_utils.escapeHtml)(message)}</span>
3549
3551
  </div>
3550
3552
  </div>`;
3551
3553
  }
@@ -1 +1 @@
1
- {"version":3,"file":"dts-parser.d.ts","sourceRoot":"","sources":["../../src/typings/dts-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAa,cAAc,EAAE,MAAM,SAAS,CAAC;AAwCzD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CA2F/D;AAaD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAiBjE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcrE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAoDxE"}
1
+ {"version":3,"file":"dts-parser.d.ts","sourceRoot":"","sources":["../../src/typings/dts-parser.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAa,cAAc,EAAE,MAAM,SAAS,CAAC;AAwCzD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CA2F/D;AAaD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAQ3D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAiBjE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAM7E;AAQD;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAmBrE;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAoDxE"}
package/typings/index.js CHANGED
@@ -418,7 +418,11 @@ function getSubpathFromSpecifier(specifier) {
418
418
  }
419
419
  return void 0;
420
420
  }
421
+ var MAX_IMPORT_STATEMENT_LENGTH = 2e3;
421
422
  function parseImportStatement(statement) {
423
+ if (statement.length > MAX_IMPORT_STATEMENT_LENGTH) {
424
+ return null;
425
+ }
422
426
  const namedMatch = /import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/.exec(statement);
423
427
  if (namedMatch) {
424
428
  return namedMatch[1];
package/utils/index.d.ts CHANGED
@@ -1,10 +1,9 @@
1
1
  /**
2
2
  * @frontmcp/ui Utilities
3
3
  *
4
- * Common utility functions for UI operations.
4
+ * Re-exports common utility functions from @frontmcp/utils.
5
5
  *
6
6
  * @packageDocumentation
7
7
  */
8
- export { safeStringify } from './safe-stringify';
9
- export { escapeHtml, escapeHtmlAttr, escapeJsString, escapeScriptClose, safeJsonForScript } from './escape-html';
8
+ export { safeStringify, escapeHtml, escapeHtmlAttr, escapeJsString, escapeScriptClose, safeJsonForScript, } from '@frontmcp/utils';
10
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,aAAa,EACb,UAAU,EACV,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,iBAAiB,CAAC"}
package/utils/index.js CHANGED
@@ -20,71 +20,15 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // libs/uipack/src/utils/index.ts
21
21
  var utils_exports = {};
22
22
  __export(utils_exports, {
23
- escapeHtml: () => escapeHtml,
24
- escapeHtmlAttr: () => escapeHtmlAttr,
25
- escapeJsString: () => escapeJsString,
26
- escapeScriptClose: () => escapeScriptClose,
27
- safeJsonForScript: () => safeJsonForScript,
28
- safeStringify: () => safeStringify
23
+ escapeHtml: () => import_utils.escapeHtml,
24
+ escapeHtmlAttr: () => import_utils.escapeHtmlAttr,
25
+ escapeJsString: () => import_utils.escapeJsString,
26
+ escapeScriptClose: () => import_utils.escapeScriptClose,
27
+ safeJsonForScript: () => import_utils.safeJsonForScript,
28
+ safeStringify: () => import_utils.safeStringify
29
29
  });
30
30
  module.exports = __toCommonJS(utils_exports);
31
-
32
- // libs/uipack/src/utils/safe-stringify.ts
33
- function safeStringify(value, space) {
34
- const seen = /* @__PURE__ */ new WeakSet();
35
- try {
36
- return JSON.stringify(
37
- value,
38
- (_key, val) => {
39
- if (typeof val === "object" && val !== null) {
40
- if (seen.has(val)) return "[Circular]";
41
- seen.add(val);
42
- }
43
- return val;
44
- },
45
- space
46
- );
47
- } catch {
48
- return JSON.stringify({ error: "Output could not be serialized" });
49
- }
50
- }
51
-
52
- // libs/uipack/src/utils/escape-html.ts
53
- function escapeHtml(str) {
54
- if (str === null || str === void 0) {
55
- return "";
56
- }
57
- const s = String(str);
58
- 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");
59
- }
60
- function escapeHtmlAttr(str) {
61
- return str.replace(/&/g, "&amp;").replace(/"/g, "&quot;");
62
- }
63
- function escapeJsString(str) {
64
- 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");
65
- }
66
- function escapeScriptClose(jsonString) {
67
- return jsonString.replace(/<\//g, "<\\/");
68
- }
69
- function safeJsonForScript(value) {
70
- if (value === void 0) {
71
- return "null";
72
- }
73
- try {
74
- const jsonString = JSON.stringify(value, (_key, val) => {
75
- if (typeof val === "bigint") {
76
- return val.toString();
77
- }
78
- return val;
79
- });
80
- if (jsonString === void 0) {
81
- return "null";
82
- }
83
- return escapeScriptClose(jsonString);
84
- } catch {
85
- return '{"error":"Value could not be serialized"}';
86
- }
87
- }
31
+ var import_utils = require("@frontmcp/utils");
88
32
  // Annotate the CommonJS export names for ESM import in node:
89
33
  0 && (module.exports = {
90
34
  escapeHtml,
@@ -38,14 +38,8 @@ __export(validation_exports, {
38
38
  });
39
39
  module.exports = __toCommonJS(validation_exports);
40
40
 
41
- // libs/uipack/src/utils/escape-html.ts
42
- function escapeHtml(str) {
43
- if (str === null || str === void 0) {
44
- return "";
45
- }
46
- const s = String(str);
47
- 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");
48
- }
41
+ // libs/uipack/src/utils/index.ts
42
+ var import_utils = require("@frontmcp/utils");
49
43
 
50
44
  // libs/uipack/src/validation/error-box.ts
51
45
  var errorIcon = `<svg class="w-5 h-5 flex-shrink-0" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
@@ -57,13 +51,13 @@ function validationErrorBox(options) {
57
51
  class="validation-error flex items-start gap-3 p-4 bg-red-50 border border-red-200 text-red-800 rounded-lg"
58
52
  role="alert"
59
53
  data-testid="validation-error"
60
- data-component="${escapeHtml(componentName)}"
61
- data-param="${escapeHtml(invalidParam)}"
54
+ data-component="${(0, import_utils.escapeHtml)(componentName)}"
55
+ data-param="${(0, import_utils.escapeHtml)(invalidParam)}"
62
56
  >
63
57
  ${errorIcon}
64
58
  <div class="min-w-0">
65
- <p class="font-semibold text-sm">${escapeHtml(componentName)}: Invalid Configuration</p>
66
- <p class="text-sm opacity-90 mt-0.5">The "${escapeHtml(invalidParam)}" parameter is invalid.</p>
59
+ <p class="font-semibold text-sm">${(0, import_utils.escapeHtml)(componentName)}: Invalid Configuration</p>
60
+ <p class="text-sm opacity-90 mt-0.5">The "${(0, import_utils.escapeHtml)(invalidParam)}" parameter is invalid.</p>
67
61
  </div>
68
62
  </div>`;
69
63
  }
@@ -1,102 +0,0 @@
1
- /**
2
- * HTML Escaping Utilities
3
- *
4
- * Functions for escaping strings to prevent XSS attacks in HTML output.
5
- *
6
- * @packageDocumentation
7
- */
8
- /**
9
- * Escape HTML special characters to prevent XSS.
10
- *
11
- * Handles null/undefined by returning empty string.
12
- * Converts non-string values to string before escaping.
13
- *
14
- * @param str - Value to escape (will be converted to string)
15
- * @returns Escaped string safe for HTML content
16
- *
17
- * @example
18
- * ```typescript
19
- * escapeHtml('<script>alert("xss")</script>')
20
- * // Returns: '&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;'
21
- *
22
- * escapeHtml(null) // Returns: ''
23
- * escapeHtml(123) // Returns: '123'
24
- * ```
25
- */
26
- export declare function escapeHtml(str: unknown): string;
27
- /**
28
- * Escape string for use in HTML attributes.
29
- *
30
- * Lighter version that only escapes & and " characters,
31
- * suitable for attribute values that are already quoted.
32
- *
33
- * @param str - String to escape
34
- * @returns Escaped string safe for HTML attributes
35
- *
36
- * @example
37
- * ```typescript
38
- * escapeHtmlAttr('value with "quotes" & ampersand')
39
- * // Returns: 'value with &quot;quotes&quot; &amp; ampersand'
40
- * ```
41
- */
42
- export declare function escapeHtmlAttr(str: string): string;
43
- /**
44
- * Escape string for use in JavaScript string literals.
45
- *
46
- * Escapes characters that could break out of a JS string context.
47
- *
48
- * @param str - String to escape
49
- * @returns Escaped string safe for JS string literals
50
- *
51
- * @example
52
- * ```typescript
53
- * escapeJsString("it's a \"test\"")
54
- * // Returns: "it\\'s a \\\"test\\\""
55
- * ```
56
- */
57
- export declare function escapeJsString(str: string): string;
58
- /**
59
- * Escape script closing tags in JSON strings to prevent XSS.
60
- *
61
- * When embedding JSON in a <script> tag, the string `</script>` will
62
- * prematurely close the script block. This function escapes the closing
63
- * tag by replacing `</` with `<\/`.
64
- *
65
- * @param jsonString - JSON string (already passed through JSON.stringify)
66
- * @returns Escaped JSON string safe for embedding in script tags
67
- *
68
- * @example
69
- * ```typescript
70
- * const json = JSON.stringify({ html: '</script><script>alert(1)</script>' });
71
- * escapeScriptClose(json);
72
- * // Returns: '{"html":"<\\/script><script>alert(1)<\\/script>"}'
73
- * ```
74
- */
75
- export declare function escapeScriptClose(jsonString: string): string;
76
- /**
77
- * Safely serialize a value to JSON for embedding in HTML <script> tags.
78
- *
79
- * Combines JSON.stringify with escapeScriptClose to prevent XSS attacks
80
- * where malicious data contains `</script>` or other HTML-sensitive sequences.
81
- *
82
- * Handles edge cases:
83
- * - undefined: Returns 'null' (since undefined is not valid JSON)
84
- * - Circular references: Returns error placeholder
85
- * - BigInt: Converted to string representation
86
- * - Functions/Symbols: Omitted (standard JSON.stringify behavior)
87
- *
88
- * @param value - Value to serialize
89
- * @returns Escaped JSON string safe for embedding in script tags
90
- *
91
- * @example
92
- * ```typescript
93
- * const data = { html: '</script><script>alert("xss")</script>' };
94
- * const safe = safeJsonForScript(data);
95
- * // Returns: '{"html":"<\\/script><script>alert(\\"xss\\")<\\/script>"}'
96
- *
97
- * // Safe to use in:
98
- * // <script>const data = ${safeJsonForScript(data)};</script>
99
- * ```
100
- */
101
- export declare function safeJsonForScript(value: unknown): string;
102
- //# sourceMappingURL=escape-html.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"escape-html.d.ts","sourceRoot":"","sources":["../../src/utils/escape-html.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAc/C;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAyBxD"}
@@ -1,30 +0,0 @@
1
- /**
2
- * @file safe-stringify.ts
3
- * @description Safe JSON stringification utility that handles circular references and edge cases.
4
- *
5
- * This prevents tool calls from failing due to serialization errors when
6
- * the output contains circular references or non-serializable values.
7
- */
8
- /**
9
- * Safely stringify a value, handling circular references and other edge cases.
10
- *
11
- * @param value - The value to stringify
12
- * @param space - Optional indentation for pretty-printing (passed to JSON.stringify)
13
- * @returns JSON string representation of the value
14
- *
15
- * @example
16
- * ```typescript
17
- * // Normal object
18
- * safeStringify({ name: 'test' }); // '{"name":"test"}'
19
- *
20
- * // Circular reference
21
- * const obj = { name: 'test' };
22
- * obj.self = obj;
23
- * safeStringify(obj); // '{"name":"test","self":"[Circular]"}'
24
- *
25
- * // Pretty print
26
- * safeStringify({ name: 'test' }, 2); // '{\n "name": "test"\n}'
27
- * ```
28
- */
29
- export declare function safeStringify(value: unknown, space?: number): string;
30
- //# sourceMappingURL=safe-stringify.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"safe-stringify.d.ts","sourceRoot":"","sources":["../../src/utils/safe-stringify.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBpE"}