@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.
- package/CLAUDE.md +0 -14
- package/adapters/index.js +50 -47
- package/adapters/platform-meta.d.ts.map +1 -1
- package/adapters/response-builder.d.ts +16 -3
- package/adapters/response-builder.d.ts.map +1 -1
- package/bridge-runtime/iife-generator.d.ts.map +1 -1
- package/bridge-runtime/index.js +4 -0
- package/build/index.d.ts +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +61 -69
- package/bundler/index.js +35 -34
- package/dependency/import-map.d.ts.map +1 -1
- package/dependency/index.js +22 -29
- package/esm/adapters/index.mjs +52 -42
- package/esm/bridge-runtime/index.mjs +4 -0
- package/esm/build/index.mjs +30 -32
- package/esm/bundler/index.mjs +19 -11
- package/esm/dependency/index.mjs +18 -18
- package/esm/handlebars/index.mjs +9 -8
- package/esm/index.mjs +107 -126
- package/esm/package.json +3 -2
- package/esm/registry/index.mjs +53 -49
- package/esm/renderers/index.mjs +15 -21
- package/esm/runtime/index.mjs +16 -15
- package/esm/theme/index.mjs +8 -0
- package/esm/tool-template/index.mjs +23 -15
- package/esm/typings/index.mjs +4 -0
- package/esm/utils/index.mjs +9 -56
- package/esm/validation/index.mjs +9 -8
- package/handlebars/index.js +4 -10
- package/index.js +186 -211
- package/package.json +3 -2
- package/preview/generic-preview.d.ts +4 -5
- package/preview/generic-preview.d.ts.map +1 -1
- package/preview/types.d.ts +15 -1
- package/preview/types.d.ts.map +1 -1
- package/registry/index.js +61 -63
- package/registry/render-template.d.ts.map +1 -1
- package/renderers/index.js +16 -28
- package/renderers/utils/detect.d.ts.map +1 -1
- package/runtime/index.js +20 -25
- package/runtime/sanitizer.d.ts.map +1 -1
- package/theme/css-to-theme.d.ts +0 -27
- package/theme/css-to-theme.d.ts.map +1 -1
- package/theme/index.js +8 -0
- package/tool-template/index.js +30 -28
- package/typings/dts-parser.d.ts.map +1 -1
- package/typings/index.js +4 -0
- package/utils/index.d.ts +2 -3
- package/utils/index.d.ts.map +1 -1
- package/utils/index.js +7 -63
- package/validation/index.js +6 -12
- package/utils/escape-html.d.ts +0 -102
- package/utils/escape-html.d.ts.map +0 -1
- package/utils/safe-stringify.d.ts +0 -30
- 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;
|
|
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;
|
package/tool-template/index.js
CHANGED
|
@@ -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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").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
|
-
|
|
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;
|
|
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
|
-
*
|
|
4
|
+
* Re-exports common utility functions from @frontmcp/utils.
|
|
5
5
|
*
|
|
6
6
|
* @packageDocumentation
|
|
7
7
|
*/
|
|
8
|
-
export { safeStringify } from '
|
|
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
|
package/utils/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
59
|
-
}
|
|
60
|
-
function escapeHtmlAttr(str) {
|
|
61
|
-
return str.replace(/&/g, "&").replace(/"/g, """);
|
|
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,
|
package/validation/index.js
CHANGED
|
@@ -38,14 +38,8 @@ __export(validation_exports, {
|
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(validation_exports);
|
|
40
40
|
|
|
41
|
-
// libs/uipack/src/utils/
|
|
42
|
-
|
|
43
|
-
if (str === null || str === void 0) {
|
|
44
|
-
return "";
|
|
45
|
-
}
|
|
46
|
-
const s = String(str);
|
|
47
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").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
|
}
|
package/utils/escape-html.d.ts
DELETED
|
@@ -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: '<script>alert("xss")</script>'
|
|
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 "quotes" & 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"}
|