@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
package/index.js
CHANGED
|
@@ -30,79 +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/safe-stringify.ts
|
|
34
|
-
function safeStringify(value, space) {
|
|
35
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
36
|
-
try {
|
|
37
|
-
return JSON.stringify(
|
|
38
|
-
value,
|
|
39
|
-
(_key, val) => {
|
|
40
|
-
if (typeof val === "object" && val !== null) {
|
|
41
|
-
if (seen.has(val)) return "[Circular]";
|
|
42
|
-
seen.add(val);
|
|
43
|
-
}
|
|
44
|
-
return val;
|
|
45
|
-
},
|
|
46
|
-
space
|
|
47
|
-
);
|
|
48
|
-
} catch {
|
|
49
|
-
return JSON.stringify({ error: "Output could not be serialized" });
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
var init_safe_stringify = __esm({
|
|
53
|
-
"libs/uipack/src/utils/safe-stringify.ts"() {
|
|
54
|
-
"use strict";
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// libs/uipack/src/utils/escape-html.ts
|
|
59
|
-
function escapeHtml(str) {
|
|
60
|
-
if (str === null || str === void 0) {
|
|
61
|
-
return "";
|
|
62
|
-
}
|
|
63
|
-
const s = String(str);
|
|
64
|
-
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
65
|
-
}
|
|
66
|
-
function escapeHtmlAttr(str) {
|
|
67
|
-
return str.replace(/&/g, "&").replace(/"/g, """);
|
|
68
|
-
}
|
|
69
|
-
function escapeJsString(str) {
|
|
70
|
-
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");
|
|
71
|
-
}
|
|
72
|
-
function escapeScriptClose(jsonString) {
|
|
73
|
-
return jsonString.replace(/<\//g, "<\\/");
|
|
74
|
-
}
|
|
75
|
-
function safeJsonForScript(value) {
|
|
76
|
-
if (value === void 0) {
|
|
77
|
-
return "null";
|
|
78
|
-
}
|
|
79
|
-
try {
|
|
80
|
-
const jsonString = JSON.stringify(value, (_key, val) => {
|
|
81
|
-
if (typeof val === "bigint") {
|
|
82
|
-
return val.toString();
|
|
83
|
-
}
|
|
84
|
-
return val;
|
|
85
|
-
});
|
|
86
|
-
if (jsonString === void 0) {
|
|
87
|
-
return "null";
|
|
88
|
-
}
|
|
89
|
-
return escapeScriptClose(jsonString);
|
|
90
|
-
} catch {
|
|
91
|
-
return '{"error":"Value could not be serialized"}';
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
var init_escape_html = __esm({
|
|
95
|
-
"libs/uipack/src/utils/escape-html.ts"() {
|
|
96
|
-
"use strict";
|
|
97
|
-
}
|
|
98
|
-
});
|
|
99
|
-
|
|
100
33
|
// libs/uipack/src/utils/index.ts
|
|
34
|
+
var import_utils;
|
|
101
35
|
var init_utils = __esm({
|
|
102
36
|
"libs/uipack/src/utils/index.ts"() {
|
|
103
37
|
"use strict";
|
|
104
|
-
|
|
105
|
-
init_escape_html();
|
|
38
|
+
import_utils = require("@frontmcp/utils");
|
|
106
39
|
}
|
|
107
40
|
});
|
|
108
41
|
|
|
@@ -820,6 +753,13 @@ var init_theme = __esm({
|
|
|
820
753
|
|
|
821
754
|
// libs/uipack/src/theme/css-to-theme.ts
|
|
822
755
|
function cssToTailwindTheme(userCss) {
|
|
756
|
+
if (userCss.length > MAX_CSS_INPUT_LENGTH) {
|
|
757
|
+
return {
|
|
758
|
+
themeBlock: "",
|
|
759
|
+
remainingCss: userCss,
|
|
760
|
+
colorVars: /* @__PURE__ */ new Map()
|
|
761
|
+
};
|
|
762
|
+
}
|
|
823
763
|
const colorVars = /* @__PURE__ */ new Map();
|
|
824
764
|
const regex = new RegExp(COLOR_VAR_REGEX.source, "g");
|
|
825
765
|
let match;
|
|
@@ -852,11 +792,12 @@ function buildTailwindStyleBlock(userCss) {
|
|
|
852
792
|
${parts.join("\n\n")}
|
|
853
793
|
</style>`;
|
|
854
794
|
}
|
|
855
|
-
var COLOR_VAR_REGEX;
|
|
795
|
+
var COLOR_VAR_REGEX, MAX_CSS_INPUT_LENGTH;
|
|
856
796
|
var init_css_to_theme = __esm({
|
|
857
797
|
"libs/uipack/src/theme/css-to-theme.ts"() {
|
|
858
798
|
"use strict";
|
|
859
799
|
COLOR_VAR_REGEX = /--(color-[\w-]+):\s*([^;]+);/g;
|
|
800
|
+
MAX_CSS_INPUT_LENGTH = 1e5;
|
|
860
801
|
}
|
|
861
802
|
});
|
|
862
803
|
|
|
@@ -901,6 +842,9 @@ function isTemplateBuilderFunction(fn) {
|
|
|
901
842
|
return true;
|
|
902
843
|
}
|
|
903
844
|
function containsJsx(source) {
|
|
845
|
+
if (source.length > MAX_TEMPLATE_LENGTH) {
|
|
846
|
+
return false;
|
|
847
|
+
}
|
|
904
848
|
if (/<[A-Z][a-zA-Z0-9]*(\s|>|\/)/.test(source)) {
|
|
905
849
|
return true;
|
|
906
850
|
}
|
|
@@ -925,6 +869,9 @@ function containsJsx(source) {
|
|
|
925
869
|
return false;
|
|
926
870
|
}
|
|
927
871
|
function containsMdxSyntax(source) {
|
|
872
|
+
if (source.length > MAX_TEMPLATE_LENGTH) {
|
|
873
|
+
return false;
|
|
874
|
+
}
|
|
928
875
|
if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
|
|
929
876
|
return true;
|
|
930
877
|
}
|
|
@@ -998,9 +945,11 @@ function detectTemplateType(template) {
|
|
|
998
945
|
reason: "Unknown template type, defaulting to HTML"
|
|
999
946
|
};
|
|
1000
947
|
}
|
|
948
|
+
var MAX_TEMPLATE_LENGTH;
|
|
1001
949
|
var init_detect = __esm({
|
|
1002
950
|
"libs/uipack/src/renderers/utils/detect.ts"() {
|
|
1003
951
|
"use strict";
|
|
952
|
+
MAX_TEMPLATE_LENGTH = 5e4;
|
|
1004
953
|
}
|
|
1005
954
|
});
|
|
1006
955
|
|
|
@@ -1221,7 +1170,7 @@ var init_helpers = __esm({
|
|
|
1221
1170
|
idCounter = 0;
|
|
1222
1171
|
builtinHelpers = {
|
|
1223
1172
|
// Escaping
|
|
1224
|
-
escapeHtml,
|
|
1173
|
+
escapeHtml: import_utils.escapeHtml,
|
|
1225
1174
|
// Formatting
|
|
1226
1175
|
formatDate,
|
|
1227
1176
|
formatCurrency,
|
|
@@ -1392,7 +1341,7 @@ __export(handlebars_exports, {
|
|
|
1392
1341
|
createHandlebarsRenderer: () => createHandlebarsRenderer,
|
|
1393
1342
|
defaultValue: () => defaultValue,
|
|
1394
1343
|
eq: () => eq,
|
|
1395
|
-
escapeHtml: () => escapeHtml,
|
|
1344
|
+
escapeHtml: () => import_utils.escapeHtml,
|
|
1396
1345
|
extractAll: () => extractAll,
|
|
1397
1346
|
extractExpressions: () => extractExpressions,
|
|
1398
1347
|
extractInputPaths: () => extractInputPaths,
|
|
@@ -2228,12 +2177,12 @@ var init_mdx_client_renderer = __esm({
|
|
|
2228
2177
|
...outputProps,
|
|
2229
2178
|
...props
|
|
2230
2179
|
};
|
|
2231
|
-
const escapedMdx = escapeScriptClose(JSON.stringify(template));
|
|
2232
|
-
const escapedProps = escapeScriptClose(JSON.stringify(spreadProps));
|
|
2233
|
-
const safeContainerId = escapeJsString(containerId);
|
|
2234
|
-
const loadingHtml = showLoading ? `<div class="mdx-loading">${escapeHtml(loadingMessage)}</div>` : "";
|
|
2180
|
+
const escapedMdx = (0, import_utils.escapeScriptClose)(JSON.stringify(template));
|
|
2181
|
+
const escapedProps = (0, import_utils.escapeScriptClose)(JSON.stringify(spreadProps));
|
|
2182
|
+
const safeContainerId = (0, import_utils.escapeJsString)(containerId);
|
|
2183
|
+
const loadingHtml = showLoading ? `<div class="mdx-loading">${(0, import_utils.escapeHtml)(loadingMessage)}</div>` : "";
|
|
2235
2184
|
return `
|
|
2236
|
-
<div id="${escapeHtml(containerId)}">${loadingHtml}</div>
|
|
2185
|
+
<div id="${(0, import_utils.escapeHtml)(containerId)}">${loadingHtml}</div>
|
|
2237
2186
|
<script type="module">
|
|
2238
2187
|
(async function() {
|
|
2239
2188
|
try {
|
|
@@ -2446,7 +2395,7 @@ function sha256Buffer(buffer) {
|
|
|
2446
2395
|
}
|
|
2447
2396
|
async function hashFile(filePath) {
|
|
2448
2397
|
try {
|
|
2449
|
-
const content = await (0,
|
|
2398
|
+
const content = await (0, import_utils8.readFileBuffer)(filePath);
|
|
2450
2399
|
return sha256Buffer(content);
|
|
2451
2400
|
} catch {
|
|
2452
2401
|
return void 0;
|
|
@@ -2497,7 +2446,7 @@ async function collectLocalDependencies(filePath, baseDir, collected, maxDepth,
|
|
|
2497
2446
|
if (!(0, import_fs.existsSync)(filePath)) return;
|
|
2498
2447
|
collected.add(filePath);
|
|
2499
2448
|
try {
|
|
2500
|
-
const content = await (0,
|
|
2449
|
+
const content = await (0, import_utils8.readFile)(filePath);
|
|
2501
2450
|
const imports = extractImportPaths(content);
|
|
2502
2451
|
for (const importPath of imports) {
|
|
2503
2452
|
if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
|
|
@@ -2566,14 +2515,14 @@ function generateBuildId() {
|
|
|
2566
2515
|
const random = Math.random().toString(36).substring(2, 10);
|
|
2567
2516
|
return `${timestamp}-${random}`;
|
|
2568
2517
|
}
|
|
2569
|
-
var import_crypto,
|
|
2518
|
+
var import_crypto, import_fs, import_path, import_utils8;
|
|
2570
2519
|
var init_hash_calculator = __esm({
|
|
2571
2520
|
"libs/uipack/src/bundler/file-cache/hash-calculator.ts"() {
|
|
2572
2521
|
"use strict";
|
|
2573
2522
|
import_crypto = require("crypto");
|
|
2574
|
-
import_promises = require("fs/promises");
|
|
2575
2523
|
import_fs = require("fs");
|
|
2576
2524
|
import_path = require("path");
|
|
2525
|
+
import_utils8 = require("@frontmcp/utils");
|
|
2577
2526
|
}
|
|
2578
2527
|
});
|
|
2579
2528
|
|
|
@@ -3420,13 +3369,16 @@ function generateUMDShim(dependencies, options = {}) {
|
|
|
3420
3369
|
console.warn('UMD shim failed:', e);
|
|
3421
3370
|
}
|
|
3422
3371
|
})();` : `window.__esm_shim = ${shimObject};`;
|
|
3423
|
-
|
|
3372
|
+
if (minify && code.length <= 1e5) {
|
|
3373
|
+
return code.replace(/\s+/g, " ").replace(/\s*([{},:])\s*/g, "$1");
|
|
3374
|
+
}
|
|
3375
|
+
return code;
|
|
3424
3376
|
}
|
|
3425
3377
|
function generateCDNScriptTags(dependencies) {
|
|
3426
3378
|
return dependencies.filter((dep) => !dep.esm).map((dep) => {
|
|
3427
|
-
const attrs = [`src="${escapeHtmlAttr(dep.cdnUrl)}"`];
|
|
3379
|
+
const attrs = [`src="${(0, import_utils.escapeHtmlAttr)(dep.cdnUrl)}"`];
|
|
3428
3380
|
if (dep.integrity) {
|
|
3429
|
-
attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
|
|
3381
|
+
attrs.push(`integrity="${(0, import_utils.escapeHtmlAttr)(dep.integrity)}"`);
|
|
3430
3382
|
}
|
|
3431
3383
|
attrs.push('crossorigin="anonymous"');
|
|
3432
3384
|
return `<script ${attrs.join(" ")}></script>`;
|
|
@@ -3434,9 +3386,9 @@ function generateCDNScriptTags(dependencies) {
|
|
|
3434
3386
|
}
|
|
3435
3387
|
function generateESMScriptTags(dependencies) {
|
|
3436
3388
|
return dependencies.filter((dep) => dep.esm).map((dep) => {
|
|
3437
|
-
const attrs = ['type="module"', `src="${escapeHtmlAttr(dep.cdnUrl)}"`];
|
|
3389
|
+
const attrs = ['type="module"', `src="${(0, import_utils.escapeHtmlAttr)(dep.cdnUrl)}"`];
|
|
3438
3390
|
if (dep.integrity) {
|
|
3439
|
-
attrs.push(`integrity="${escapeHtmlAttr(dep.integrity)}"`);
|
|
3391
|
+
attrs.push(`integrity="${(0, import_utils.escapeHtmlAttr)(dep.integrity)}"`);
|
|
3440
3392
|
}
|
|
3441
3393
|
attrs.push('crossorigin="anonymous"');
|
|
3442
3394
|
return `<script ${attrs.join(" ")}></script>`;
|
|
@@ -3722,14 +3674,14 @@ __export(filesystem_exports, {
|
|
|
3722
3674
|
function createFilesystemStorage(options) {
|
|
3723
3675
|
return new FilesystemStorage(options);
|
|
3724
3676
|
}
|
|
3725
|
-
var
|
|
3677
|
+
var import_path3, import_fs3, import_crypto3, import_utils16, CacheInitializationError, CacheOperationError, StorageNotInitializedError, DEFAULT_FS_OPTIONS, FilesystemStorage;
|
|
3726
3678
|
var init_filesystem = __esm({
|
|
3727
3679
|
"libs/uipack/src/bundler/file-cache/storage/filesystem.ts"() {
|
|
3728
3680
|
"use strict";
|
|
3729
|
-
import_promises2 = require("fs/promises");
|
|
3730
3681
|
import_path3 = require("path");
|
|
3731
3682
|
import_fs3 = require("fs");
|
|
3732
3683
|
import_crypto3 = require("crypto");
|
|
3684
|
+
import_utils16 = require("@frontmcp/utils");
|
|
3733
3685
|
init_interface();
|
|
3734
3686
|
CacheInitializationError = class extends Error {
|
|
3735
3687
|
cause;
|
|
@@ -3781,7 +3733,7 @@ var init_filesystem = __esm({
|
|
|
3781
3733
|
async initialize() {
|
|
3782
3734
|
if (this.initialized) return;
|
|
3783
3735
|
try {
|
|
3784
|
-
await (0,
|
|
3736
|
+
await (0, import_utils16.mkdir)(this.options.cacheDir, { recursive: true });
|
|
3785
3737
|
await this.loadStats();
|
|
3786
3738
|
this.initialized = true;
|
|
3787
3739
|
} catch (error) {
|
|
@@ -3800,7 +3752,7 @@ var init_filesystem = __esm({
|
|
|
3800
3752
|
this.updateHitRate();
|
|
3801
3753
|
return void 0;
|
|
3802
3754
|
}
|
|
3803
|
-
const content = await (0,
|
|
3755
|
+
const content = await (0, import_utils16.readFile)(filePath, "utf8");
|
|
3804
3756
|
const entry = JSON.parse(content);
|
|
3805
3757
|
if (Date.now() > entry.metadata.expiresAt) {
|
|
3806
3758
|
await this.delete(key);
|
|
@@ -3856,7 +3808,7 @@ var init_filesystem = __esm({
|
|
|
3856
3808
|
const filePath = this.getFilePath(key);
|
|
3857
3809
|
try {
|
|
3858
3810
|
if (!(0, import_fs3.existsSync)(filePath)) return false;
|
|
3859
|
-
const content = await (0,
|
|
3811
|
+
const content = await (0, import_utils16.readFile)(filePath, "utf8");
|
|
3860
3812
|
const entry = JSON.parse(content);
|
|
3861
3813
|
if (Date.now() > entry.metadata.expiresAt) {
|
|
3862
3814
|
await this.delete(key);
|
|
@@ -3875,9 +3827,9 @@ var init_filesystem = __esm({
|
|
|
3875
3827
|
const filePath = this.getFilePath(key);
|
|
3876
3828
|
try {
|
|
3877
3829
|
if (!(0, import_fs3.existsSync)(filePath)) return false;
|
|
3878
|
-
const content = await (0,
|
|
3830
|
+
const content = await (0, import_utils16.readFile)(filePath, "utf8");
|
|
3879
3831
|
const entry = JSON.parse(content);
|
|
3880
|
-
await (0,
|
|
3832
|
+
await (0, import_utils16.unlink)(filePath);
|
|
3881
3833
|
this.stats.entries = Math.max(0, this.stats.entries - 1);
|
|
3882
3834
|
this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
|
|
3883
3835
|
return true;
|
|
@@ -3891,8 +3843,8 @@ var init_filesystem = __esm({
|
|
|
3891
3843
|
async clear() {
|
|
3892
3844
|
this.ensureInitialized();
|
|
3893
3845
|
try {
|
|
3894
|
-
await (0,
|
|
3895
|
-
await (0,
|
|
3846
|
+
await (0, import_utils16.rm)(this.options.cacheDir, { recursive: true, force: true });
|
|
3847
|
+
await (0, import_utils16.mkdir)(this.options.cacheDir, { recursive: true });
|
|
3896
3848
|
this.stats = {
|
|
3897
3849
|
entries: 0,
|
|
3898
3850
|
totalSize: 0,
|
|
@@ -3917,21 +3869,21 @@ var init_filesystem = __esm({
|
|
|
3917
3869
|
this.ensureInitialized();
|
|
3918
3870
|
let removed = 0;
|
|
3919
3871
|
try {
|
|
3920
|
-
const files = await (0,
|
|
3872
|
+
const files = await (0, import_utils16.readdir)(this.options.cacheDir);
|
|
3921
3873
|
for (const file of files) {
|
|
3922
3874
|
if (!file.endsWith(this.options.extension)) continue;
|
|
3923
3875
|
const filePath = (0, import_path3.join)(this.options.cacheDir, file);
|
|
3924
3876
|
try {
|
|
3925
|
-
const content = await (0,
|
|
3877
|
+
const content = await (0, import_utils16.readFile)(filePath, "utf8");
|
|
3926
3878
|
const entry = JSON.parse(content);
|
|
3927
3879
|
if (Date.now() > entry.metadata.expiresAt) {
|
|
3928
|
-
await (0,
|
|
3880
|
+
await (0, import_utils16.unlink)(filePath);
|
|
3929
3881
|
this.stats.entries = Math.max(0, this.stats.entries - 1);
|
|
3930
3882
|
this.stats.totalSize = Math.max(0, this.stats.totalSize - entry.metadata.size);
|
|
3931
3883
|
removed++;
|
|
3932
3884
|
}
|
|
3933
3885
|
} catch {
|
|
3934
|
-
await (0,
|
|
3886
|
+
await (0, import_utils16.unlink)(filePath).catch(() => {
|
|
3935
3887
|
});
|
|
3936
3888
|
removed++;
|
|
3937
3889
|
}
|
|
@@ -3957,8 +3909,8 @@ var init_filesystem = __esm({
|
|
|
3957
3909
|
* Write a cache entry to disk.
|
|
3958
3910
|
*/
|
|
3959
3911
|
async writeEntry(filePath, entry) {
|
|
3960
|
-
await (0,
|
|
3961
|
-
await (0,
|
|
3912
|
+
await (0, import_utils16.mkdir)((0, import_path3.dirname)(filePath), { recursive: true });
|
|
3913
|
+
await (0, import_utils16.writeFile)(filePath, JSON.stringify(entry, null, 2));
|
|
3962
3914
|
}
|
|
3963
3915
|
/**
|
|
3964
3916
|
* Ensure the storage is initialized.
|
|
@@ -3974,14 +3926,14 @@ var init_filesystem = __esm({
|
|
|
3974
3926
|
*/
|
|
3975
3927
|
async loadStats() {
|
|
3976
3928
|
try {
|
|
3977
|
-
const files = await (0,
|
|
3929
|
+
const files = await (0, import_utils16.readdir)(this.options.cacheDir);
|
|
3978
3930
|
let entries = 0;
|
|
3979
3931
|
let totalSize = 0;
|
|
3980
3932
|
for (const file of files) {
|
|
3981
3933
|
if (!file.endsWith(this.options.extension)) continue;
|
|
3982
3934
|
const filePath = (0, import_path3.join)(this.options.cacheDir, file);
|
|
3983
3935
|
try {
|
|
3984
|
-
const content = await (0,
|
|
3936
|
+
const content = await (0, import_utils16.readFile)(filePath, "utf8");
|
|
3985
3937
|
const entry = JSON.parse(content);
|
|
3986
3938
|
entries++;
|
|
3987
3939
|
totalSize += entry.metadata.size;
|
|
@@ -4010,7 +3962,7 @@ var init_filesystem = __esm({
|
|
|
4010
3962
|
*/
|
|
4011
3963
|
async evictLRU() {
|
|
4012
3964
|
try {
|
|
4013
|
-
const files = await (0,
|
|
3965
|
+
const files = await (0, import_utils16.readdir)(this.options.cacheDir);
|
|
4014
3966
|
let oldestKey = null;
|
|
4015
3967
|
let oldestTime = Infinity;
|
|
4016
3968
|
let corruptedFile = null;
|
|
@@ -4018,7 +3970,7 @@ var init_filesystem = __esm({
|
|
|
4018
3970
|
if (!file.endsWith(this.options.extension)) continue;
|
|
4019
3971
|
const filePath = (0, import_path3.join)(this.options.cacheDir, file);
|
|
4020
3972
|
try {
|
|
4021
|
-
const content = await (0,
|
|
3973
|
+
const content = await (0, import_utils16.readFile)(filePath, "utf8");
|
|
4022
3974
|
const entry = JSON.parse(content);
|
|
4023
3975
|
if (entry.metadata.lastAccessedAt < oldestTime) {
|
|
4024
3976
|
oldestTime = entry.metadata.lastAccessedAt;
|
|
@@ -4030,7 +3982,7 @@ var init_filesystem = __esm({
|
|
|
4030
3982
|
}
|
|
4031
3983
|
if (corruptedFile) {
|
|
4032
3984
|
try {
|
|
4033
|
-
await (0,
|
|
3985
|
+
await (0, import_utils16.unlink)(corruptedFile);
|
|
4034
3986
|
this.stats.entries = Math.max(0, this.stats.entries - 1);
|
|
4035
3987
|
return true;
|
|
4036
3988
|
} catch {
|
|
@@ -4330,14 +4282,14 @@ async function createRedisBuilder(redisClient, keyPrefix = "frontmcp:ui:build:")
|
|
|
4330
4282
|
await storage.initialize();
|
|
4331
4283
|
return new ComponentBuilder(storage);
|
|
4332
4284
|
}
|
|
4333
|
-
var
|
|
4285
|
+
var import_fs4, import_path4, import_crypto4, import_utils17, ComponentBuilder;
|
|
4334
4286
|
var init_component_builder = __esm({
|
|
4335
4287
|
"libs/uipack/src/bundler/file-cache/component-builder.ts"() {
|
|
4336
4288
|
"use strict";
|
|
4337
|
-
import_promises3 = require("fs/promises");
|
|
4338
4289
|
import_fs4 = require("fs");
|
|
4339
4290
|
import_path4 = require("path");
|
|
4340
4291
|
import_crypto4 = require("crypto");
|
|
4292
|
+
import_utils17 = require("@frontmcp/utils");
|
|
4341
4293
|
init_hash_calculator();
|
|
4342
4294
|
init_resolver();
|
|
4343
4295
|
init_import_map();
|
|
@@ -4384,7 +4336,7 @@ var init_component_builder = __esm({
|
|
|
4384
4336
|
};
|
|
4385
4337
|
}
|
|
4386
4338
|
}
|
|
4387
|
-
const source = await (0,
|
|
4339
|
+
const source = await (0, import_utils17.readFile)(absoluteEntryPath, "utf8");
|
|
4388
4340
|
const resolver = new DependencyResolver({ platform });
|
|
4389
4341
|
const resolvedDeps = [];
|
|
4390
4342
|
for (const pkg of externals) {
|
|
@@ -4707,10 +4659,10 @@ __export(index_exports, {
|
|
|
4707
4659
|
detectTemplateMode: () => detectTemplateMode,
|
|
4708
4660
|
detectTemplateType: () => detectTemplateType,
|
|
4709
4661
|
errorDisplay: () => errorDisplay,
|
|
4710
|
-
escapeHtml: () => escapeHtml,
|
|
4711
|
-
escapeHtmlAttr: () => escapeHtmlAttr,
|
|
4712
|
-
escapeJsString: () => escapeJsString,
|
|
4713
|
-
escapeScriptClose: () => escapeScriptClose,
|
|
4662
|
+
escapeHtml: () => import_utils.escapeHtml,
|
|
4663
|
+
escapeHtmlAttr: () => import_utils.escapeHtmlAttr,
|
|
4664
|
+
escapeJsString: () => import_utils.escapeJsString,
|
|
4665
|
+
escapeScriptClose: () => import_utils.escapeScriptClose,
|
|
4714
4666
|
executeTemplate: () => executeTemplate,
|
|
4715
4667
|
executeTranspiledCode: () => executeTranspiledCode,
|
|
4716
4668
|
extractExternalPackages: () => extractExternalPackages,
|
|
@@ -4814,8 +4766,8 @@ __export(index_exports, {
|
|
|
4814
4766
|
rendererRegistry: () => rendererRegistry,
|
|
4815
4767
|
resolveDependencies: () => resolveDependencies,
|
|
4816
4768
|
resolveServingMode: () => resolveServingMode,
|
|
4817
|
-
safeJsonForScript: () => safeJsonForScript,
|
|
4818
|
-
safeStringify: () => safeStringify,
|
|
4769
|
+
safeJsonForScript: () => import_utils.safeJsonForScript,
|
|
4770
|
+
safeStringify: () => import_utils.safeStringify,
|
|
4819
4771
|
sanitizeCSPDomains: () => sanitizeCSPDomains,
|
|
4820
4772
|
sanitizeInput: () => sanitizeInput,
|
|
4821
4773
|
sha256: () => sha256,
|
|
@@ -4930,16 +4882,13 @@ function buildUIMeta(options) {
|
|
|
4930
4882
|
case "generic-mcp":
|
|
4931
4883
|
case "gemini":
|
|
4932
4884
|
default:
|
|
4933
|
-
meta["frontmcp/html"] = html;
|
|
4934
|
-
meta["frontmcp/mimeType"] = "text/html+mcp";
|
|
4935
|
-
if (rendererType) meta["frontmcp/type"] = rendererType;
|
|
4936
|
-
if (contentHash) meta["frontmcp/contentHash"] = contentHash;
|
|
4937
|
-
if (manifestUri) meta["frontmcp/manifestUri"] = manifestUri;
|
|
4938
|
-
if (token) meta["frontmcp/widgetToken"] = token;
|
|
4939
|
-
if (directUrl) meta["frontmcp/directUrl"] = directUrl;
|
|
4940
4885
|
meta["ui/html"] = html;
|
|
4941
4886
|
meta["ui/mimeType"] = "text/html+mcp";
|
|
4942
4887
|
if (rendererType) meta["ui/type"] = rendererType;
|
|
4888
|
+
if (contentHash) meta["ui/contentHash"] = contentHash;
|
|
4889
|
+
if (manifestUri) meta["ui/manifestUri"] = manifestUri;
|
|
4890
|
+
if (token) meta["ui/widgetToken"] = token;
|
|
4891
|
+
if (directUrl) meta["ui/directUrl"] = directUrl;
|
|
4943
4892
|
if (platformType === "claude") {
|
|
4944
4893
|
return buildClaudeMeta(meta, uiConfig);
|
|
4945
4894
|
} else if (platformType === "gemini") {
|
|
@@ -4998,34 +4947,37 @@ function buildIDEMeta(meta, uiConfig) {
|
|
|
4998
4947
|
}
|
|
4999
4948
|
return meta;
|
|
5000
4949
|
}
|
|
5001
|
-
function buildFrontMCPCSP(csp) {
|
|
5002
|
-
const result = {};
|
|
5003
|
-
if (csp.connectDomains?.length) {
|
|
5004
|
-
result.connectDomains = csp.connectDomains;
|
|
5005
|
-
}
|
|
5006
|
-
if (csp.resourceDomains?.length) {
|
|
5007
|
-
result.resourceDomains = csp.resourceDomains;
|
|
5008
|
-
}
|
|
5009
|
-
return result;
|
|
5010
|
-
}
|
|
5011
4950
|
function buildGenericMeta(meta, uiConfig) {
|
|
5012
|
-
if (uiConfig.widgetAccessible) {
|
|
5013
|
-
meta["frontmcp/widgetAccessible"] = true;
|
|
5014
|
-
}
|
|
5015
4951
|
if (uiConfig.csp) {
|
|
5016
|
-
|
|
4952
|
+
const csp = {};
|
|
4953
|
+
if (uiConfig.csp.connectDomains?.length) {
|
|
4954
|
+
csp.connectDomains = uiConfig.csp.connectDomains;
|
|
4955
|
+
}
|
|
4956
|
+
if (uiConfig.csp.resourceDomains?.length) {
|
|
4957
|
+
csp.resourceDomains = uiConfig.csp.resourceDomains;
|
|
4958
|
+
}
|
|
4959
|
+
if (Object.keys(csp).length > 0) {
|
|
4960
|
+
meta["ui/csp"] = csp;
|
|
4961
|
+
}
|
|
5017
4962
|
}
|
|
5018
4963
|
if (uiConfig.displayMode) {
|
|
5019
|
-
|
|
5020
|
-
|
|
5021
|
-
|
|
5022
|
-
|
|
4964
|
+
const displayModeMap = {
|
|
4965
|
+
inline: "inline",
|
|
4966
|
+
fullscreen: "fullscreen",
|
|
4967
|
+
pip: "pip",
|
|
4968
|
+
widget: "inline",
|
|
4969
|
+
panel: "fullscreen"
|
|
4970
|
+
};
|
|
4971
|
+
const mappedMode = displayModeMap[uiConfig.displayMode];
|
|
4972
|
+
if (mappedMode) {
|
|
4973
|
+
meta["ui/displayMode"] = mappedMode;
|
|
4974
|
+
}
|
|
5023
4975
|
}
|
|
5024
4976
|
if (uiConfig.prefersBorder !== void 0) {
|
|
5025
|
-
meta["
|
|
4977
|
+
meta["ui/prefersBorder"] = uiConfig.prefersBorder;
|
|
5026
4978
|
}
|
|
5027
4979
|
if (uiConfig.sandboxDomain) {
|
|
5028
|
-
meta["
|
|
4980
|
+
meta["ui/domain"] = uiConfig.sandboxDomain;
|
|
5029
4981
|
}
|
|
5030
4982
|
return meta;
|
|
5031
4983
|
}
|
|
@@ -5261,7 +5213,7 @@ function buildToolResponseContent(options) {
|
|
|
5261
5213
|
const { rawOutput, htmlContent, servingMode, useStructuredContent, platformType } = options;
|
|
5262
5214
|
if (servingMode === "static") {
|
|
5263
5215
|
return {
|
|
5264
|
-
content: [{ type: "text", text: safeStringify(rawOutput) }],
|
|
5216
|
+
content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
|
|
5265
5217
|
structuredContent: useStructuredContent ? rawOutput : void 0,
|
|
5266
5218
|
contentCleared: false,
|
|
5267
5219
|
format: "json-only"
|
|
@@ -5269,7 +5221,7 @@ function buildToolResponseContent(options) {
|
|
|
5269
5221
|
}
|
|
5270
5222
|
if (servingMode === "hybrid") {
|
|
5271
5223
|
return {
|
|
5272
|
-
content: [{ type: "text", text: safeStringify(rawOutput) }],
|
|
5224
|
+
content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
|
|
5273
5225
|
structuredContent: useStructuredContent ? rawOutput : void 0,
|
|
5274
5226
|
contentCleared: false,
|
|
5275
5227
|
format: "json-only"
|
|
@@ -5277,15 +5229,25 @@ function buildToolResponseContent(options) {
|
|
|
5277
5229
|
}
|
|
5278
5230
|
if (useStructuredContent) {
|
|
5279
5231
|
if (htmlContent) {
|
|
5280
|
-
|
|
5281
|
-
|
|
5282
|
-
|
|
5283
|
-
|
|
5284
|
-
|
|
5285
|
-
|
|
5232
|
+
const htmlInContent = platformType === "openai" || platformType === "ext-apps";
|
|
5233
|
+
if (htmlInContent) {
|
|
5234
|
+
return {
|
|
5235
|
+
content: [{ type: "text", text: htmlContent }],
|
|
5236
|
+
structuredContent: rawOutput,
|
|
5237
|
+
contentCleared: false,
|
|
5238
|
+
format: "structured-content"
|
|
5239
|
+
};
|
|
5240
|
+
} else {
|
|
5241
|
+
return {
|
|
5242
|
+
content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
|
|
5243
|
+
structuredContent: rawOutput,
|
|
5244
|
+
contentCleared: false,
|
|
5245
|
+
format: "structured-content"
|
|
5246
|
+
};
|
|
5247
|
+
}
|
|
5286
5248
|
}
|
|
5287
5249
|
return {
|
|
5288
|
-
content: [{ type: "text", text: safeStringify(rawOutput) }],
|
|
5250
|
+
content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput) }],
|
|
5289
5251
|
structuredContent: rawOutput,
|
|
5290
5252
|
contentCleared: false,
|
|
5291
5253
|
format: "json-only"
|
|
@@ -5306,7 +5268,7 @@ function buildToolResponseContent(options) {
|
|
|
5306
5268
|
type: "text",
|
|
5307
5269
|
text: `## Data
|
|
5308
5270
|
\`\`\`json
|
|
5309
|
-
${safeStringify(
|
|
5271
|
+
${(0, import_utils.safeStringify)(
|
|
5310
5272
|
rawOutput,
|
|
5311
5273
|
2
|
|
5312
5274
|
)}
|
|
@@ -5323,7 +5285,7 @@ ${htmlContent}
|
|
|
5323
5285
|
};
|
|
5324
5286
|
}
|
|
5325
5287
|
return {
|
|
5326
|
-
content: [{ type: "text", text: safeStringify(rawOutput, 2) }],
|
|
5288
|
+
content: [{ type: "text", text: (0, import_utils.safeStringify)(rawOutput, 2) }],
|
|
5327
5289
|
contentCleared: false,
|
|
5328
5290
|
format: "json-only"
|
|
5329
5291
|
};
|
|
@@ -6154,7 +6116,11 @@ FrontMcpBridge.prototype._setupDataToolCallHandler = function() {
|
|
|
6154
6116
|
};
|
|
6155
6117
|
`.trim();
|
|
6156
6118
|
}
|
|
6119
|
+
var MAX_MINIFY_CODE_LENGTH = 5e5;
|
|
6157
6120
|
function minifyJS(code) {
|
|
6121
|
+
if (code.length > MAX_MINIFY_CODE_LENGTH) {
|
|
6122
|
+
return code;
|
|
6123
|
+
}
|
|
6158
6124
|
return code.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "").replace(/\s+/g, " ").replace(/\s*([{};,:()[\]])\s*/g, "$1").replace(/;\}/g, "}").trim();
|
|
6159
6125
|
}
|
|
6160
6126
|
function generatePlatformBundle(platform, options = {}) {
|
|
@@ -6794,7 +6760,11 @@ function detectPIIType(value) {
|
|
|
6794
6760
|
if (isIPv4(value)) return "IP";
|
|
6795
6761
|
return null;
|
|
6796
6762
|
}
|
|
6763
|
+
var MAX_PII_TEXT_LENGTH = 1e5;
|
|
6797
6764
|
function redactPIIFromText(text) {
|
|
6765
|
+
if (text.length > MAX_PII_TEXT_LENGTH) {
|
|
6766
|
+
return text;
|
|
6767
|
+
}
|
|
6798
6768
|
let result = text;
|
|
6799
6769
|
result = result.replace(PII_PATTERNS.creditCardInText, REDACTION_TOKENS.CARD);
|
|
6800
6770
|
result = result.replace(PII_PATTERNS.ssnInText, REDACTION_TOKENS.ID);
|
|
@@ -6913,7 +6883,7 @@ function createTemplateHelpers() {
|
|
|
6913
6883
|
/**
|
|
6914
6884
|
* Escape HTML special characters to prevent XSS
|
|
6915
6885
|
*/
|
|
6916
|
-
escapeHtml,
|
|
6886
|
+
escapeHtml: import_utils.escapeHtml,
|
|
6917
6887
|
/**
|
|
6918
6888
|
* Format a date for display
|
|
6919
6889
|
*/
|
|
@@ -7017,7 +6987,7 @@ function wrapToolUI(options) {
|
|
|
7017
6987
|
widgetAccessible,
|
|
7018
6988
|
hostContext
|
|
7019
6989
|
});
|
|
7020
|
-
const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
|
|
6990
|
+
const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
|
|
7021
6991
|
return `<!DOCTYPE html>
|
|
7022
6992
|
<html lang="en">
|
|
7023
6993
|
<head>
|
|
@@ -7170,7 +7140,7 @@ function wrapToolUIUniversal(options) {
|
|
|
7170
7140
|
resourceMode
|
|
7171
7141
|
});
|
|
7172
7142
|
const bridgeScript = includeBridge ? BRIDGE_SCRIPT_TAGS.universal : "";
|
|
7173
|
-
const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
|
|
7143
|
+
const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
|
|
7174
7144
|
return `<!DOCTYPE html>
|
|
7175
7145
|
<html lang="en">
|
|
7176
7146
|
<head>
|
|
@@ -7284,7 +7254,7 @@ function wrapToolUIMinimal(options) {
|
|
|
7284
7254
|
window.__mcpWidgetAccessible = ${helpers.jsonEmbed(widgetAccessible)};
|
|
7285
7255
|
window.__mcpHostContext = ${helpers.jsonEmbed(contextData)};
|
|
7286
7256
|
</script>`;
|
|
7287
|
-
const pageTitle = title || `${escapeHtml(toolName)} - Tool Result`;
|
|
7257
|
+
const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Result`;
|
|
7288
7258
|
return `<!DOCTYPE html>
|
|
7289
7259
|
<html lang="en">
|
|
7290
7260
|
<head>
|
|
@@ -7434,7 +7404,7 @@ function wrapLeanWidgetShell(options) {
|
|
|
7434
7404
|
<head>
|
|
7435
7405
|
<meta charset="UTF-8">
|
|
7436
7406
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7437
|
-
<title>${escapeHtml(title || toolName)}</title>
|
|
7407
|
+
<title>${(0, import_utils.escapeHtml)(title || toolName)}</title>
|
|
7438
7408
|
${fontPreconnect}
|
|
7439
7409
|
${fontStylesheets}
|
|
7440
7410
|
${tailwindScript}
|
|
@@ -7835,7 +7805,7 @@ function wrapHybridWidgetShell(options) {
|
|
|
7835
7805
|
<head>
|
|
7836
7806
|
<meta charset="UTF-8">
|
|
7837
7807
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
7838
|
-
<title>${escapeHtml(title || toolName)}</title>
|
|
7808
|
+
<title>${(0, import_utils.escapeHtml)(title || toolName)}</title>
|
|
7839
7809
|
${fontPreconnect}
|
|
7840
7810
|
${fontStylesheets}
|
|
7841
7811
|
${tailwindScript}
|
|
@@ -8377,7 +8347,7 @@ function wrapStaticWidgetUniversal(options) {
|
|
|
8377
8347
|
}, 100);
|
|
8378
8348
|
}
|
|
8379
8349
|
</script>` : "";
|
|
8380
|
-
const pageTitle = title || `${escapeHtml(toolName)} - Tool Widget`;
|
|
8350
|
+
const pageTitle = title || `${(0, import_utils.escapeHtml)(toolName)} - Tool Widget`;
|
|
8381
8351
|
const loaderHtml = isReactBased && componentCode && !hasEmbeddedData ? `
|
|
8382
8352
|
<!-- Loading State -->
|
|
8383
8353
|
<div id="frontmcp-loader" style="display: flex; align-items: center; justify-content: center; padding: 2rem; gap: 0.5rem;">
|
|
@@ -8559,13 +8529,13 @@ function validationErrorBox(options) {
|
|
|
8559
8529
|
class="validation-error flex items-start gap-3 p-4 bg-red-50 border border-red-200 text-red-800 rounded-lg"
|
|
8560
8530
|
role="alert"
|
|
8561
8531
|
data-testid="validation-error"
|
|
8562
|
-
data-component="${escapeHtml(componentName)}"
|
|
8563
|
-
data-param="${escapeHtml(invalidParam)}"
|
|
8532
|
+
data-component="${(0, import_utils.escapeHtml)(componentName)}"
|
|
8533
|
+
data-param="${(0, import_utils.escapeHtml)(invalidParam)}"
|
|
8564
8534
|
>
|
|
8565
8535
|
${errorIcon}
|
|
8566
8536
|
<div class="min-w-0">
|
|
8567
|
-
<p class="font-semibold text-sm">${escapeHtml(componentName)}: Invalid Configuration</p>
|
|
8568
|
-
<p class="text-sm opacity-90 mt-0.5">The "${escapeHtml(invalidParam)}" parameter is invalid.</p>
|
|
8537
|
+
<p class="font-semibold text-sm">${(0, import_utils.escapeHtml)(componentName)}: Invalid Configuration</p>
|
|
8538
|
+
<p class="text-sm opacity-90 mt-0.5">The "${(0, import_utils.escapeHtml)(invalidParam)}" parameter is invalid.</p>
|
|
8569
8539
|
</div>
|
|
8570
8540
|
</div>`;
|
|
8571
8541
|
}
|
|
@@ -8779,7 +8749,7 @@ function describeZodType(schema) {
|
|
|
8779
8749
|
}
|
|
8780
8750
|
|
|
8781
8751
|
// libs/uipack/src/validation/template-validator.ts
|
|
8782
|
-
|
|
8752
|
+
init_handlebars();
|
|
8783
8753
|
function validateTemplate(template, outputSchema, options = {}) {
|
|
8784
8754
|
const { inputSchema, warnOnOptional = true, suggestSimilar = true, maxSuggestionDistance = 3 } = options;
|
|
8785
8755
|
const errors = [];
|
|
@@ -9145,7 +9115,7 @@ function safeInputToRecord(input) {
|
|
|
9145
9115
|
return {};
|
|
9146
9116
|
}
|
|
9147
9117
|
var defaultHelpers = {
|
|
9148
|
-
escapeHtml,
|
|
9118
|
+
escapeHtml: import_utils.escapeHtml,
|
|
9149
9119
|
formatDate: (date, format) => {
|
|
9150
9120
|
const d = date instanceof Date ? date : new Date(date);
|
|
9151
9121
|
if (format === "iso") return d.toISOString();
|
|
@@ -10002,7 +9972,7 @@ var BaseBuilder = class {
|
|
|
10002
9972
|
"<head>",
|
|
10003
9973
|
'<meta charset="UTF-8">',
|
|
10004
9974
|
'<meta name="viewport" content="width=device-width, initial-scale=1.0">',
|
|
10005
|
-
`<title>${escapeHtml(title)}</title>`
|
|
9975
|
+
`<title>${(0, import_utils.escapeHtml)(title)}</title>`
|
|
10006
9976
|
];
|
|
10007
9977
|
parts.push(buildFontPreconnect());
|
|
10008
9978
|
parts.push(buildFontStylesheets({ inter: true }));
|
|
@@ -10119,7 +10089,7 @@ ${body}
|
|
|
10119
10089
|
input,
|
|
10120
10090
|
output,
|
|
10121
10091
|
helpers: {
|
|
10122
|
-
escapeHtml,
|
|
10092
|
+
escapeHtml: import_utils.escapeHtml,
|
|
10123
10093
|
formatDate: (date, format) => {
|
|
10124
10094
|
const d = typeof date === "string" ? new Date(date) : date;
|
|
10125
10095
|
if (isNaN(d.getTime())) return String(date);
|
|
@@ -11213,11 +11183,11 @@ var OpenAIPreview = class {
|
|
|
11213
11183
|
const theme = mockData?.theme || "light";
|
|
11214
11184
|
const displayMode = mockData?.displayMode || "inline";
|
|
11215
11185
|
const toolResponses = mockData?.toolResponses || {};
|
|
11216
|
-
const safeTheme = safeJsonForScript(theme);
|
|
11217
|
-
const safeDisplayMode = safeJsonForScript(displayMode);
|
|
11218
|
-
const safeToolResponses = safeJsonForScript(toolResponses);
|
|
11219
|
-
const safeInput = safeJsonForScript(input);
|
|
11220
|
-
const safeOutput = safeJsonForScript(output);
|
|
11186
|
+
const safeTheme = (0, import_utils.safeJsonForScript)(theme);
|
|
11187
|
+
const safeDisplayMode = (0, import_utils.safeJsonForScript)(displayMode);
|
|
11188
|
+
const safeToolResponses = (0, import_utils.safeJsonForScript)(toolResponses);
|
|
11189
|
+
const safeInput = (0, import_utils.safeJsonForScript)(input);
|
|
11190
|
+
const safeOutput = (0, import_utils.safeJsonForScript)(output);
|
|
11221
11191
|
const mockScript = `
|
|
11222
11192
|
<script>
|
|
11223
11193
|
// Mock window.openai for builder mode
|
|
@@ -11258,8 +11228,8 @@ var OpenAIPreview = class {
|
|
|
11258
11228
|
*/
|
|
11259
11229
|
combineHybridForBuilder(result, input, output, mockData) {
|
|
11260
11230
|
let html = result.vendorShell;
|
|
11261
|
-
const safeInput = safeJsonForScript(input);
|
|
11262
|
-
const safeOutput = safeJsonForScript(output);
|
|
11231
|
+
const safeInput = (0, import_utils.safeJsonForScript)(input);
|
|
11232
|
+
const safeOutput = (0, import_utils.safeJsonForScript)(output);
|
|
11263
11233
|
html = html.replace(DATA_PLACEHOLDERS.input, `window.__mcpToolInput = ${safeInput};`).replace(DATA_PLACEHOLDERS.output, `window.__mcpToolOutput = ${safeOutput};`).replace(DATA_PLACEHOLDERS.structuredContent, `window.__mcpStructuredContent = ${safeOutput};`);
|
|
11264
11234
|
const componentScript = `
|
|
11265
11235
|
<script type="module">
|
|
@@ -11334,8 +11304,8 @@ var ClaudePreview = class {
|
|
|
11334
11304
|
}
|
|
11335
11305
|
forExecutionHybrid(result, input, output) {
|
|
11336
11306
|
let html = result.vendorShell;
|
|
11337
|
-
const safeInput = safeJsonForScript(input);
|
|
11338
|
-
const safeOutput = safeJsonForScript(output);
|
|
11307
|
+
const safeInput = (0, import_utils.safeJsonForScript)(input);
|
|
11308
|
+
const safeOutput = (0, import_utils.safeJsonForScript)(output);
|
|
11339
11309
|
html = html.replace(DATA_PLACEHOLDERS2.input, `window.__mcpToolInput = ${safeInput};`).replace(DATA_PLACEHOLDERS2.output, `window.__mcpToolOutput = ${safeOutput};`).replace(DATA_PLACEHOLDERS2.structuredContent, `window.__mcpStructuredContent = ${safeOutput};`);
|
|
11340
11310
|
const componentScript = `
|
|
11341
11311
|
<script type="module">
|
|
@@ -11396,9 +11366,9 @@ var ClaudePreview = class {
|
|
|
11396
11366
|
* to prevent XSS attacks from malicious data.
|
|
11397
11367
|
*/
|
|
11398
11368
|
buildClaudeInlineHtml(input, output) {
|
|
11399
|
-
const safeInput = safeJsonForScript(input);
|
|
11400
|
-
const safeOutput = safeJsonForScript(output);
|
|
11401
|
-
const escapedOutputDisplay = escapeHtml(JSON.stringify(output, null, 2));
|
|
11369
|
+
const safeInput = (0, import_utils.safeJsonForScript)(input);
|
|
11370
|
+
const safeOutput = (0, import_utils.safeJsonForScript)(output);
|
|
11371
|
+
const escapedOutputDisplay = (0, import_utils.escapeHtml)(JSON.stringify(output, null, 2));
|
|
11402
11372
|
return `<!DOCTYPE html>
|
|
11403
11373
|
<html lang="en">
|
|
11404
11374
|
<head>
|
|
@@ -11475,13 +11445,12 @@ var GenericPreview = class {
|
|
|
11475
11445
|
forDiscoveryStatic(result, toolName, _description) {
|
|
11476
11446
|
const resourceUri = `resource://widget/${toolName}`;
|
|
11477
11447
|
const _meta = {
|
|
11478
|
-
//
|
|
11479
|
-
"
|
|
11480
|
-
"
|
|
11481
|
-
|
|
11482
|
-
|
|
11448
|
+
// Use ui/* namespace for generic MCP clients
|
|
11449
|
+
"ui/resourceUri": resourceUri,
|
|
11450
|
+
"ui/widgetCSP": {
|
|
11451
|
+
connectDomains: ["esm.sh", "cdn.tailwindcss.com"],
|
|
11452
|
+
resourceDomains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
|
|
11483
11453
|
},
|
|
11484
|
-
// Fallback for compatibility
|
|
11485
11454
|
"ui/mimeType": "text/html+mcp"
|
|
11486
11455
|
};
|
|
11487
11456
|
return {
|
|
@@ -11492,10 +11461,11 @@ var GenericPreview = class {
|
|
|
11492
11461
|
}
|
|
11493
11462
|
forDiscoveryHybrid(result, _toolName, _description) {
|
|
11494
11463
|
const _meta = {
|
|
11495
|
-
|
|
11496
|
-
"
|
|
11497
|
-
|
|
11498
|
-
|
|
11464
|
+
// Use ui/* namespace for generic MCP clients
|
|
11465
|
+
"ui/resourceUri": result.shellResourceUri,
|
|
11466
|
+
"ui/widgetCSP": {
|
|
11467
|
+
connectDomains: ["esm.sh", "cdn.tailwindcss.com"],
|
|
11468
|
+
resourceDomains: ["esm.sh", "cdn.tailwindcss.com", "fonts.googleapis.com", "fonts.gstatic.com"]
|
|
11499
11469
|
},
|
|
11500
11470
|
"ui/mimeType": "text/html+mcp"
|
|
11501
11471
|
};
|
|
@@ -11507,7 +11477,7 @@ var GenericPreview = class {
|
|
|
11507
11477
|
}
|
|
11508
11478
|
forDiscoveryInline(result, _toolName, _description) {
|
|
11509
11479
|
const _meta = {
|
|
11510
|
-
|
|
11480
|
+
// Use ui/* namespace for generic MCP clients
|
|
11511
11481
|
"ui/html": result.loaderShell,
|
|
11512
11482
|
"ui/mimeType": "text/html+mcp"
|
|
11513
11483
|
};
|
|
@@ -11523,7 +11493,6 @@ var GenericPreview = class {
|
|
|
11523
11493
|
const html = this.injectBuilderMode(result.html, input, output, mockData);
|
|
11524
11494
|
return {
|
|
11525
11495
|
_meta: {
|
|
11526
|
-
"frontmcp/html": html,
|
|
11527
11496
|
"ui/html": html
|
|
11528
11497
|
},
|
|
11529
11498
|
html,
|
|
@@ -11539,13 +11508,12 @@ var GenericPreview = class {
|
|
|
11539
11508
|
}
|
|
11540
11509
|
forExecutionHybrid(result, input, output, builderMode, mockData) {
|
|
11541
11510
|
const _meta = {
|
|
11542
|
-
"
|
|
11511
|
+
"ui/component": result.componentChunk
|
|
11543
11512
|
};
|
|
11544
11513
|
if (builderMode) {
|
|
11545
11514
|
const html = this.combineHybridForBuilder(result, input, output, mockData);
|
|
11546
11515
|
return {
|
|
11547
11516
|
_meta: {
|
|
11548
|
-
"frontmcp/html": html,
|
|
11549
11517
|
"ui/html": html
|
|
11550
11518
|
},
|
|
11551
11519
|
html,
|
|
@@ -11561,7 +11529,6 @@ var GenericPreview = class {
|
|
|
11561
11529
|
}
|
|
11562
11530
|
forExecutionInline(result, input, output, _builderMode, _mockData) {
|
|
11563
11531
|
const _meta = {
|
|
11564
|
-
"frontmcp/html": "<!-- Full widget will be generated -->",
|
|
11565
11532
|
"ui/html": "<!-- Full widget will be generated -->"
|
|
11566
11533
|
};
|
|
11567
11534
|
return {
|
|
@@ -11583,11 +11550,11 @@ var GenericPreview = class {
|
|
|
11583
11550
|
const theme = mockData?.theme || "light";
|
|
11584
11551
|
const displayMode = mockData?.displayMode || "inline";
|
|
11585
11552
|
const toolResponses = mockData?.toolResponses || {};
|
|
11586
|
-
const safeTheme = safeJsonForScript(theme);
|
|
11587
|
-
const safeDisplayMode = safeJsonForScript(displayMode);
|
|
11588
|
-
const safeToolResponses = safeJsonForScript(toolResponses);
|
|
11589
|
-
const safeInput = safeJsonForScript(input);
|
|
11590
|
-
const safeOutput = safeJsonForScript(output);
|
|
11553
|
+
const safeTheme = (0, import_utils.safeJsonForScript)(theme);
|
|
11554
|
+
const safeDisplayMode = (0, import_utils.safeJsonForScript)(displayMode);
|
|
11555
|
+
const safeToolResponses = (0, import_utils.safeJsonForScript)(toolResponses);
|
|
11556
|
+
const safeInput = (0, import_utils.safeJsonForScript)(input);
|
|
11557
|
+
const safeOutput = (0, import_utils.safeJsonForScript)(output);
|
|
11591
11558
|
const mockScript = `
|
|
11592
11559
|
<script>
|
|
11593
11560
|
// Mock FrontMCP bridge for builder mode
|
|
@@ -11620,8 +11587,8 @@ var GenericPreview = class {
|
|
|
11620
11587
|
*/
|
|
11621
11588
|
combineHybridForBuilder(result, input, output, mockData) {
|
|
11622
11589
|
let html = result.vendorShell;
|
|
11623
|
-
const safeInput = safeJsonForScript(input);
|
|
11624
|
-
const safeOutput = safeJsonForScript(output);
|
|
11590
|
+
const safeInput = (0, import_utils.safeJsonForScript)(input);
|
|
11591
|
+
const safeOutput = (0, import_utils.safeJsonForScript)(output);
|
|
11625
11592
|
html = html.replace(DATA_PLACEHOLDERS3.input, `window.__mcpToolInput = ${safeInput};`).replace(DATA_PLACEHOLDERS3.output, `window.__mcpToolOutput = ${safeOutput};`).replace(DATA_PLACEHOLDERS3.structuredContent, `window.__mcpStructuredContent = ${safeOutput};`);
|
|
11626
11593
|
const componentScript = `
|
|
11627
11594
|
<script type="module">
|
|
@@ -11727,16 +11694,16 @@ function heading(text, level = 2) {
|
|
|
11727
11694
|
3: "text-lg font-medium text-text-primary mb-2",
|
|
11728
11695
|
4: "text-base font-medium text-text-secondary mb-2"
|
|
11729
11696
|
}[level] || "";
|
|
11730
|
-
return `<${tag} class="${classes}">${escapeHtml(text)}</${tag}>`;
|
|
11697
|
+
return `<${tag} class="${classes}">${(0, import_utils.escapeHtml)(text)}</${tag}>`;
|
|
11731
11698
|
}
|
|
11732
11699
|
function paragraph(text, className = "") {
|
|
11733
|
-
return `<p class="text-text-secondary ${className}">${escapeHtml(text)}</p>`;
|
|
11700
|
+
return `<p class="text-text-secondary ${className}">${(0, import_utils.escapeHtml)(text)}</p>`;
|
|
11734
11701
|
}
|
|
11735
11702
|
function keyValue(key, value, className = "") {
|
|
11736
11703
|
const displayValue = typeof value === "boolean" ? value ? "Yes" : "No" : String(value);
|
|
11737
11704
|
return `<div class="flex justify-between items-center py-2 border-b border-border ${className}">
|
|
11738
|
-
<span class="text-text-secondary">${escapeHtml(key)}</span>
|
|
11739
|
-
<span class="text-text-primary font-medium">${escapeHtml(displayValue)}</span>
|
|
11705
|
+
<span class="text-text-secondary">${(0, import_utils.escapeHtml)(key)}</span>
|
|
11706
|
+
<span class="text-text-primary font-medium">${(0, import_utils.escapeHtml)(displayValue)}</span>
|
|
11740
11707
|
</div>`;
|
|
11741
11708
|
}
|
|
11742
11709
|
function dataList(items) {
|
|
@@ -11749,9 +11716,9 @@ function errorDisplay(message, details) {
|
|
|
11749
11716
|
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
|
11750
11717
|
<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"/>
|
|
11751
11718
|
</svg>
|
|
11752
|
-
<span class="font-medium">${escapeHtml(message)}</span>
|
|
11719
|
+
<span class="font-medium">${(0, import_utils.escapeHtml)(message)}</span>
|
|
11753
11720
|
</div>
|
|
11754
|
-
${details ? `<p class="mt-2 text-sm text-text-secondary">${escapeHtml(details)}</p>` : ""}
|
|
11721
|
+
${details ? `<p class="mt-2 text-sm text-text-secondary">${(0, import_utils.escapeHtml)(details)}</p>` : ""}
|
|
11755
11722
|
</div>`;
|
|
11756
11723
|
}
|
|
11757
11724
|
function successDisplay(message, details) {
|
|
@@ -11760,9 +11727,9 @@ function successDisplay(message, details) {
|
|
|
11760
11727
|
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
|
11761
11728
|
<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"/>
|
|
11762
11729
|
</svg>
|
|
11763
|
-
<span class="font-medium">${escapeHtml(message)}</span>
|
|
11730
|
+
<span class="font-medium">${(0, import_utils.escapeHtml)(message)}</span>
|
|
11764
11731
|
</div>
|
|
11765
|
-
${details ? `<p class="mt-2 text-sm text-text-secondary">${escapeHtml(details)}</p>` : ""}
|
|
11732
|
+
${details ? `<p class="mt-2 text-sm text-text-secondary">${(0, import_utils.escapeHtml)(details)}</p>` : ""}
|
|
11766
11733
|
</div>`;
|
|
11767
11734
|
}
|
|
11768
11735
|
function loadingDisplay(message = "Loading...") {
|
|
@@ -11772,7 +11739,7 @@ function loadingDisplay(message = "Loading...") {
|
|
|
11772
11739
|
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
|
|
11773
11740
|
<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>
|
|
11774
11741
|
</svg>
|
|
11775
|
-
<span>${escapeHtml(message)}</span>
|
|
11742
|
+
<span>${(0, import_utils.escapeHtml)(message)}</span>
|
|
11776
11743
|
</div>
|
|
11777
11744
|
</div>`;
|
|
11778
11745
|
}
|
|
@@ -12746,7 +12713,11 @@ init_renderers();
|
|
|
12746
12713
|
var import_crypto2 = require("crypto");
|
|
12747
12714
|
|
|
12748
12715
|
// libs/uipack/src/registry/render-template.ts
|
|
12716
|
+
var MAX_MDX_SOURCE_LENGTH = 1e5;
|
|
12749
12717
|
function containsMdxSyntax2(source) {
|
|
12718
|
+
if (source.length > MAX_MDX_SOURCE_LENGTH) {
|
|
12719
|
+
return false;
|
|
12720
|
+
}
|
|
12750
12721
|
if (/<[A-Z][a-zA-Z0-9]*/.test(source)) {
|
|
12751
12722
|
return true;
|
|
12752
12723
|
}
|
|
@@ -13589,7 +13560,11 @@ function getSubpathFromSpecifier(specifier) {
|
|
|
13589
13560
|
}
|
|
13590
13561
|
return void 0;
|
|
13591
13562
|
}
|
|
13563
|
+
var MAX_IMPORT_STATEMENT_LENGTH = 2e3;
|
|
13592
13564
|
function parseImportStatement(statement) {
|
|
13565
|
+
if (statement.length > MAX_IMPORT_STATEMENT_LENGTH) {
|
|
13566
|
+
return null;
|
|
13567
|
+
}
|
|
13593
13568
|
const namedMatch = /import\s+(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)\s+from\s+['"]([^'"]+)['"]/.exec(statement);
|
|
13594
13569
|
if (namedMatch) {
|
|
13595
13570
|
return namedMatch[1];
|