@frontmcp/uipack 1.8.0 → 1.8.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/README.md +12 -11
- package/adapters/content-detector.d.ts.map +1 -1
- package/adapters/index.js +92 -42
- package/adapters/template-renderer.d.ts +11 -1
- package/adapters/template-renderer.d.ts.map +1 -1
- package/component/index.js +13 -10
- package/esm/adapters/index.mjs +92 -42
- package/esm/component/index.mjs +13 -10
- package/esm/index.mjs +96 -40
- package/esm/package.json +2 -2
- package/esm/shell/index.mjs +54 -25
- package/esm/utils/index.mjs +5 -1
- package/index.d.ts +1 -1
- package/index.d.ts.map +1 -1
- package/index.js +99 -40
- package/package.json +2 -2
- package/shell/custom-shell-applier.d.ts +7 -6
- package/shell/custom-shell-applier.d.ts.map +1 -1
- package/shell/data-injector.d.ts +5 -0
- package/shell/data-injector.d.ts.map +1 -1
- package/shell/index.d.ts +1 -0
- package/shell/index.d.ts.map +1 -1
- package/shell/index.js +57 -25
- package/shell/trusted-html.d.ts +40 -0
- package/shell/trusted-html.d.ts.map +1 -0
- package/types/ui-config.d.ts +30 -2
- package/types/ui-config.d.ts.map +1 -1
- package/utils/index.d.ts +7 -0
- package/utils/index.d.ts.map +1 -1
- package/utils/index.js +5 -1
package/shell/index.js
CHANGED
|
@@ -37,11 +37,14 @@ __export(shell_exports, {
|
|
|
37
37
|
clearShellTemplateCache: () => clearShellTemplateCache,
|
|
38
38
|
createTemplateHelpers: () => createTemplateHelpers,
|
|
39
39
|
hasSizing: () => hasSizing,
|
|
40
|
+
html: () => html,
|
|
40
41
|
isInlineShellSource: () => isInlineShellSource,
|
|
41
42
|
isNpmShellSource: () => isNpmShellSource,
|
|
43
|
+
isTrustedHtml: () => isTrustedHtml,
|
|
42
44
|
isUrlShellSource: () => isUrlShellSource,
|
|
43
45
|
resolveShellTemplate: () => resolveShellTemplate,
|
|
44
46
|
sanitizeCSPDomains: () => sanitizeCSPDomains,
|
|
47
|
+
trustedHtml: () => trustedHtml,
|
|
45
48
|
validateCSPDomain: () => validateCSPDomain,
|
|
46
49
|
validateShellTemplate: () => validateShellTemplate
|
|
47
50
|
});
|
|
@@ -1332,14 +1335,16 @@ function isNpmShellSource(source) {
|
|
|
1332
1335
|
}
|
|
1333
1336
|
|
|
1334
1337
|
// libs/uipack/src/shell/custom-shell-applier.ts
|
|
1338
|
+
var PLACEHOLDER_PATTERN = new RegExp(`\\{\\{(${SHELL_PLACEHOLDER_NAMES.join("|")})\\}\\}`, "g");
|
|
1339
|
+
var VALUE_KEYS = {
|
|
1340
|
+
CSP: "csp",
|
|
1341
|
+
DATA: "data",
|
|
1342
|
+
BRIDGE: "bridge",
|
|
1343
|
+
CONTENT: "content",
|
|
1344
|
+
TITLE: "title"
|
|
1345
|
+
};
|
|
1335
1346
|
function applyShellTemplate(template, values) {
|
|
1336
|
-
|
|
1337
|
-
result = result.replaceAll(SHELL_PLACEHOLDERS.CSP, values.csp);
|
|
1338
|
-
result = result.replaceAll(SHELL_PLACEHOLDERS.DATA, values.data);
|
|
1339
|
-
result = result.replaceAll(SHELL_PLACEHOLDERS.BRIDGE, values.bridge);
|
|
1340
|
-
result = result.replaceAll(SHELL_PLACEHOLDERS.CONTENT, values.content);
|
|
1341
|
-
result = result.replaceAll(SHELL_PLACEHOLDERS.TITLE, values.title);
|
|
1342
|
-
return result;
|
|
1347
|
+
return template.replace(PLACEHOLDER_PATTERN, (_token, name) => values[VALUE_KEYS[name]]);
|
|
1343
1348
|
}
|
|
1344
1349
|
|
|
1345
1350
|
// libs/uipack/src/shell/custom-shell-validator.ts
|
|
@@ -1366,8 +1371,9 @@ function escapeHtml(str) {
|
|
|
1366
1371
|
const s = String(str);
|
|
1367
1372
|
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
1368
1373
|
}
|
|
1369
|
-
|
|
1370
|
-
|
|
1374
|
+
var SCRIPT_UNSAFE_CHARACTERS = /[<>&\u2028\u2029]/g;
|
|
1375
|
+
function toUnicodeEscape(character) {
|
|
1376
|
+
return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
|
1371
1377
|
}
|
|
1372
1378
|
function safeJsonForScript(value) {
|
|
1373
1379
|
if (value === void 0) {
|
|
@@ -1383,12 +1389,35 @@ function safeJsonForScript(value) {
|
|
|
1383
1389
|
if (jsonString === void 0) {
|
|
1384
1390
|
return "null";
|
|
1385
1391
|
}
|
|
1386
|
-
return
|
|
1392
|
+
return jsonString.replace(SCRIPT_UNSAFE_CHARACTERS, toUnicodeEscape);
|
|
1387
1393
|
} catch {
|
|
1388
1394
|
return '{"error":"Value could not be serialized"}';
|
|
1389
1395
|
}
|
|
1390
1396
|
}
|
|
1391
1397
|
|
|
1398
|
+
// libs/uipack/src/shell/trusted-html.ts
|
|
1399
|
+
var TRUSTED_HTML = /* @__PURE__ */ Symbol.for("@frontmcp/uipack/trusted-html");
|
|
1400
|
+
function trustedHtml(markup) {
|
|
1401
|
+
const value = String(markup);
|
|
1402
|
+
return Object.freeze({ [TRUSTED_HTML]: value, toString: () => value });
|
|
1403
|
+
}
|
|
1404
|
+
function isTrustedHtml(value) {
|
|
1405
|
+
return typeof value === "object" && value !== null && typeof value[TRUSTED_HTML] === "string";
|
|
1406
|
+
}
|
|
1407
|
+
function interpolate(value) {
|
|
1408
|
+
if (isTrustedHtml(value)) return value[TRUSTED_HTML];
|
|
1409
|
+
if (Array.isArray(value)) return value.map(interpolate).join("");
|
|
1410
|
+
if (value === false) return "";
|
|
1411
|
+
return escapeHtml(value);
|
|
1412
|
+
}
|
|
1413
|
+
function html(strings, ...values) {
|
|
1414
|
+
let markup = strings[0];
|
|
1415
|
+
for (let index = 0; index < values.length; index++) {
|
|
1416
|
+
markup += interpolate(values[index]) + strings[index + 1];
|
|
1417
|
+
}
|
|
1418
|
+
return trustedHtml(markup);
|
|
1419
|
+
}
|
|
1420
|
+
|
|
1392
1421
|
// libs/uipack/src/shell/data-injector.ts
|
|
1393
1422
|
function hasSizing(sizing) {
|
|
1394
1423
|
if (!sizing) return false;
|
|
@@ -1442,9 +1471,9 @@ function createTemplateHelpers() {
|
|
|
1442
1471
|
uniqueId: (prefix = "mcp") => {
|
|
1443
1472
|
return `${prefix}-${++_uniqueIdCounter}`;
|
|
1444
1473
|
},
|
|
1445
|
-
jsonEmbed: (data) =>
|
|
1446
|
-
|
|
1447
|
-
|
|
1474
|
+
jsonEmbed: (data) => safeJsonForScript(data),
|
|
1475
|
+
html,
|
|
1476
|
+
trustedHtml
|
|
1448
1477
|
};
|
|
1449
1478
|
}
|
|
1450
1479
|
|
|
@@ -1522,12 +1551,12 @@ function buildShell(content, config) {
|
|
|
1522
1551
|
sizing
|
|
1523
1552
|
});
|
|
1524
1553
|
if (!withShell) {
|
|
1525
|
-
const
|
|
1554
|
+
const html3 = `${dataScript}
|
|
1526
1555
|
${content}`;
|
|
1527
1556
|
return {
|
|
1528
|
-
html:
|
|
1529
|
-
hash: simpleHash(
|
|
1530
|
-
size: Buffer.byteLength(
|
|
1557
|
+
html: html3,
|
|
1558
|
+
hash: simpleHash(html3),
|
|
1559
|
+
size: Buffer.byteLength(html3, "utf-8")
|
|
1531
1560
|
};
|
|
1532
1561
|
}
|
|
1533
1562
|
if (customShell) {
|
|
@@ -1560,7 +1589,7 @@ ${content}`;
|
|
|
1560
1589
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
1561
1590
|
headParts.push(`<script>${bridgeScript}</script>`);
|
|
1562
1591
|
}
|
|
1563
|
-
const
|
|
1592
|
+
const html2 = `<!DOCTYPE html>
|
|
1564
1593
|
<html lang="en">
|
|
1565
1594
|
<head>
|
|
1566
1595
|
${headParts.map((p) => ` ${p}`).join("\n")}
|
|
@@ -1570,9 +1599,9 @@ ${content}
|
|
|
1570
1599
|
</body>
|
|
1571
1600
|
</html>`;
|
|
1572
1601
|
return {
|
|
1573
|
-
html,
|
|
1574
|
-
hash: simpleHash(
|
|
1575
|
-
size: Buffer.byteLength(
|
|
1602
|
+
html: html2,
|
|
1603
|
+
hash: simpleHash(html2),
|
|
1604
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
1576
1605
|
};
|
|
1577
1606
|
}
|
|
1578
1607
|
function buildCustomShell(content, customShell, ctx) {
|
|
@@ -1605,7 +1634,7 @@ ${sizingStyle}` : dataScript;
|
|
|
1605
1634
|
const bridgeScript = generateBridgeIIFE({ minify: true });
|
|
1606
1635
|
bridgeHtml = `<script>${bridgeScript}</script>`;
|
|
1607
1636
|
}
|
|
1608
|
-
const
|
|
1637
|
+
const html2 = applyShellTemplate(template, {
|
|
1609
1638
|
csp: cspTag,
|
|
1610
1639
|
data: dataWithSizing,
|
|
1611
1640
|
bridge: bridgeHtml,
|
|
@@ -1613,9 +1642,9 @@ ${sizingStyle}` : dataScript;
|
|
|
1613
1642
|
title: ctx.title ? escapeHtmlForTag(ctx.title) : ""
|
|
1614
1643
|
});
|
|
1615
1644
|
return {
|
|
1616
|
-
html,
|
|
1617
|
-
hash: simpleHash(
|
|
1618
|
-
size: Buffer.byteLength(
|
|
1645
|
+
html: html2,
|
|
1646
|
+
hash: simpleHash(html2),
|
|
1647
|
+
size: Buffer.byteLength(html2, "utf-8")
|
|
1619
1648
|
};
|
|
1620
1649
|
}
|
|
1621
1650
|
function simpleHash(str) {
|
|
@@ -1757,11 +1786,14 @@ function escapeRegExp(str) {
|
|
|
1757
1786
|
clearShellTemplateCache,
|
|
1758
1787
|
createTemplateHelpers,
|
|
1759
1788
|
hasSizing,
|
|
1789
|
+
html,
|
|
1760
1790
|
isInlineShellSource,
|
|
1761
1791
|
isNpmShellSource,
|
|
1792
|
+
isTrustedHtml,
|
|
1762
1793
|
isUrlShellSource,
|
|
1763
1794
|
resolveShellTemplate,
|
|
1764
1795
|
sanitizeCSPDomains,
|
|
1796
|
+
trustedHtml,
|
|
1765
1797
|
validateCSPDomain,
|
|
1766
1798
|
validateShellTemplate
|
|
1767
1799
|
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trusted Markup
|
|
3
|
+
*
|
|
4
|
+
* Explicit markup values for UI template functions. A template result built with {@link html}
|
|
5
|
+
* or wrapped with {@link trustedHtml} is rendered as HTML; with `escapeStringResults` on, a plain
|
|
6
|
+
* string result is escaped instead.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
declare const TRUSTED_HTML: unique symbol;
|
|
11
|
+
/**
|
|
12
|
+
* Markup a template author vouches for. It renders as HTML and is never escaped again.
|
|
13
|
+
* Create it with {@link html} or {@link trustedHtml}; `String(value)` returns the markup.
|
|
14
|
+
*/
|
|
15
|
+
export interface TrustedHtml {
|
|
16
|
+
readonly [TRUSTED_HTML]: string;
|
|
17
|
+
toString(): string;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Mark already-safe markup as trusted. Only pass markup you produced or sanitized yourself —
|
|
21
|
+
* never raw tool output or user input.
|
|
22
|
+
*/
|
|
23
|
+
export declare function trustedHtml(markup: string): TrustedHtml;
|
|
24
|
+
/** Whether a value was created by {@link html} or {@link trustedHtml}. */
|
|
25
|
+
export declare function isTrustedHtml(value: unknown): value is TrustedHtml;
|
|
26
|
+
/**
|
|
27
|
+
* Tagged template that builds {@link TrustedHtml}.
|
|
28
|
+
*
|
|
29
|
+
* The literal parts are kept as markup. Each interpolated value is HTML-escaped unless it is
|
|
30
|
+
* itself `TrustedHtml`; arrays are joined without a separator and `null`, `undefined` and `false`
|
|
31
|
+
* render nothing. Always quote attribute values.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* html`<ul>${items.map((item) => html`<li>${item.name}</li>`)}</ul>`
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export declare function html(strings: TemplateStringsArray, ...values: unknown[]): TrustedHtml;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=trusted-html.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trusted-html.d.ts","sourceRoot":"","sources":["../../src/shell/trusted-html.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,QAAA,MAAM,YAAY,EAAE,OAAO,MAAoD,CAAC;AAEhF;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAChC,QAAQ,IAAI,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,CAGvD;AAED,0EAA0E;AAC1E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,WAAW,CAMlE;AASD;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,WAAW,CAMrF"}
|
package/types/ui-config.d.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
import type { FileSource } from '../component/types';
|
|
11
11
|
import type { CDNDependency } from '../resolver/types';
|
|
12
12
|
import type { CustomShellSource } from '../shell/custom-shell-types';
|
|
13
|
+
import type { TrustedHtml } from '../shell/trusted-html';
|
|
13
14
|
/**
|
|
14
15
|
* Configuration options for bundling file-based components.
|
|
15
16
|
*/
|
|
@@ -172,6 +173,19 @@ export interface TemplateHelpers {
|
|
|
172
173
|
* Safely embed JSON data in HTML (escapes script-breaking characters).
|
|
173
174
|
*/
|
|
174
175
|
jsonEmbed: (data: unknown) => string;
|
|
176
|
+
/**
|
|
177
|
+
* Tagged template that builds trusted markup. The literal parts stay HTML; each interpolated
|
|
178
|
+
* value is HTML-escaped unless it is itself `TrustedHtml`. Arrays are joined without a
|
|
179
|
+
* separator and `null` / `undefined` / `false` render nothing. Don't pre-escape values.
|
|
180
|
+
*
|
|
181
|
+
* @example ctx.helpers.html`<h2>${ctx.output.title}</h2>`
|
|
182
|
+
*/
|
|
183
|
+
html: (strings: TemplateStringsArray, ...values: unknown[]) => TrustedHtml;
|
|
184
|
+
/**
|
|
185
|
+
* Mark markup you produced or sanitized yourself as trusted, so it renders as HTML even when
|
|
186
|
+
* `escapeStringResults` is on. Never pass raw tool output or user input.
|
|
187
|
+
*/
|
|
188
|
+
trustedHtml: (markup: string) => TrustedHtml;
|
|
175
189
|
}
|
|
176
190
|
/**
|
|
177
191
|
* Context passed to template builder functions.
|
|
@@ -198,9 +212,10 @@ export interface TemplateContext<In = unknown, Out = unknown> {
|
|
|
198
212
|
}
|
|
199
213
|
/**
|
|
200
214
|
* Template builder function type.
|
|
201
|
-
* Receives context with input/output and returns
|
|
215
|
+
* Receives context with input/output and returns markup: `TrustedHtml` from
|
|
216
|
+
* `ctx.helpers.html` / `ctx.helpers.trustedHtml`, or a string (see `escapeStringResults`).
|
|
202
217
|
*/
|
|
203
|
-
export type TemplateBuilderFn<In = unknown, Out = unknown> = (ctx: TemplateContext<In, Out>) => string;
|
|
218
|
+
export type TemplateBuilderFn<In = unknown, Out = unknown> = (ctx: TemplateContext<In, Out>) => string | TrustedHtml;
|
|
204
219
|
/**
|
|
205
220
|
* Widget serving mode determines how the widget HTML is delivered to the client.
|
|
206
221
|
*
|
|
@@ -331,6 +346,19 @@ export interface UITemplateConfig<In = unknown, Out = unknown> {
|
|
|
331
346
|
* ```
|
|
332
347
|
*/
|
|
333
348
|
contentSecurity?: UIContentSecurity;
|
|
349
|
+
/**
|
|
350
|
+
* HTML-escape a plain string returned by a template function.
|
|
351
|
+
*
|
|
352
|
+
* - `true`: plain strings are escaped and shown as text; markup built with
|
|
353
|
+
* `ctx.helpers.html` or wrapped with `ctx.helpers.trustedHtml` still renders as HTML.
|
|
354
|
+
* - unset (1.8 default): strings that look like HTML render as markup, and a one-time
|
|
355
|
+
* notice per tool recommends `html` because 1.9 will escape string results by default.
|
|
356
|
+
* - `false`: keep rendering strings as markup without the notice.
|
|
357
|
+
*
|
|
358
|
+
* Overrides the server-wide `@FrontMcp({ ui: { escapeStringResults } })` default.
|
|
359
|
+
* Static string templates (`template: '<div>…</div>'`) are author markup and never escaped.
|
|
360
|
+
*/
|
|
361
|
+
escapeStringResults?: boolean;
|
|
334
362
|
/**
|
|
335
363
|
* Whether the widget can invoke tools via the MCP bridge.
|
|
336
364
|
* When true, the widget gains access to `window.mcpBridge.callTool()`.
|
package/types/ui-config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui-config.d.ts","sourceRoot":"","sources":["../../src/types/ui-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"ui-config.d.ts","sourceRoot":"","sources":["../../src/types/ui-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gCAAgC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yCAAyC;IACzC,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gCAAgC;IAChC,MAAM,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IACzE,0BAA0B;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2BAA2B;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAE1B;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;;OAcG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;;;;;;;OAaG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B;;;;;;;;;;;;;;;;;OAiBG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAMD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;OAIG;IACH,UAAU,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IAErC;;;;OAIG;IACH,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAE7D;;;;OAIG;IACH,cAAc,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAE9D;;;OAGG;IACH,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IAEtC;;OAEG;IACH,SAAS,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC;IAErC;;;;;;OAMG;IACH,IAAI,EAAE,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,KAAK,WAAW,CAAC;IAE3E;;;OAGG;IACH,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,WAAW,CAAC;CAC9C;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO;IAC1D;;OAEG;IACH,KAAK,EAAE,EAAE,CAAC;IAEV;;OAEG;IACH,MAAM,EAAE,GAAG,CAAC;IAEZ;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;OAEG;IACH,OAAO,EAAE,eAAe,CAAC;CAC1B;AAED;;;;GAIG;AACH,MAAM,MAAM,iBAAiB,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,EAAE,EAAE,GAAG,CAAC,KAAK,MAAM,GAAG,WAAW,CAAC;AAMrH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,MAAM,iBAAiB,GACzB,MAAM,GACN,QAAQ,GACR,QAAQ,GACR,QAAQ,GACR,YAAY,GACZ,YAAY,CAAC;AAMjB;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,YAAY,GAAG,KAAK,CAAC;AAEhE;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,MAAM,CAAC;AAK9C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,gBAAgB,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO;IAC3D;;;;;;;;OAQG;IAEH,QAAQ,EAAE,iBAAiB,CAAC,EAAE,EAAE,GAAG,CAAC,GAAG,MAAM,GAAG,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,GAAG,UAAU,CAAC;IAEnF;;;OAGG;IACH,GAAG,CAAC,EAAE,uBAAuB,CAAC;IAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4CG;IACH,eAAe,CAAC,EAAE,iBAAiB,CAAC;IAEpC;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAEhC;;;;;;;;OAQG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAE5B;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAE5B;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE9B;;;;;;;;;;;;;;;;OAgBG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAE3B;;;;;;;;;;;OAWG;IACH,gBAAgB,CAAC,EAAE;QACjB,gDAAgD;QAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,uDAAuD;QACvD,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;IAEF;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;IAEhC;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB;;;;;;;;;OASG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;;;;;;;;;;;;OAcG;IAEH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAMpC;;;;;;;;;OASG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE;QACnB,oEAAoE;QACpE,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,qDAAqD;QACrD,oBAAoB,CAAC,EAAE,OAAO,CAAC;KAChC,CAAC;IAEF;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAMvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8CG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAMlB;;;;;;;;;;OAUG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAC;IAExD;;;;;;;OAOG;IACH,YAAY,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAEpC;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,YAAY,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAEhC;;OAEG;IACH,cAAc,CAAC,EAAE;QACf,uCAAuC;QACvC,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,iCAAiC;QACjC,QAAQ,CAAC,EAAE;YACT,sCAAsC;YACtC,GAAG,CAAC,EAAE,OAAO,CAAC;YACd,gCAAgC;YAChC,cAAc,CAAC,EAAE,MAAM,CAAC;SACzB,CAAC;KACH,CAAC;IAMF;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAM5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4CG;IACH,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IAErB;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAEtC;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,WAAW,CAAC,EAAE,iBAAiB,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,GAAG,OAAO,IAAI,gBAAgB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC"}
|
package/utils/index.d.ts
CHANGED
|
@@ -11,5 +11,12 @@ export declare function escapeHtml(str: unknown): string;
|
|
|
11
11
|
export declare function escapeHtmlAttr(str: string): string;
|
|
12
12
|
export declare function escapeJsString(str: string): string;
|
|
13
13
|
export declare function escapeScriptClose(jsonString: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Serialize a value as JSON that can be embedded in an inline `<script>`.
|
|
16
|
+
*
|
|
17
|
+
* `<`, `>`, `&`, U+2028 and U+2029 are written as `\uXXXX`, so the output can neither close
|
|
18
|
+
* the element, open a comment or nested script, nor end a line; `JSON.parse` and the JS engine
|
|
19
|
+
* read the escapes back as the original characters.
|
|
20
|
+
*/
|
|
14
21
|
export declare function safeJsonForScript(value: unknown): string;
|
|
15
22
|
//# 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;;;;;;;GAOG;AAEH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBpE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAc/C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAiBpE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAc/C;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAElD;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAUlD;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE5D;AAQD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAqBxD"}
|
package/utils/index.js
CHANGED
|
@@ -62,6 +62,10 @@ function escapeJsString(str) {
|
|
|
62
62
|
function escapeScriptClose(jsonString) {
|
|
63
63
|
return jsonString.replace(/<\//g, "<\\/");
|
|
64
64
|
}
|
|
65
|
+
var SCRIPT_UNSAFE_CHARACTERS = /[<>&\u2028\u2029]/g;
|
|
66
|
+
function toUnicodeEscape(character) {
|
|
67
|
+
return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
|
|
68
|
+
}
|
|
65
69
|
function safeJsonForScript(value) {
|
|
66
70
|
if (value === void 0) {
|
|
67
71
|
return "null";
|
|
@@ -76,7 +80,7 @@ function safeJsonForScript(value) {
|
|
|
76
80
|
if (jsonString === void 0) {
|
|
77
81
|
return "null";
|
|
78
82
|
}
|
|
79
|
-
return
|
|
83
|
+
return jsonString.replace(SCRIPT_UNSAFE_CHARACTERS, toUnicodeEscape);
|
|
80
84
|
} catch {
|
|
81
85
|
return '{"error":"Value could not be serialized"}';
|
|
82
86
|
}
|