@vielzeug/sandbox 2.0.0 → 2.1.0
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/dist/_document.cjs +3 -3
- package/dist/_document.cjs.map +1 -1
- package/dist/_document.d.ts +2 -2
- package/dist/_document.d.ts.map +1 -1
- package/dist/_document.js +9 -12
- package/dist/_document.js.map +1 -1
- package/dist/_policy.cjs +1 -1
- package/dist/_policy.cjs.map +1 -1
- package/dist/_policy.d.ts +1 -0
- package/dist/_policy.d.ts.map +1 -1
- package/dist/_policy.js +4 -1
- package/dist/_policy.js.map +1 -1
- package/dist/_runtime.cjs +1 -1
- package/dist/_runtime.cjs.map +1 -1
- package/dist/_runtime.d.ts.map +1 -1
- package/dist/_runtime.js +1 -1
- package/dist/_runtime.js.map +1 -1
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +0 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +1 -4
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -4
- package/dist/sandbox.cjs +14 -14
- package/dist/sandbox.cjs.map +1 -1
- package/dist/sandbox.iife.js +13 -13
- package/dist/sandbox.iife.js.map +1 -1
- package/dist/sandbox.js +14 -14
- package/dist/sandbox.js.map +1 -1
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.ts +4 -4
- package/dist/testing.d.ts.map +1 -1
- package/dist/testing.js.map +1 -1
- package/dist/types.d.ts +25 -25
- package/dist/types.d.ts.map +1 -1
- package/package.json +28 -23
- package/dist/_sandbox.cjs +0 -2
- package/dist/_sandbox.cjs.map +0 -1
- package/dist/_sandbox.d.ts +0 -5
- package/dist/_sandbox.d.ts.map +0 -1
- package/dist/_sandbox.js +0 -11
- package/dist/_sandbox.js.map +0 -1
package/dist/_document.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const e=require("./
|
|
1
|
+
const e=require("./_bridge.cjs"),t=require("./_policy.cjs");function n(e){return e.replace(/<\/style/gi,`\\3C /style`)}function r(e){return e.replace(/&/g,`&`).replace(/"/g,`"`).replace(/</g,`<`).replace(/>/g,`>`)}function i(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`)}function a(a,o,s){let c=r(t.buildCspFromOptions(o)),l=Object.entries(o.namedStyles).map(([e,t])=>`<style id="${r(e)}">${n(t)}</style>`).join(`
|
|
2
2
|
`),u=o.scripts.map(e=>`<script crossorigin="anonymous" src="${r(e)}"><\/script>`).join(`
|
|
3
3
|
`),d=o.nonce?` nonce="${r(o.nonce)}"`:``,f=`<script${d}>window.__sandboxChannel=${JSON.stringify(s.channel)};window.__sandboxGeneration=${s.generation};<\/script>`;return`<!doctype html>
|
|
4
4
|
<html lang="${r(o.lang)}">
|
|
@@ -14,8 +14,8 @@ ${l}
|
|
|
14
14
|
${u}
|
|
15
15
|
${a}
|
|
16
16
|
<script${d}>
|
|
17
|
-
${
|
|
17
|
+
${e.buildBridgeScript(s)}
|
|
18
18
|
<\/script>
|
|
19
19
|
</body>
|
|
20
|
-
</html>`}function o(
|
|
20
|
+
</html>`}function o(e,n={}){return a(e,t.normalizeSandboxOptions(n),{channel:``,generation:0})}exports.buildDocument=o,exports.buildDocumentFromOptions=a;
|
|
21
21
|
//# sourceMappingURL=_document.cjs.map
|
package/dist/_document.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_document.cjs","names":[],"sources":["../src/_document.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"_document.cjs","names":[],"sources":["../src/_document.ts"],"sourcesContent":["import { buildBridgeScript } from './_bridge.js';\nimport { buildCspFromOptions, type NormalizedSandboxOptions, normalizeSandboxOptions } from './_policy.js';\nimport type { BridgeBootstrap } from './_protocol.js';\nimport type { SandboxOptions } from './types.js';\n\nfunction escapeCss(css: string): string {\n return css.replace(/<\\/style/gi, '\\\\3C /style');\n}\n\nfunction escapeAttr(value: string): string {\n return value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n}\n\nfunction escapeText(value: string): string {\n return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nexport function buildDocumentFromOptions(\n html: string,\n options: NormalizedSandboxOptions,\n bootstrap: BridgeBootstrap,\n): string {\n const csp = escapeAttr(buildCspFromOptions(options));\n const styles = Object.entries(options.namedStyles)\n .map(([id, css]) => `<style id=\"${escapeAttr(id)}\">${escapeCss(css)}</style>`)\n .join('\\n');\n const scripts = options.scripts\n .map((src) => `<script crossorigin=\"anonymous\" src=\"${escapeAttr(src)}\"></script>`)\n .join('\\n');\n const nonce = options.nonce ? ` nonce=\"${escapeAttr(options.nonce)}\"` : '';\n const bootstrapScript = `<script${nonce}>window.__sandboxChannel=${JSON.stringify(bootstrap.channel)};window.__sandboxGeneration=${bootstrap.generation};</script>`;\n\n return `<!doctype html>\n<html lang=\"${escapeAttr(options.lang)}\">\n<head>\n<meta http-equiv=\"Content-Security-Policy\" content=\"${csp}\">\n${bootstrapScript}\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${escapeText(options.title)}</title>\n${styles}\n</head>\n<body>\n${scripts}\n${html}\n<script${nonce}>\n${buildBridgeScript(bootstrap)}\n</script>\n</body>\n</html>`;\n}\n\nexport function buildDocument(html: string, options: SandboxOptions = {}): string {\n return buildDocumentFromOptions(html, normalizeSandboxOptions(options), { channel: '', generation: 0 });\n}\n"],"mappings":"4DAKA,SAAS,EAAU,EAAqB,CACtC,OAAO,EAAI,QAAQ,aAAc,aAAa,CAChD,CAEA,SAAS,EAAW,EAAuB,CACzC,OAAO,EAAM,QAAQ,KAAM,OAAO,CAAC,CAAC,QAAQ,KAAM,QAAQ,CAAC,CAAC,QAAQ,KAAM,MAAM,CAAC,CAAC,QAAQ,KAAM,MAAM,CACxG,CAEA,SAAS,EAAW,EAAuB,CACzC,OAAO,EAAM,QAAQ,KAAM,OAAO,CAAC,CAAC,QAAQ,KAAM,MAAM,CAAC,CAAC,QAAQ,KAAM,MAAM,CAChF,CAEA,SAAgB,EACd,EACA,EACA,EACQ,CACR,IAAM,EAAM,EAAW,EAAA,oBAAoB,CAAO,CAAC,EAC7C,EAAS,OAAO,QAAQ,EAAQ,WAAW,CAAC,CAC/C,KAAK,CAAC,EAAI,KAAS,cAAc,EAAW,CAAE,EAAE,IAAI,EAAU,CAAG,EAAE,SAAS,CAAC,CAC7E,KAAK;CAAI,EACN,EAAU,EAAQ,QACrB,IAAK,GAAQ,wCAAwC,EAAW,CAAG,EAAE,aAAY,CAAC,CAClF,KAAK;CAAI,EACN,EAAQ,EAAQ,MAAQ,WAAW,EAAW,EAAQ,KAAK,EAAE,GAAK,GAClE,EAAkB,UAAU,EAAM,2BAA2B,KAAK,UAAU,EAAU,OAAO,EAAE,8BAA8B,EAAU,WAAW,aAExJ,MAAO;cACK,EAAW,EAAQ,IAAI,EAAE;;sDAEe,EAAI;EACxD,EAAgB;;;SAGT,EAAW,EAAQ,KAAK,EAAE;EACjC,EAAO;;;EAGP,EAAQ;EACR,EAAK;SACE,EAAM;EACb,EAAA,kBAAkB,CAAS,EAAE;;;QAI/B,CAEA,SAAgB,EAAc,EAAc,EAA0B,CAAC,EAAW,CAChF,OAAO,EAAyB,EAAM,EAAA,wBAAwB,CAAO,EAAG,CAAE,QAAS,GAAI,WAAY,CAAE,CAAC,CACxG"}
|
package/dist/_document.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { type NormalizedSandboxOptions } from './_policy.js';
|
|
1
2
|
import type { BridgeBootstrap } from './_protocol.js';
|
|
2
3
|
import type { SandboxOptions } from './types.js';
|
|
3
|
-
|
|
4
|
+
export declare function buildDocumentFromOptions(html: string, options: NormalizedSandboxOptions, bootstrap: BridgeBootstrap): string;
|
|
4
5
|
export declare function buildDocument(html: string, options?: SandboxOptions): string;
|
|
5
|
-
export declare function buildRuntimeDocument(html: string, options: NormalizedSandboxOptions, bootstrap: BridgeBootstrap): string;
|
|
6
6
|
//# sourceMappingURL=_document.d.ts.map
|
package/dist/_document.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_document.d.ts","sourceRoot":"","sources":["../src/_document.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"_document.d.ts","sourceRoot":"","sources":["../src/_document.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,KAAK,wBAAwB,EAA2B,MAAM,cAAc,CAAC;AAC3G,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAcjD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,wBAAwB,EACjC,SAAS,EAAE,eAAe,GACzB,MAAM,CA6BR;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CAEhF"}
|
package/dist/_document.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { buildBridgeScript as e } from "./_bridge.js";
|
|
2
|
+
import { buildCspFromOptions as t, normalizeSandboxOptions as n } from "./_policy.js";
|
|
3
3
|
//#region src/_document.ts
|
|
4
4
|
function r(e) {
|
|
5
5
|
return e.replace(/<\/style/gi, "\\3C /style");
|
|
@@ -10,8 +10,8 @@ function i(e) {
|
|
|
10
10
|
function a(e) {
|
|
11
11
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
12
12
|
}
|
|
13
|
-
function o(
|
|
14
|
-
let c = i(
|
|
13
|
+
function o(n, o, s) {
|
|
14
|
+
let c = i(t(o)), l = Object.entries(o.namedStyles).map(([e, t]) => `<style id="${i(e)}">${r(t)}</style>`).join("\n"), u = o.scripts.map((e) => `<script crossorigin="anonymous" src="${i(e)}"><\/script>`).join("\n"), d = o.nonce ? ` nonce="${i(o.nonce)}"` : "", f = `<script${d}>window.__sandboxChannel=${JSON.stringify(s.channel)};window.__sandboxGeneration=${s.generation};<\/script>`;
|
|
15
15
|
return `<!doctype html>
|
|
16
16
|
<html lang="${i(o.lang)}">
|
|
17
17
|
<head>
|
|
@@ -24,23 +24,20 @@ ${l}
|
|
|
24
24
|
</head>
|
|
25
25
|
<body>
|
|
26
26
|
${u}
|
|
27
|
-
${
|
|
27
|
+
${n}
|
|
28
28
|
<script${d}>
|
|
29
|
-
${
|
|
29
|
+
${e(s)}
|
|
30
30
|
<\/script>
|
|
31
31
|
</body>
|
|
32
32
|
</html>`;
|
|
33
33
|
}
|
|
34
|
-
function s(e,
|
|
35
|
-
return o(e, t
|
|
34
|
+
function s(e, t = {}) {
|
|
35
|
+
return o(e, n(t), {
|
|
36
36
|
channel: "",
|
|
37
37
|
generation: 0
|
|
38
38
|
});
|
|
39
39
|
}
|
|
40
|
-
function c(e, t, n) {
|
|
41
|
-
return o(e, t, n);
|
|
42
|
-
}
|
|
43
40
|
//#endregion
|
|
44
|
-
export { s as buildDocument,
|
|
41
|
+
export { s as buildDocument, o as buildDocumentFromOptions };
|
|
45
42
|
|
|
46
43
|
//# sourceMappingURL=_document.js.map
|
package/dist/_document.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_document.js","names":[],"sources":["../src/_document.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"_document.js","names":[],"sources":["../src/_document.ts"],"sourcesContent":["import { buildBridgeScript } from './_bridge.js';\nimport { buildCspFromOptions, type NormalizedSandboxOptions, normalizeSandboxOptions } from './_policy.js';\nimport type { BridgeBootstrap } from './_protocol.js';\nimport type { SandboxOptions } from './types.js';\n\nfunction escapeCss(css: string): string {\n return css.replace(/<\\/style/gi, '\\\\3C /style');\n}\n\nfunction escapeAttr(value: string): string {\n return value.replace(/&/g, '&').replace(/\"/g, '"').replace(/</g, '<').replace(/>/g, '>');\n}\n\nfunction escapeText(value: string): string {\n return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');\n}\n\nexport function buildDocumentFromOptions(\n html: string,\n options: NormalizedSandboxOptions,\n bootstrap: BridgeBootstrap,\n): string {\n const csp = escapeAttr(buildCspFromOptions(options));\n const styles = Object.entries(options.namedStyles)\n .map(([id, css]) => `<style id=\"${escapeAttr(id)}\">${escapeCss(css)}</style>`)\n .join('\\n');\n const scripts = options.scripts\n .map((src) => `<script crossorigin=\"anonymous\" src=\"${escapeAttr(src)}\"></script>`)\n .join('\\n');\n const nonce = options.nonce ? ` nonce=\"${escapeAttr(options.nonce)}\"` : '';\n const bootstrapScript = `<script${nonce}>window.__sandboxChannel=${JSON.stringify(bootstrap.channel)};window.__sandboxGeneration=${bootstrap.generation};</script>`;\n\n return `<!doctype html>\n<html lang=\"${escapeAttr(options.lang)}\">\n<head>\n<meta http-equiv=\"Content-Security-Policy\" content=\"${csp}\">\n${bootstrapScript}\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>${escapeText(options.title)}</title>\n${styles}\n</head>\n<body>\n${scripts}\n${html}\n<script${nonce}>\n${buildBridgeScript(bootstrap)}\n</script>\n</body>\n</html>`;\n}\n\nexport function buildDocument(html: string, options: SandboxOptions = {}): string {\n return buildDocumentFromOptions(html, normalizeSandboxOptions(options), { channel: '', generation: 0 });\n}\n"],"mappings":";;;AAKA,SAAS,EAAU,GAAqB;CACtC,OAAO,EAAI,QAAQ,cAAc,aAAa;AAChD;AAEA,SAAS,EAAW,GAAuB;CACzC,OAAO,EAAM,QAAQ,MAAM,OAAO,CAAC,CAAC,QAAQ,MAAM,QAAQ,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM,MAAM;AACxG;AAEA,SAAS,EAAW,GAAuB;CACzC,OAAO,EAAM,QAAQ,MAAM,OAAO,CAAC,CAAC,QAAQ,MAAM,MAAM,CAAC,CAAC,QAAQ,MAAM,MAAM;AAChF;AAEA,SAAgB,EACd,GACA,GACA,GACQ;CACR,IAAM,IAAM,EAAW,EAAoB,CAAO,CAAC,GAC7C,IAAS,OAAO,QAAQ,EAAQ,WAAW,CAAC,CAC/C,KAAK,CAAC,GAAI,OAAS,cAAc,EAAW,CAAE,EAAE,IAAI,EAAU,CAAG,EAAE,SAAS,CAAC,CAC7E,KAAK,IAAI,GACN,IAAU,EAAQ,QACrB,KAAK,MAAQ,wCAAwC,EAAW,CAAG,EAAE,aAAY,CAAC,CAClF,KAAK,IAAI,GACN,IAAQ,EAAQ,QAAQ,WAAW,EAAW,EAAQ,KAAK,EAAE,KAAK,IAClE,IAAkB,UAAU,EAAM,2BAA2B,KAAK,UAAU,EAAU,OAAO,EAAE,8BAA8B,EAAU,WAAW;CAExJ,OAAO;cACK,EAAW,EAAQ,IAAI,EAAE;;sDAEe,EAAI;EACxD,EAAgB;;;SAGT,EAAW,EAAQ,KAAK,EAAE;EACjC,EAAO;;;EAGP,EAAQ;EACR,EAAK;SACE,EAAM;EACb,EAAkB,CAAS,EAAE;;;;AAI/B;AAEA,SAAgB,EAAc,GAAc,IAA0B,CAAC,GAAW;CAChF,OAAO,EAAyB,GAAM,EAAwB,CAAO,GAAG;EAAE,SAAS;EAAI,YAAY;CAAE,CAAC;AACxG"}
|
package/dist/_policy.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./errors.cjs");var t=/^[A-Za-z][A-Za-z0-9_-]*$/,n=/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/,r=/^[A-Za-z0-9+/_-]+={0,2}$/;function i(t,n){throw new e.SandboxConfigurationError(`${t} is invalid: ${String(n)}`)}function a(e,t){let n;try{n=new URL(e)}catch{return i(t,e)}return n.protocol!==`http:`&&n.protocol!==`https:`||n.username||n.password||n.pathname!==`/`||n.search||n.hash?i(t,e):n.origin}function o(e,t){return(e??[]).map(e=>a(e,t))}function s(e){let t;try{t=new URL(e)}catch{return i(`scripts`,e)}return t.protocol!==`http:`&&t.protocol!==`https:`?i(`scripts`,e):t.href}function c(e){let n={};for(let[r,a]of Object.entries(e??{}))(!t.test(r)||typeof a!=`string`)&&i(`namedStyles`,r),n[r]=a;return n}function l(e={}){let t=e.lang??`en`;n.test(t)||i(`lang`,t),e.nonce!==void 0&&(!r.test(e.nonce)||e.nonce.length===0)&&i(`nonce`,e.nonce),e.title!==void 0&&typeof e.title!=`string`&&i(`title`,e.title);let a=(e.scripts??[]).map(s);return{allowedFontOrigins:o(e.allowedFontOrigins,`allowedFontOrigins`),allowedImageOrigins:o(e.allowedImageOrigins,`allowedImageOrigins`),allowedScriptOrigins:o(e.allowedScriptOrigins,`allowedScriptOrigins`),allowedStyleOrigins:o(e.allowedStyleOrigins,`allowedStyleOrigins`),lang:t,namedStyles:c(e.namedStyles),nonce:e.nonce,scripts:a,title:e.title??``}}function u(e){let t=[`'unsafe-inline'`,...e.nonce?[`'nonce-${e.nonce}'`]:[],...e.allowedScriptOrigins,...e.scripts.map(e=>new URL(e).origin)].join(` `),n=[`'unsafe-inline'`,...e.allowedStyleOrigins].join(` `),r=[`data:`,...e.allowedImageOrigins].join(` `),i=e.allowedFontOrigins.join(` `)||`'none'`;return[`default-src 'none'`,`script-src ${t}`,`style-src ${n}`,`img-src ${r}`,`font-src ${i}`,`connect-src 'none'`,`form-action 'none'`,`base-uri 'none'`].join(`; `)}exports.buildCspFromOptions=u,exports.normalizeSandboxOptions=l;
|
|
1
|
+
const e=require("./errors.cjs");var t=/^[A-Za-z][A-Za-z0-9_-]*$/,n=/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/,r=/^[A-Za-z0-9+/_-]+={0,2}$/;function i(t,n){throw new e.SandboxConfigurationError(`${t} is invalid: ${String(n)}`)}function a(e,t){let n;try{n=new URL(e)}catch{return i(t,e)}return n.protocol!==`http:`&&n.protocol!==`https:`||n.username||n.password||n.pathname!==`/`||n.search||n.hash?i(t,e):n.origin}function o(e,t){return(e??[]).map(e=>a(e,t))}function s(e){let t;try{t=new URL(e)}catch{return i(`scripts`,e)}return t.protocol!==`http:`&&t.protocol!==`https:`?i(`scripts`,e):t.href}function c(e){let n={};for(let[r,a]of Object.entries(e??{}))(!t.test(r)||typeof a!=`string`)&&i(`namedStyles`,r),n[r]=a;return n}function l(e={}){let t=e.lang??`en`;n.test(t)||i(`lang`,t),e.nonce!==void 0&&(!r.test(e.nonce)||e.nonce.length===0)&&i(`nonce`,e.nonce),e.title!==void 0&&typeof e.title!=`string`&&i(`title`,e.title);let a=(e.scripts??[]).map(s);return{allowedFontOrigins:o(e.allowedFontOrigins,`allowedFontOrigins`),allowedImageOrigins:o(e.allowedImageOrigins,`allowedImageOrigins`),allowedScriptOrigins:o(e.allowedScriptOrigins,`allowedScriptOrigins`),allowedStyleOrigins:o(e.allowedStyleOrigins,`allowedStyleOrigins`),lang:t,namedStyles:c(e.namedStyles),nonce:e.nonce,scripts:a,title:e.title??``}}function u(e){let t=[`'unsafe-inline'`,...e.nonce?[`'nonce-${e.nonce}'`]:[],...e.allowedScriptOrigins,...e.scripts.map(e=>new URL(e).origin)].join(` `),n=[`'unsafe-inline'`,...e.allowedStyleOrigins].join(` `),r=[`data:`,...e.allowedImageOrigins].join(` `),i=e.allowedFontOrigins.join(` `)||`'none'`;return[`default-src 'none'`,`script-src ${t}`,`style-src ${n}`,`img-src ${r}`,`font-src ${i}`,`connect-src 'none'`,`form-action 'none'`,`base-uri 'none'`].join(`; `)}function d(e={}){return u(l(e))}exports.buildCsp=d,exports.buildCspFromOptions=u,exports.normalizeSandboxOptions=l;
|
|
2
2
|
//# sourceMappingURL=_policy.cjs.map
|
package/dist/_policy.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_policy.cjs","names":[],"sources":["../src/_policy.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"_policy.cjs","names":[],"sources":["../src/_policy.ts"],"sourcesContent":["import { SandboxConfigurationError } from './errors.js';\nimport type { SandboxOptions } from './types.js';\n\nexport interface NormalizedSandboxOptions {\n allowedFontOrigins: string[];\n allowedImageOrigins: string[];\n allowedScriptOrigins: string[];\n allowedStyleOrigins: string[];\n lang: string;\n namedStyles: Record<string, string>;\n nonce: string | undefined;\n scripts: string[];\n title: string;\n}\n\nconst ID = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst LANG = /^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/;\nconst NONCE = /^[A-Za-z0-9+/_-]+={0,2}$/;\n\nfunction fail(field: string, value: unknown): never {\n throw new SandboxConfigurationError(`${field} is invalid: ${String(value)}`);\n}\n\nfunction normalizeOrigin(value: string, field: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return fail(field, value);\n }\n\n if (\n (url.protocol !== 'http:' && url.protocol !== 'https:') ||\n url.username ||\n url.password ||\n url.pathname !== '/' ||\n url.search ||\n url.hash\n ) {\n return fail(field, value);\n }\n\n return url.origin;\n}\n\nfunction normalizeOrigins(values: string[] | undefined, field: string): string[] {\n return (values ?? []).map((value) => normalizeOrigin(value, field));\n}\n\nfunction normalizeScript(value: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return fail('scripts', value);\n }\n\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return fail('scripts', value);\n\n return url.href;\n}\n\nfunction normalizeStyles(styles: Record<string, string> | undefined): Record<string, string> {\n const normalized: Record<string, string> = {};\n\n for (const [id, css] of Object.entries(styles ?? {})) {\n if (!ID.test(id) || typeof css !== 'string') fail('namedStyles', id);\n\n normalized[id] = css;\n }\n\n return normalized;\n}\n\nexport function normalizeSandboxOptions(options: SandboxOptions = {}): NormalizedSandboxOptions {\n const lang = options.lang ?? 'en';\n\n if (!LANG.test(lang)) fail('lang', lang);\n\n if (options.nonce !== undefined && (!NONCE.test(options.nonce) || options.nonce.length === 0)) {\n fail('nonce', options.nonce);\n }\n\n if (options.title !== undefined && typeof options.title !== 'string') fail('title', options.title);\n\n const scripts = (options.scripts ?? []).map(normalizeScript);\n\n return {\n allowedFontOrigins: normalizeOrigins(options.allowedFontOrigins, 'allowedFontOrigins'),\n allowedImageOrigins: normalizeOrigins(options.allowedImageOrigins, 'allowedImageOrigins'),\n allowedScriptOrigins: normalizeOrigins(options.allowedScriptOrigins, 'allowedScriptOrigins'),\n allowedStyleOrigins: normalizeOrigins(options.allowedStyleOrigins, 'allowedStyleOrigins'),\n lang,\n namedStyles: normalizeStyles(options.namedStyles),\n nonce: options.nonce,\n scripts,\n title: options.title ?? '',\n };\n}\n\nexport function buildCspFromOptions(options: NormalizedSandboxOptions): string {\n const scriptOrigins = [\n \"'unsafe-inline'\",\n ...(options.nonce ? [`'nonce-${options.nonce}'`] : []),\n ...options.allowedScriptOrigins,\n ...options.scripts.map((script) => new URL(script).origin),\n ].join(' ');\n const styleOrigins = [\"'unsafe-inline'\", ...options.allowedStyleOrigins].join(' ');\n const imageOrigins = ['data:', ...options.allowedImageOrigins].join(' ');\n const fontOrigins = options.allowedFontOrigins.join(' ') || \"'none'\";\n\n return [\n \"default-src 'none'\",\n `script-src ${scriptOrigins}`,\n `style-src ${styleOrigins}`,\n `img-src ${imageOrigins}`,\n `font-src ${fontOrigins}`,\n \"connect-src 'none'\",\n \"form-action 'none'\",\n \"base-uri 'none'\",\n ].join('; ');\n}\n\nexport function buildCsp(options: SandboxOptions = {}): string {\n return buildCspFromOptions(normalizeSandboxOptions(options));\n}\n"],"mappings":"gCAeA,IAAM,EAAK,2BACL,EAAO,wCACP,EAAQ,2BAEd,SAAS,EAAK,EAAe,EAAuB,CAClD,MAAM,IAAI,EAAA,0BAA0B,GAAG,EAAM,eAAe,OAAO,CAAK,GAAG,CAC7E,CAEA,SAAS,EAAgB,EAAe,EAAuB,CAC7D,IAAI,EAEJ,GAAI,CACF,EAAM,IAAI,IAAI,CAAK,CACrB,MAAQ,CACN,OAAO,EAAK,EAAO,CAAK,CAC1B,CAaA,OAVG,EAAI,WAAa,SAAW,EAAI,WAAa,UAC9C,EAAI,UACJ,EAAI,UACJ,EAAI,WAAa,KACjB,EAAI,QACJ,EAAI,KAEG,EAAK,EAAO,CAAK,EAGnB,EAAI,MACb,CAEA,SAAS,EAAiB,EAA8B,EAAyB,CAC/E,OAAQ,GAAU,CAAC,EAAA,CAAG,IAAK,GAAU,EAAgB,EAAO,CAAK,CAAC,CACpE,CAEA,SAAS,EAAgB,EAAuB,CAC9C,IAAI,EAEJ,GAAI,CACF,EAAM,IAAI,IAAI,CAAK,CACrB,MAAQ,CACN,OAAO,EAAK,UAAW,CAAK,CAC9B,CAIA,OAFI,EAAI,WAAa,SAAW,EAAI,WAAa,SAAiB,EAAK,UAAW,CAAK,EAEhF,EAAI,IACb,CAEA,SAAS,EAAgB,EAAoE,CAC3F,IAAM,EAAqC,CAAC,EAE5C,IAAK,GAAM,CAAC,EAAI,KAAQ,OAAO,QAAQ,GAAU,CAAC,CAAC,GAC7C,CAAC,EAAG,KAAK,CAAE,GAAK,OAAO,GAAQ,WAAU,EAAK,cAAe,CAAE,EAEnE,EAAW,GAAM,EAGnB,OAAO,CACT,CAEA,SAAgB,EAAwB,EAA0B,CAAC,EAA6B,CAC9F,IAAM,EAAO,EAAQ,MAAQ,KAExB,EAAK,KAAK,CAAI,GAAG,EAAK,OAAQ,CAAI,EAEnC,EAAQ,QAAU,IAAA,KAAc,CAAC,EAAM,KAAK,EAAQ,KAAK,GAAK,EAAQ,MAAM,SAAW,IACzF,EAAK,QAAS,EAAQ,KAAK,EAGzB,EAAQ,QAAU,IAAA,IAAa,OAAO,EAAQ,OAAU,UAAU,EAAK,QAAS,EAAQ,KAAK,EAEjG,IAAM,GAAW,EAAQ,SAAW,CAAC,EAAA,CAAG,IAAI,CAAe,EAE3D,MAAO,CACL,mBAAoB,EAAiB,EAAQ,mBAAoB,oBAAoB,EACrF,oBAAqB,EAAiB,EAAQ,oBAAqB,qBAAqB,EACxF,qBAAsB,EAAiB,EAAQ,qBAAsB,sBAAsB,EAC3F,oBAAqB,EAAiB,EAAQ,oBAAqB,qBAAqB,EACxF,OACA,YAAa,EAAgB,EAAQ,WAAW,EAChD,MAAO,EAAQ,MACf,UACA,MAAO,EAAQ,OAAS,EAC1B,CACF,CAEA,SAAgB,EAAoB,EAA2C,CAC7E,IAAM,EAAgB,CACpB,kBACA,GAAI,EAAQ,MAAQ,CAAC,UAAU,EAAQ,MAAM,EAAE,EAAI,CAAC,EACpD,GAAG,EAAQ,qBACX,GAAG,EAAQ,QAAQ,IAAK,GAAW,IAAI,IAAI,CAAM,CAAC,CAAC,MAAM,CAC3D,CAAC,CAAC,KAAK,GAAG,EACJ,EAAe,CAAC,kBAAmB,GAAG,EAAQ,mBAAmB,CAAC,CAAC,KAAK,GAAG,EAC3E,EAAe,CAAC,QAAS,GAAG,EAAQ,mBAAmB,CAAC,CAAC,KAAK,GAAG,EACjE,EAAc,EAAQ,mBAAmB,KAAK,GAAG,GAAK,SAE5D,MAAO,CACL,qBACA,cAAc,IACd,aAAa,IACb,WAAW,IACX,YAAY,IACZ,qBACA,qBACA,iBACF,CAAC,CAAC,KAAK,IAAI,CACb,CAEA,SAAgB,EAAS,EAA0B,CAAC,EAAW,CAC7D,OAAO,EAAoB,EAAwB,CAAO,CAAC,CAC7D"}
|
package/dist/_policy.d.ts
CHANGED
|
@@ -12,4 +12,5 @@ export interface NormalizedSandboxOptions {
|
|
|
12
12
|
}
|
|
13
13
|
export declare function normalizeSandboxOptions(options?: SandboxOptions): NormalizedSandboxOptions;
|
|
14
14
|
export declare function buildCspFromOptions(options: NormalizedSandboxOptions): string;
|
|
15
|
+
export declare function buildCsp(options?: SandboxOptions): string;
|
|
15
16
|
//# sourceMappingURL=_policy.d.ts.map
|
package/dist/_policy.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_policy.d.ts","sourceRoot":"","sources":["../src/_policy.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"_policy.d.ts","sourceRoot":"","sources":["../src/_policy.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD,MAAM,WAAW,wBAAwB;IACvC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,mBAAmB,EAAE,MAAM,EAAE,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACpC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf;AA+DD,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,cAAmB,GAAG,wBAAwB,CAwB9F;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAqB7E;AAED,wBAAgB,QAAQ,CAAC,OAAO,GAAE,cAAmB,GAAG,MAAM,CAE7D"}
|
package/dist/_policy.js
CHANGED
|
@@ -64,7 +64,10 @@ function u(e) {
|
|
|
64
64
|
"base-uri 'none'"
|
|
65
65
|
].join("; ");
|
|
66
66
|
}
|
|
67
|
+
function d(e = {}) {
|
|
68
|
+
return u(l(e));
|
|
69
|
+
}
|
|
67
70
|
//#endregion
|
|
68
|
-
export { u as buildCspFromOptions, l as normalizeSandboxOptions };
|
|
71
|
+
export { d as buildCsp, u as buildCspFromOptions, l as normalizeSandboxOptions };
|
|
69
72
|
|
|
70
73
|
//# sourceMappingURL=_policy.js.map
|
package/dist/_policy.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_policy.js","names":[],"sources":["../src/_policy.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"file":"_policy.js","names":[],"sources":["../src/_policy.ts"],"sourcesContent":["import { SandboxConfigurationError } from './errors.js';\nimport type { SandboxOptions } from './types.js';\n\nexport interface NormalizedSandboxOptions {\n allowedFontOrigins: string[];\n allowedImageOrigins: string[];\n allowedScriptOrigins: string[];\n allowedStyleOrigins: string[];\n lang: string;\n namedStyles: Record<string, string>;\n nonce: string | undefined;\n scripts: string[];\n title: string;\n}\n\nconst ID = /^[A-Za-z][A-Za-z0-9_-]*$/;\nconst LANG = /^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/;\nconst NONCE = /^[A-Za-z0-9+/_-]+={0,2}$/;\n\nfunction fail(field: string, value: unknown): never {\n throw new SandboxConfigurationError(`${field} is invalid: ${String(value)}`);\n}\n\nfunction normalizeOrigin(value: string, field: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return fail(field, value);\n }\n\n if (\n (url.protocol !== 'http:' && url.protocol !== 'https:') ||\n url.username ||\n url.password ||\n url.pathname !== '/' ||\n url.search ||\n url.hash\n ) {\n return fail(field, value);\n }\n\n return url.origin;\n}\n\nfunction normalizeOrigins(values: string[] | undefined, field: string): string[] {\n return (values ?? []).map((value) => normalizeOrigin(value, field));\n}\n\nfunction normalizeScript(value: string): string {\n let url: URL;\n\n try {\n url = new URL(value);\n } catch {\n return fail('scripts', value);\n }\n\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return fail('scripts', value);\n\n return url.href;\n}\n\nfunction normalizeStyles(styles: Record<string, string> | undefined): Record<string, string> {\n const normalized: Record<string, string> = {};\n\n for (const [id, css] of Object.entries(styles ?? {})) {\n if (!ID.test(id) || typeof css !== 'string') fail('namedStyles', id);\n\n normalized[id] = css;\n }\n\n return normalized;\n}\n\nexport function normalizeSandboxOptions(options: SandboxOptions = {}): NormalizedSandboxOptions {\n const lang = options.lang ?? 'en';\n\n if (!LANG.test(lang)) fail('lang', lang);\n\n if (options.nonce !== undefined && (!NONCE.test(options.nonce) || options.nonce.length === 0)) {\n fail('nonce', options.nonce);\n }\n\n if (options.title !== undefined && typeof options.title !== 'string') fail('title', options.title);\n\n const scripts = (options.scripts ?? []).map(normalizeScript);\n\n return {\n allowedFontOrigins: normalizeOrigins(options.allowedFontOrigins, 'allowedFontOrigins'),\n allowedImageOrigins: normalizeOrigins(options.allowedImageOrigins, 'allowedImageOrigins'),\n allowedScriptOrigins: normalizeOrigins(options.allowedScriptOrigins, 'allowedScriptOrigins'),\n allowedStyleOrigins: normalizeOrigins(options.allowedStyleOrigins, 'allowedStyleOrigins'),\n lang,\n namedStyles: normalizeStyles(options.namedStyles),\n nonce: options.nonce,\n scripts,\n title: options.title ?? '',\n };\n}\n\nexport function buildCspFromOptions(options: NormalizedSandboxOptions): string {\n const scriptOrigins = [\n \"'unsafe-inline'\",\n ...(options.nonce ? [`'nonce-${options.nonce}'`] : []),\n ...options.allowedScriptOrigins,\n ...options.scripts.map((script) => new URL(script).origin),\n ].join(' ');\n const styleOrigins = [\"'unsafe-inline'\", ...options.allowedStyleOrigins].join(' ');\n const imageOrigins = ['data:', ...options.allowedImageOrigins].join(' ');\n const fontOrigins = options.allowedFontOrigins.join(' ') || \"'none'\";\n\n return [\n \"default-src 'none'\",\n `script-src ${scriptOrigins}`,\n `style-src ${styleOrigins}`,\n `img-src ${imageOrigins}`,\n `font-src ${fontOrigins}`,\n \"connect-src 'none'\",\n \"form-action 'none'\",\n \"base-uri 'none'\",\n ].join('; ');\n}\n\nexport function buildCsp(options: SandboxOptions = {}): string {\n return buildCspFromOptions(normalizeSandboxOptions(options));\n}\n"],"mappings":";;AAeA,IAAM,IAAK,4BACL,IAAO,yCACP,IAAQ;AAEd,SAAS,EAAK,GAAe,GAAuB;CAClD,MAAM,IAAI,EAA0B,GAAG,EAAM,eAAe,OAAO,CAAK,GAAG;AAC7E;AAEA,SAAS,EAAgB,GAAe,GAAuB;CAC7D,IAAI;CAEJ,IAAI;EACF,IAAM,IAAI,IAAI,CAAK;CACrB,QAAQ;EACN,OAAO,EAAK,GAAO,CAAK;CAC1B;CAaA,OAVG,EAAI,aAAa,WAAW,EAAI,aAAa,YAC9C,EAAI,YACJ,EAAI,YACJ,EAAI,aAAa,OACjB,EAAI,UACJ,EAAI,OAEG,EAAK,GAAO,CAAK,IAGnB,EAAI;AACb;AAEA,SAAS,EAAiB,GAA8B,GAAyB;CAC/E,QAAQ,KAAU,CAAC,EAAA,CAAG,KAAK,MAAU,EAAgB,GAAO,CAAK,CAAC;AACpE;AAEA,SAAS,EAAgB,GAAuB;CAC9C,IAAI;CAEJ,IAAI;EACF,IAAM,IAAI,IAAI,CAAK;CACrB,QAAQ;EACN,OAAO,EAAK,WAAW,CAAK;CAC9B;CAIA,OAFI,EAAI,aAAa,WAAW,EAAI,aAAa,WAAiB,EAAK,WAAW,CAAK,IAEhF,EAAI;AACb;AAEA,SAAS,EAAgB,GAAoE;CAC3F,IAAM,IAAqC,CAAC;CAE5C,KAAK,IAAM,CAAC,GAAI,MAAQ,OAAO,QAAQ,KAAU,CAAC,CAAC,GAGjD,CAFI,CAAC,EAAG,KAAK,CAAE,KAAK,OAAO,KAAQ,aAAU,EAAK,eAAe,CAAE,GAEnE,EAAW,KAAM;CAGnB,OAAO;AACT;AAEA,SAAgB,EAAwB,IAA0B,CAAC,GAA6B;CAC9F,IAAM,IAAO,EAAQ,QAAQ;CAQ7B,AANK,EAAK,KAAK,CAAI,KAAG,EAAK,QAAQ,CAAI,GAEnC,EAAQ,UAAU,KAAA,MAAc,CAAC,EAAM,KAAK,EAAQ,KAAK,KAAK,EAAQ,MAAM,WAAW,MACzF,EAAK,SAAS,EAAQ,KAAK,GAGzB,EAAQ,UAAU,KAAA,KAAa,OAAO,EAAQ,SAAU,YAAU,EAAK,SAAS,EAAQ,KAAK;CAEjG,IAAM,KAAW,EAAQ,WAAW,CAAC,EAAA,CAAG,IAAI,CAAe;CAE3D,OAAO;EACL,oBAAoB,EAAiB,EAAQ,oBAAoB,oBAAoB;EACrF,qBAAqB,EAAiB,EAAQ,qBAAqB,qBAAqB;EACxF,sBAAsB,EAAiB,EAAQ,sBAAsB,sBAAsB;EAC3F,qBAAqB,EAAiB,EAAQ,qBAAqB,qBAAqB;EACxF;EACA,aAAa,EAAgB,EAAQ,WAAW;EAChD,OAAO,EAAQ;EACf;EACA,OAAO,EAAQ,SAAS;CAC1B;AACF;AAEA,SAAgB,EAAoB,GAA2C;CAC7E,IAAM,IAAgB;EACpB;EACA,GAAI,EAAQ,QAAQ,CAAC,UAAU,EAAQ,MAAM,EAAE,IAAI,CAAC;EACpD,GAAG,EAAQ;EACX,GAAG,EAAQ,QAAQ,KAAK,MAAW,IAAI,IAAI,CAAM,CAAC,CAAC,MAAM;CAC3D,CAAC,CAAC,KAAK,GAAG,GACJ,IAAe,CAAC,mBAAmB,GAAG,EAAQ,mBAAmB,CAAC,CAAC,KAAK,GAAG,GAC3E,IAAe,CAAC,SAAS,GAAG,EAAQ,mBAAmB,CAAC,CAAC,KAAK,GAAG,GACjE,IAAc,EAAQ,mBAAmB,KAAK,GAAG,KAAK;CAE5D,OAAO;EACL;EACA,cAAc;EACd,aAAa;EACb,WAAW;EACX,YAAY;EACZ;EACA;EACA;CACF,CAAC,CAAC,KAAK,IAAI;AACb;AAEA,SAAgB,EAAS,IAA0B,CAAC,GAAW;CAC7D,OAAO,EAAoB,EAAwB,CAAO,CAAC;AAC7D"}
|
package/dist/_runtime.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("./errors.cjs"),t=require("./_policy.cjs"),n=require("./_document.cjs");require("./_dev.cjs");const r=require("./_protocol.cjs");var i=5e3;function a(a,o={}){let s=t.normalizeSandboxOptions(o),c=r.createChannel(),l={...s.namedStyles},u=new Set,d=new AbortController,f=null,p=!1,m=!1,h=0,g=null,_=null,v,y=new Promise(e=>{v=e});function b(){return{channel:c,generation:h}}function x(){g!==null&&(clearTimeout(g),g=null)}function S(){x(),_?.resolve(),_=null,m=!1}function C(e){for(let t of u)t(e)}function w(e){if(!f||e.source!==f.contentWindow)return;let t=b();if(r.isProtocolMessage(e.data,t))switch(e.data.type){case r.MSG_CUSTOM:typeof e.data.event==`string`&&C({detail:e.data.detail,event:e.data.event,type:r.MSG_CUSTOM});break;case r.MSG_ERROR:typeof e.data.message==`string`&&C({message:e.data.message,...typeof e.data.stack==`string`?{stack:e.data.stack}:{},type:r.MSG_ERROR});break;case r.MSG_READY:S(),v(),m=!0;break;case r.MSG_RESIZE:typeof e.data.height==`number`&&Number.isFinite(e.data.height)&&e.data.height>=0&&C({height:e.data.height,type:r.MSG_RESIZE})}}function T(){return f||(f=document.createElement(`iframe`),f.setAttribute(`sandbox`,`allow-scripts`),f.setAttribute(`referrerpolicy`,`no-referrer`),f.dataset.sandboxChannel=c,a.appendChild(f),window.addEventListener(`message`,w),f)}function E(){p||(p=!0,S(),d.abort(),v(),f&&=(window.removeEventListener(`message`,w),f.remove(),null),u.clear())}function D(e){return p?()=>{}:(u.add(e),()=>u.delete(e))}function O(t,r){if(p||r?.signal?.aborted)return Promise.resolve();t.trim(),S(),h+=1;let a=T(),o=b(),c={...s,namedStyles:{...l}};a.dataset.sandboxGeneration=String(h),a.srcdoc=n.
|
|
1
|
+
const e=require("./errors.cjs"),t=require("./_policy.cjs"),n=require("./_document.cjs");require("./_dev.cjs");const r=require("./_protocol.cjs");var i=5e3;function a(a,o={}){let s=t.normalizeSandboxOptions(o),c=r.createChannel(),l={...s.namedStyles},u=new Set,d=new AbortController,f=null,p=!1,m=!1,h=0,g=null,_=null,v,y=new Promise(e=>{v=e});function b(){return{channel:c,generation:h}}function x(){g!==null&&(clearTimeout(g),g=null)}function S(){x(),_?.resolve(),_=null,m=!1}function C(e){for(let t of u)t(e)}function w(e){if(!f||e.source!==f.contentWindow)return;let t=b();if(r.isProtocolMessage(e.data,t))switch(e.data.type){case r.MSG_CUSTOM:typeof e.data.event==`string`&&C({detail:e.data.detail,event:e.data.event,type:r.MSG_CUSTOM});break;case r.MSG_ERROR:typeof e.data.message==`string`&&C({message:e.data.message,...typeof e.data.stack==`string`?{stack:e.data.stack}:{},type:r.MSG_ERROR});break;case r.MSG_READY:S(),v(),m=!0;break;case r.MSG_RESIZE:typeof e.data.height==`number`&&Number.isFinite(e.data.height)&&e.data.height>=0&&C({height:e.data.height,type:r.MSG_RESIZE})}}function T(){return f||(f=document.createElement(`iframe`),f.setAttribute(`sandbox`,`allow-scripts`),f.setAttribute(`referrerpolicy`,`no-referrer`),f.dataset.sandboxChannel=c,a.appendChild(f),window.addEventListener(`message`,w),f)}function E(){p||(p=!0,S(),d.abort(),v(),f&&=(window.removeEventListener(`message`,w),f.remove(),null),u.clear())}function D(e){return p?()=>{}:(u.add(e),()=>u.delete(e))}function O(t,r){if(p||r?.signal?.aborted)return Promise.resolve();t.trim(),S(),h+=1;let a=T(),o=b(),c={...s,namedStyles:{...l}};a.dataset.sandboxGeneration=String(h),a.srcdoc=n.buildDocumentFromOptions(t,c,o);let u=new Promise((e,t)=>{_={reject:t,resolve:e}});return g=setTimeout(()=>{_&&(_.reject(new e.SandboxTimeoutError(`render() did not receive a 'ready' signal from the sandbox document within ${i}ms. The document is likely missing the bridge script — use buildDocument() to generate documents that include it.`)),_=null,g=null)},i),u}function k(e){f?.contentWindow?.postMessage(r.envelope(b(),e),`*`)}function A(e){p||!m||!f?.contentWindow||k({html:e,type:r.MSG_HTML_REPLACE})}function j(e,t){p||f?.contentWindow&&k({key:e,type:r.MSG_STATE_UPDATE,value:t})}function M(e){p||f?.contentWindow&&k({record:e,type:r.MSG_STATE_UPDATE_ALL})}function N(e,t){p||(l[e]=t,m&&f?.contentWindow&&k({css:t,id:e,type:r.MSG_STYLE_PATCH}))}return{get disposalSignal(){return d.signal},dispose:E,get disposed(){return p},onMessage:D,ready:y,render:O,replaceBody:A,setState:j,setStateAll:M,[Symbol.dispose](){E()},updateStyle:N}}exports.createSandbox=a;
|
|
2
2
|
//# sourceMappingURL=_runtime.cjs.map
|
package/dist/_runtime.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_runtime.cjs","names":[],"sources":["../src/_runtime.ts"],"sourcesContent":["import type { SandboxHandle, SandboxMessage, SandboxOptions, Unsubscribe } from './types.js';\n\nimport { devOnly, warn } from './_dev.js';\nimport { buildRuntimeDocument } from './_document.js';\nimport { normalizeSandboxOptions } from './_policy.js';\nimport {\n createChannel,\n envelope,\n isProtocolMessage,\n MSG_CUSTOM,\n MSG_ERROR,\n MSG_HTML_REPLACE,\n MSG_READY,\n MSG_RESIZE,\n MSG_STATE_UPDATE,\n MSG_STATE_UPDATE_ALL,\n MSG_STYLE_PATCH,\n type BridgeBootstrap,\n} from './_protocol.js';\nimport { SandboxTimeoutError } from './errors.js';\n\nconst READY_TIMEOUT_MS = 5000;\n\nexport function createSandbox(container: HTMLElement, options: SandboxOptions = {}): SandboxHandle {\n const normalized = normalizeSandboxOptions(options);\n const channel = createChannel();\n const namedStyles: Record<string, string> = { ...normalized.namedStyles };\n const listeners = new Set<(message: SandboxMessage) => void>();\n const controller = new AbortController();\n let iframe: HTMLIFrameElement | null = null;\n let disposed = false;\n let bridgeReady = false;\n let generation = 0;\n let readyTimeout: ReturnType<typeof setTimeout> | null = null;\n let currentRender: { reject: (error: unknown) => void; resolve: () => void } | null = null;\n\n let resolveReady!: () => void;\n const ready = new Promise<void>((resolve) => {\n resolveReady = resolve;\n });\n\n function currentBootstrap(): BridgeBootstrap {\n return { channel, generation };\n }\n\n function clearReadyTimeout(): void {\n if (readyTimeout === null) return;\n\n clearTimeout(readyTimeout);\n readyTimeout = null;\n }\n\n function supersedePendingRender(): void {\n clearReadyTimeout();\n currentRender?.resolve();\n currentRender = null;\n bridgeReady = false;\n }\n\n function broadcast(message: SandboxMessage): void {\n for (const listener of listeners) listener(message);\n }\n\n function handleMessage(event: MessageEvent): void {\n if (!iframe || event.source !== iframe.contentWindow) return;\n\n const bootstrap = currentBootstrap();\n\n if (!isProtocolMessage(event.data, bootstrap)) return;\n\n switch (event.data.type) {\n case MSG_CUSTOM:\n if (typeof event.data.event === 'string') {\n broadcast({ detail: event.data.detail, event: event.data.event, type: MSG_CUSTOM });\n }\n\n break;\n case MSG_ERROR:\n if (typeof event.data.message === 'string') {\n broadcast({\n message: event.data.message,\n ...(typeof event.data.stack === 'string' ? { stack: event.data.stack } : {}),\n type: MSG_ERROR,\n });\n }\n\n break;\n case MSG_READY:\n supersedePendingRender();\n resolveReady();\n bridgeReady = true;\n break;\n case MSG_RESIZE:\n if (typeof event.data.height === 'number' && Number.isFinite(event.data.height) && event.data.height >= 0) {\n broadcast({ height: event.data.height, type: MSG_RESIZE });\n }\n\n break;\n }\n }\n\n function ensureIframe(): HTMLIFrameElement {\n if (iframe) return iframe;\n\n iframe = document.createElement('iframe');\n iframe.setAttribute('sandbox', 'allow-scripts');\n iframe.setAttribute('referrerpolicy', 'no-referrer');\n iframe.dataset.sandboxChannel = channel;\n container.appendChild(iframe);\n window.addEventListener('message', handleMessage);\n\n return iframe;\n }\n\n function dispose(): void {\n if (disposed) return;\n\n disposed = true;\n supersedePendingRender();\n controller.abort();\n resolveReady();\n\n if (iframe) {\n window.removeEventListener('message', handleMessage);\n iframe.remove();\n iframe = null;\n }\n\n listeners.clear();\n }\n\n function onMessage(handler: (message: SandboxMessage) => void): Unsubscribe {\n if (disposed) {\n warn('onMessage() called on a disposed sandbox — handler will never fire.');\n\n return () => {};\n }\n\n listeners.add(handler);\n\n return () => listeners.delete(handler);\n }\n\n function render(html: string, renderOptions?: { signal?: AbortSignal }): Promise<void> {\n if (disposed) {\n warn('render() called on a disposed sandbox.');\n\n return Promise.resolve();\n }\n\n if (renderOptions?.signal?.aborted) return Promise.resolve();\n\n if (!html.trim()) warn('render() called with empty HTML.');\n\n supersedePendingRender();\n generation += 1;\n\n const current = ensureIframe();\n const bootstrap = currentBootstrap();\n const documentOptions = { ...normalized, namedStyles: { ...namedStyles } };\n\n current.dataset.sandboxGeneration = String(generation);\n current.srcdoc = buildRuntimeDocument(html, documentOptions, bootstrap);\n\n const promise = new Promise<void>((resolve, reject) => {\n currentRender = { reject, resolve };\n });\n\n readyTimeout = setTimeout(() => {\n if (!currentRender) return;\n\n currentRender.reject(\n new SandboxTimeoutError(\n `render() did not receive a 'ready' signal from the sandbox document within ${READY_TIMEOUT_MS}ms. ` +\n 'The document is likely missing the bridge script — use buildDocument() to generate documents that include it.',\n ),\n );\n currentRender = null;\n readyTimeout = null;\n }, READY_TIMEOUT_MS);\n\n return promise;\n }\n\n function send(message: Record<string, unknown>): void {\n iframe?.contentWindow?.postMessage(envelope(currentBootstrap(), message), '*');\n }\n\n function replaceBody(html: string): void {\n if (disposed) {\n warn('replaceBody() called on a disposed sandbox.');\n\n return;\n }\n\n if (!bridgeReady || !iframe?.contentWindow) {\n warn('replaceBody() called before render() has resolved — bridge is not ready. Await render() first.');\n\n return;\n }\n\n send({ html, type: MSG_HTML_REPLACE });\n }\n\n function setState(key: string, value: unknown): void {\n if (disposed) {\n warn('setState() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setState() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setState() called before ready — state update may be lost. Await render() first.');\n }\n\n send({ key, type: MSG_STATE_UPDATE, value });\n }\n\n function setStateAll(record: Record<string, unknown>): void {\n if (disposed) {\n warn('setStateAll() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setStateAll() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setStateAll() called before ready — state updates may be lost. Await render() first.');\n }\n\n send({ record, type: MSG_STATE_UPDATE_ALL });\n }\n\n function updateStyle(id: string, css: string): void {\n if (disposed) return;\n\n devOnly(() => {\n if (!(id in namedStyles)) {\n warn(`updateStyle('${id}', …) — '${id}' is not a known namedStyles key.`);\n }\n });\n\n namedStyles[id] = css;\n\n if (bridgeReady && iframe?.contentWindow) send({ css, id, type: MSG_STYLE_PATCH });\n }\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n onMessage,\n ready,\n render,\n replaceBody,\n setState,\n setStateAll,\n [Symbol.dispose]() {\n dispose();\n },\n updateStyle,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"_runtime.cjs","names":[],"sources":["../src/_runtime.ts"],"sourcesContent":["import { devOnly, warn } from './_dev.js';\nimport { buildDocumentFromOptions } from './_document.js';\nimport { normalizeSandboxOptions } from './_policy.js';\nimport {\n type BridgeBootstrap,\n createChannel,\n envelope,\n isProtocolMessage,\n MSG_CUSTOM,\n MSG_ERROR,\n MSG_HTML_REPLACE,\n MSG_READY,\n MSG_RESIZE,\n MSG_STATE_UPDATE,\n MSG_STATE_UPDATE_ALL,\n MSG_STYLE_PATCH,\n} from './_protocol.js';\nimport { SandboxTimeoutError } from './errors.js';\nimport type { SandboxHandle, SandboxMessage, SandboxOptions, Unsubscribe } from './types.js';\n\nconst READY_TIMEOUT_MS = 5000;\n\nexport function createSandbox(container: HTMLElement, options: SandboxOptions = {}): SandboxHandle {\n const normalized = normalizeSandboxOptions(options);\n const channel = createChannel();\n const namedStyles: Record<string, string> = { ...normalized.namedStyles };\n const listeners = new Set<(message: SandboxMessage) => void>();\n const controller = new AbortController();\n let iframe: HTMLIFrameElement | null = null;\n let disposed = false;\n let bridgeReady = false;\n let generation = 0;\n let readyTimeout: ReturnType<typeof setTimeout> | null = null;\n let currentRender: { reject: (error: unknown) => void; resolve: () => void } | null = null;\n\n let resolveReady!: () => void;\n const ready = new Promise<void>((resolve) => {\n resolveReady = resolve;\n });\n\n function currentBootstrap(): BridgeBootstrap {\n return { channel, generation };\n }\n\n function clearReadyTimeout(): void {\n if (readyTimeout === null) return;\n\n clearTimeout(readyTimeout);\n readyTimeout = null;\n }\n\n function supersedePendingRender(): void {\n clearReadyTimeout();\n currentRender?.resolve();\n currentRender = null;\n bridgeReady = false;\n }\n\n function broadcast(message: SandboxMessage): void {\n for (const listener of listeners) listener(message);\n }\n\n function handleMessage(event: MessageEvent): void {\n if (!iframe || event.source !== iframe.contentWindow) return;\n\n const bootstrap = currentBootstrap();\n\n if (!isProtocolMessage(event.data, bootstrap)) return;\n\n switch (event.data.type) {\n case MSG_CUSTOM:\n if (typeof event.data.event === 'string') {\n broadcast({ detail: event.data.detail, event: event.data.event, type: MSG_CUSTOM });\n }\n\n break;\n case MSG_ERROR:\n if (typeof event.data.message === 'string') {\n broadcast({\n message: event.data.message,\n ...(typeof event.data.stack === 'string' ? { stack: event.data.stack } : {}),\n type: MSG_ERROR,\n });\n }\n\n break;\n case MSG_READY:\n supersedePendingRender();\n resolveReady();\n bridgeReady = true;\n break;\n case MSG_RESIZE:\n if (typeof event.data.height === 'number' && Number.isFinite(event.data.height) && event.data.height >= 0) {\n broadcast({ height: event.data.height, type: MSG_RESIZE });\n }\n\n break;\n }\n }\n\n function ensureIframe(): HTMLIFrameElement {\n if (iframe) return iframe;\n\n iframe = document.createElement('iframe');\n iframe.setAttribute('sandbox', 'allow-scripts');\n iframe.setAttribute('referrerpolicy', 'no-referrer');\n iframe.dataset.sandboxChannel = channel;\n container.appendChild(iframe);\n window.addEventListener('message', handleMessage);\n\n return iframe;\n }\n\n function dispose(): void {\n if (disposed) return;\n\n disposed = true;\n supersedePendingRender();\n controller.abort();\n resolveReady();\n\n if (iframe) {\n window.removeEventListener('message', handleMessage);\n iframe.remove();\n iframe = null;\n }\n\n listeners.clear();\n }\n\n function onMessage(handler: (message: SandboxMessage) => void): Unsubscribe {\n if (disposed) {\n warn('onMessage() called on a disposed sandbox — handler will never fire.');\n\n return () => {};\n }\n\n listeners.add(handler);\n\n return () => listeners.delete(handler);\n }\n\n function render(html: string, renderOptions?: { signal?: AbortSignal }): Promise<void> {\n if (disposed) {\n warn('render() called on a disposed sandbox.');\n\n return Promise.resolve();\n }\n\n if (renderOptions?.signal?.aborted) return Promise.resolve();\n\n if (!html.trim()) warn('render() called with empty HTML.');\n\n supersedePendingRender();\n generation += 1;\n\n const current = ensureIframe();\n const bootstrap = currentBootstrap();\n const documentOptions = { ...normalized, namedStyles: { ...namedStyles } };\n\n current.dataset.sandboxGeneration = String(generation);\n current.srcdoc = buildDocumentFromOptions(html, documentOptions, bootstrap);\n\n const promise = new Promise<void>((resolve, reject) => {\n currentRender = { reject, resolve };\n });\n\n readyTimeout = setTimeout(() => {\n if (!currentRender) return;\n\n currentRender.reject(\n new SandboxTimeoutError(\n `render() did not receive a 'ready' signal from the sandbox document within ${READY_TIMEOUT_MS}ms. ` +\n 'The document is likely missing the bridge script — use buildDocument() to generate documents that include it.',\n ),\n );\n currentRender = null;\n readyTimeout = null;\n }, READY_TIMEOUT_MS);\n\n return promise;\n }\n\n function send(message: Record<string, unknown>): void {\n iframe?.contentWindow?.postMessage(envelope(currentBootstrap(), message), '*');\n }\n\n function replaceBody(html: string): void {\n if (disposed) {\n warn('replaceBody() called on a disposed sandbox.');\n\n return;\n }\n\n if (!bridgeReady || !iframe?.contentWindow) {\n warn('replaceBody() called before render() has resolved — bridge is not ready. Await render() first.');\n\n return;\n }\n\n send({ html, type: MSG_HTML_REPLACE });\n }\n\n function setState(key: string, value: unknown): void {\n if (disposed) {\n warn('setState() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setState() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setState() called before ready — state update may be lost. Await render() first.');\n }\n\n send({ key, type: MSG_STATE_UPDATE, value });\n }\n\n function setStateAll(record: Record<string, unknown>): void {\n if (disposed) {\n warn('setStateAll() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setStateAll() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setStateAll() called before ready — state updates may be lost. Await render() first.');\n }\n\n send({ record, type: MSG_STATE_UPDATE_ALL });\n }\n\n function updateStyle(id: string, css: string): void {\n if (disposed) return;\n\n devOnly(() => {\n if (!(id in namedStyles)) {\n warn(`updateStyle('${id}', …) — '${id}' is not a known namedStyles key.`);\n }\n });\n\n namedStyles[id] = css;\n\n if (bridgeReady && iframe?.contentWindow) send({ css, id, type: MSG_STYLE_PATCH });\n }\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n onMessage,\n ready,\n render,\n replaceBody,\n setState,\n setStateAll,\n [Symbol.dispose]() {\n dispose();\n },\n updateStyle,\n };\n}\n"],"mappings":"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"}
|
package/dist/_runtime.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_runtime.d.ts","sourceRoot":"","sources":["../src/_runtime.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"_runtime.d.ts","sourceRoot":"","sources":["../src/_runtime.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAkB,cAAc,EAAe,MAAM,YAAY,CAAC;AAI7F,wBAAgB,aAAa,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,GAAE,cAAmB,GAAG,aAAa,CA8PjG"}
|
package/dist/_runtime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SandboxTimeoutError as e } from "./errors.js";
|
|
2
2
|
import { normalizeSandboxOptions as t } from "./_policy.js";
|
|
3
|
-
import {
|
|
3
|
+
import { buildDocumentFromOptions as n } from "./_document.js";
|
|
4
4
|
import "./_dev.js";
|
|
5
5
|
import { MSG_CUSTOM as r, MSG_ERROR as i, MSG_HTML_REPLACE as a, MSG_READY as o, MSG_RESIZE as s, MSG_STATE_UPDATE as c, MSG_STATE_UPDATE_ALL as l, MSG_STYLE_PATCH as u, createChannel as d, envelope as f, isProtocolMessage as p } from "./_protocol.js";
|
|
6
6
|
//#region src/_runtime.ts
|
package/dist/_runtime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"_runtime.js","names":[],"sources":["../src/_runtime.ts"],"sourcesContent":["import type { SandboxHandle, SandboxMessage, SandboxOptions, Unsubscribe } from './types.js';\n\nimport { devOnly, warn } from './_dev.js';\nimport { buildRuntimeDocument } from './_document.js';\nimport { normalizeSandboxOptions } from './_policy.js';\nimport {\n createChannel,\n envelope,\n isProtocolMessage,\n MSG_CUSTOM,\n MSG_ERROR,\n MSG_HTML_REPLACE,\n MSG_READY,\n MSG_RESIZE,\n MSG_STATE_UPDATE,\n MSG_STATE_UPDATE_ALL,\n MSG_STYLE_PATCH,\n type BridgeBootstrap,\n} from './_protocol.js';\nimport { SandboxTimeoutError } from './errors.js';\n\nconst READY_TIMEOUT_MS = 5000;\n\nexport function createSandbox(container: HTMLElement, options: SandboxOptions = {}): SandboxHandle {\n const normalized = normalizeSandboxOptions(options);\n const channel = createChannel();\n const namedStyles: Record<string, string> = { ...normalized.namedStyles };\n const listeners = new Set<(message: SandboxMessage) => void>();\n const controller = new AbortController();\n let iframe: HTMLIFrameElement | null = null;\n let disposed = false;\n let bridgeReady = false;\n let generation = 0;\n let readyTimeout: ReturnType<typeof setTimeout> | null = null;\n let currentRender: { reject: (error: unknown) => void; resolve: () => void } | null = null;\n\n let resolveReady!: () => void;\n const ready = new Promise<void>((resolve) => {\n resolveReady = resolve;\n });\n\n function currentBootstrap(): BridgeBootstrap {\n return { channel, generation };\n }\n\n function clearReadyTimeout(): void {\n if (readyTimeout === null) return;\n\n clearTimeout(readyTimeout);\n readyTimeout = null;\n }\n\n function supersedePendingRender(): void {\n clearReadyTimeout();\n currentRender?.resolve();\n currentRender = null;\n bridgeReady = false;\n }\n\n function broadcast(message: SandboxMessage): void {\n for (const listener of listeners) listener(message);\n }\n\n function handleMessage(event: MessageEvent): void {\n if (!iframe || event.source !== iframe.contentWindow) return;\n\n const bootstrap = currentBootstrap();\n\n if (!isProtocolMessage(event.data, bootstrap)) return;\n\n switch (event.data.type) {\n case MSG_CUSTOM:\n if (typeof event.data.event === 'string') {\n broadcast({ detail: event.data.detail, event: event.data.event, type: MSG_CUSTOM });\n }\n\n break;\n case MSG_ERROR:\n if (typeof event.data.message === 'string') {\n broadcast({\n message: event.data.message,\n ...(typeof event.data.stack === 'string' ? { stack: event.data.stack } : {}),\n type: MSG_ERROR,\n });\n }\n\n break;\n case MSG_READY:\n supersedePendingRender();\n resolveReady();\n bridgeReady = true;\n break;\n case MSG_RESIZE:\n if (typeof event.data.height === 'number' && Number.isFinite(event.data.height) && event.data.height >= 0) {\n broadcast({ height: event.data.height, type: MSG_RESIZE });\n }\n\n break;\n }\n }\n\n function ensureIframe(): HTMLIFrameElement {\n if (iframe) return iframe;\n\n iframe = document.createElement('iframe');\n iframe.setAttribute('sandbox', 'allow-scripts');\n iframe.setAttribute('referrerpolicy', 'no-referrer');\n iframe.dataset.sandboxChannel = channel;\n container.appendChild(iframe);\n window.addEventListener('message', handleMessage);\n\n return iframe;\n }\n\n function dispose(): void {\n if (disposed) return;\n\n disposed = true;\n supersedePendingRender();\n controller.abort();\n resolveReady();\n\n if (iframe) {\n window.removeEventListener('message', handleMessage);\n iframe.remove();\n iframe = null;\n }\n\n listeners.clear();\n }\n\n function onMessage(handler: (message: SandboxMessage) => void): Unsubscribe {\n if (disposed) {\n warn('onMessage() called on a disposed sandbox — handler will never fire.');\n\n return () => {};\n }\n\n listeners.add(handler);\n\n return () => listeners.delete(handler);\n }\n\n function render(html: string, renderOptions?: { signal?: AbortSignal }): Promise<void> {\n if (disposed) {\n warn('render() called on a disposed sandbox.');\n\n return Promise.resolve();\n }\n\n if (renderOptions?.signal?.aborted) return Promise.resolve();\n\n if (!html.trim()) warn('render() called with empty HTML.');\n\n supersedePendingRender();\n generation += 1;\n\n const current = ensureIframe();\n const bootstrap = currentBootstrap();\n const documentOptions = { ...normalized, namedStyles: { ...namedStyles } };\n\n current.dataset.sandboxGeneration = String(generation);\n current.srcdoc = buildRuntimeDocument(html, documentOptions, bootstrap);\n\n const promise = new Promise<void>((resolve, reject) => {\n currentRender = { reject, resolve };\n });\n\n readyTimeout = setTimeout(() => {\n if (!currentRender) return;\n\n currentRender.reject(\n new SandboxTimeoutError(\n `render() did not receive a 'ready' signal from the sandbox document within ${READY_TIMEOUT_MS}ms. ` +\n 'The document is likely missing the bridge script — use buildDocument() to generate documents that include it.',\n ),\n );\n currentRender = null;\n readyTimeout = null;\n }, READY_TIMEOUT_MS);\n\n return promise;\n }\n\n function send(message: Record<string, unknown>): void {\n iframe?.contentWindow?.postMessage(envelope(currentBootstrap(), message), '*');\n }\n\n function replaceBody(html: string): void {\n if (disposed) {\n warn('replaceBody() called on a disposed sandbox.');\n\n return;\n }\n\n if (!bridgeReady || !iframe?.contentWindow) {\n warn('replaceBody() called before render() has resolved — bridge is not ready. Await render() first.');\n\n return;\n }\n\n send({ html, type: MSG_HTML_REPLACE });\n }\n\n function setState(key: string, value: unknown): void {\n if (disposed) {\n warn('setState() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setState() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setState() called before ready — state update may be lost. Await render() first.');\n }\n\n send({ key, type: MSG_STATE_UPDATE, value });\n }\n\n function setStateAll(record: Record<string, unknown>): void {\n if (disposed) {\n warn('setStateAll() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setStateAll() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setStateAll() called before ready — state updates may be lost. Await render() first.');\n }\n\n send({ record, type: MSG_STATE_UPDATE_ALL });\n }\n\n function updateStyle(id: string, css: string): void {\n if (disposed) return;\n\n devOnly(() => {\n if (!(id in namedStyles)) {\n warn(`updateStyle('${id}', …) — '${id}' is not a known namedStyles key.`);\n }\n });\n\n namedStyles[id] = css;\n\n if (bridgeReady && iframe?.contentWindow) send({ css, id, type: MSG_STYLE_PATCH });\n }\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n onMessage,\n ready,\n render,\n replaceBody,\n setState,\n setStateAll,\n [Symbol.dispose]() {\n dispose();\n },\n updateStyle,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"_runtime.js","names":[],"sources":["../src/_runtime.ts"],"sourcesContent":["import { devOnly, warn } from './_dev.js';\nimport { buildDocumentFromOptions } from './_document.js';\nimport { normalizeSandboxOptions } from './_policy.js';\nimport {\n type BridgeBootstrap,\n createChannel,\n envelope,\n isProtocolMessage,\n MSG_CUSTOM,\n MSG_ERROR,\n MSG_HTML_REPLACE,\n MSG_READY,\n MSG_RESIZE,\n MSG_STATE_UPDATE,\n MSG_STATE_UPDATE_ALL,\n MSG_STYLE_PATCH,\n} from './_protocol.js';\nimport { SandboxTimeoutError } from './errors.js';\nimport type { SandboxHandle, SandboxMessage, SandboxOptions, Unsubscribe } from './types.js';\n\nconst READY_TIMEOUT_MS = 5000;\n\nexport function createSandbox(container: HTMLElement, options: SandboxOptions = {}): SandboxHandle {\n const normalized = normalizeSandboxOptions(options);\n const channel = createChannel();\n const namedStyles: Record<string, string> = { ...normalized.namedStyles };\n const listeners = new Set<(message: SandboxMessage) => void>();\n const controller = new AbortController();\n let iframe: HTMLIFrameElement | null = null;\n let disposed = false;\n let bridgeReady = false;\n let generation = 0;\n let readyTimeout: ReturnType<typeof setTimeout> | null = null;\n let currentRender: { reject: (error: unknown) => void; resolve: () => void } | null = null;\n\n let resolveReady!: () => void;\n const ready = new Promise<void>((resolve) => {\n resolveReady = resolve;\n });\n\n function currentBootstrap(): BridgeBootstrap {\n return { channel, generation };\n }\n\n function clearReadyTimeout(): void {\n if (readyTimeout === null) return;\n\n clearTimeout(readyTimeout);\n readyTimeout = null;\n }\n\n function supersedePendingRender(): void {\n clearReadyTimeout();\n currentRender?.resolve();\n currentRender = null;\n bridgeReady = false;\n }\n\n function broadcast(message: SandboxMessage): void {\n for (const listener of listeners) listener(message);\n }\n\n function handleMessage(event: MessageEvent): void {\n if (!iframe || event.source !== iframe.contentWindow) return;\n\n const bootstrap = currentBootstrap();\n\n if (!isProtocolMessage(event.data, bootstrap)) return;\n\n switch (event.data.type) {\n case MSG_CUSTOM:\n if (typeof event.data.event === 'string') {\n broadcast({ detail: event.data.detail, event: event.data.event, type: MSG_CUSTOM });\n }\n\n break;\n case MSG_ERROR:\n if (typeof event.data.message === 'string') {\n broadcast({\n message: event.data.message,\n ...(typeof event.data.stack === 'string' ? { stack: event.data.stack } : {}),\n type: MSG_ERROR,\n });\n }\n\n break;\n case MSG_READY:\n supersedePendingRender();\n resolveReady();\n bridgeReady = true;\n break;\n case MSG_RESIZE:\n if (typeof event.data.height === 'number' && Number.isFinite(event.data.height) && event.data.height >= 0) {\n broadcast({ height: event.data.height, type: MSG_RESIZE });\n }\n\n break;\n }\n }\n\n function ensureIframe(): HTMLIFrameElement {\n if (iframe) return iframe;\n\n iframe = document.createElement('iframe');\n iframe.setAttribute('sandbox', 'allow-scripts');\n iframe.setAttribute('referrerpolicy', 'no-referrer');\n iframe.dataset.sandboxChannel = channel;\n container.appendChild(iframe);\n window.addEventListener('message', handleMessage);\n\n return iframe;\n }\n\n function dispose(): void {\n if (disposed) return;\n\n disposed = true;\n supersedePendingRender();\n controller.abort();\n resolveReady();\n\n if (iframe) {\n window.removeEventListener('message', handleMessage);\n iframe.remove();\n iframe = null;\n }\n\n listeners.clear();\n }\n\n function onMessage(handler: (message: SandboxMessage) => void): Unsubscribe {\n if (disposed) {\n warn('onMessage() called on a disposed sandbox — handler will never fire.');\n\n return () => {};\n }\n\n listeners.add(handler);\n\n return () => listeners.delete(handler);\n }\n\n function render(html: string, renderOptions?: { signal?: AbortSignal }): Promise<void> {\n if (disposed) {\n warn('render() called on a disposed sandbox.');\n\n return Promise.resolve();\n }\n\n if (renderOptions?.signal?.aborted) return Promise.resolve();\n\n if (!html.trim()) warn('render() called with empty HTML.');\n\n supersedePendingRender();\n generation += 1;\n\n const current = ensureIframe();\n const bootstrap = currentBootstrap();\n const documentOptions = { ...normalized, namedStyles: { ...namedStyles } };\n\n current.dataset.sandboxGeneration = String(generation);\n current.srcdoc = buildDocumentFromOptions(html, documentOptions, bootstrap);\n\n const promise = new Promise<void>((resolve, reject) => {\n currentRender = { reject, resolve };\n });\n\n readyTimeout = setTimeout(() => {\n if (!currentRender) return;\n\n currentRender.reject(\n new SandboxTimeoutError(\n `render() did not receive a 'ready' signal from the sandbox document within ${READY_TIMEOUT_MS}ms. ` +\n 'The document is likely missing the bridge script — use buildDocument() to generate documents that include it.',\n ),\n );\n currentRender = null;\n readyTimeout = null;\n }, READY_TIMEOUT_MS);\n\n return promise;\n }\n\n function send(message: Record<string, unknown>): void {\n iframe?.contentWindow?.postMessage(envelope(currentBootstrap(), message), '*');\n }\n\n function replaceBody(html: string): void {\n if (disposed) {\n warn('replaceBody() called on a disposed sandbox.');\n\n return;\n }\n\n if (!bridgeReady || !iframe?.contentWindow) {\n warn('replaceBody() called before render() has resolved — bridge is not ready. Await render() first.');\n\n return;\n }\n\n send({ html, type: MSG_HTML_REPLACE });\n }\n\n function setState(key: string, value: unknown): void {\n if (disposed) {\n warn('setState() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setState() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setState() called before ready — state update may be lost. Await render() first.');\n }\n\n send({ key, type: MSG_STATE_UPDATE, value });\n }\n\n function setStateAll(record: Record<string, unknown>): void {\n if (disposed) {\n warn('setStateAll() called on a disposed sandbox.');\n\n return;\n }\n\n if (!iframe?.contentWindow) {\n warn('setStateAll() called before render() — sandbox has no document yet.');\n\n return;\n }\n\n if (!bridgeReady) {\n warn('setStateAll() called before ready — state updates may be lost. Await render() first.');\n }\n\n send({ record, type: MSG_STATE_UPDATE_ALL });\n }\n\n function updateStyle(id: string, css: string): void {\n if (disposed) return;\n\n devOnly(() => {\n if (!(id in namedStyles)) {\n warn(`updateStyle('${id}', …) — '${id}' is not a known namedStyles key.`);\n }\n });\n\n namedStyles[id] = css;\n\n if (bridgeReady && iframe?.contentWindow) send({ css, id, type: MSG_STYLE_PATCH });\n }\n\n return {\n get disposalSignal() {\n return controller.signal;\n },\n dispose,\n get disposed() {\n return disposed;\n },\n onMessage,\n ready,\n render,\n replaceBody,\n setState,\n setStateAll,\n [Symbol.dispose]() {\n dispose();\n },\n updateStyle,\n };\n}\n"],"mappings":"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"}
|
package/dist/errors.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e=class
|
|
1
|
+
var e=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},t=class extends e{},n=class extends e{};exports.SandboxConfigurationError=n,exports.SandboxError=e,exports.SandboxTimeoutError=t;
|
|
2
2
|
//# sourceMappingURL=errors.cjs.map
|
package/dist/errors.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sandbox errors. */\nexport class SandboxError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n
|
|
1
|
+
{"version":3,"file":"errors.cjs","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sandbox errors. */\nexport class SandboxError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when render() does not receive a 'ready' signal from the sandbox document\n * within the timeout window. The document is most likely missing the bridge script —\n * use buildDocument() to generate documents that include it.\n */\nexport class SandboxTimeoutError extends SandboxError {}\n\n/** Thrown when Sandbox configuration cannot produce a valid document or CSP policy. */\nexport class SandboxConfigurationError extends SandboxError {}\n"],"mappings":"AACA,IAAa,EAAb,cAAkC,KAAM,CACtC,YAAY,EAAiB,EAAqB,CAChD,MAAM,EAAS,CAAI,EACnB,KAAK,KAAO,WAAW,KACvB,OAAO,eAAe,KAAM,WAAW,SAAS,CAClD,CACF,EAOa,EAAb,cAAyC,CAAa,CAAC,EAG1C,EAAb,cAA+C,CAAa,CAAC"}
|
package/dist/errors.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
/** Base class for all sandbox errors. */
|
|
2
2
|
export declare class SandboxError extends Error {
|
|
3
3
|
constructor(message: string, opts?: ErrorOptions);
|
|
4
|
-
static is(err: unknown): err is SandboxError;
|
|
5
4
|
}
|
|
6
5
|
/**
|
|
7
6
|
* Thrown when render() does not receive a 'ready' signal from the sandbox document
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,qBAAa,YAAa,SAAQ,KAAK;gBACzB,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,YAAY;CAKjD;AAED;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;CAAG;AAExD,uFAAuF;AACvF,qBAAa,yBAA0B,SAAQ,YAAY;CAAG"}
|
package/dist/errors.js
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
//#region src/errors.ts
|
|
2
|
-
var e = class
|
|
2
|
+
var e = class extends Error {
|
|
3
3
|
constructor(e, t) {
|
|
4
4
|
super(e, t), this.name = new.target.name, Object.setPrototypeOf(this, new.target.prototype);
|
|
5
5
|
}
|
|
6
|
-
static is(t) {
|
|
7
|
-
return t instanceof e;
|
|
8
|
-
}
|
|
9
6
|
}, t = class extends e {}, n = class extends e {};
|
|
10
7
|
//#endregion
|
|
11
8
|
export { n as SandboxConfigurationError, e as SandboxError, t as SandboxTimeoutError };
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sandbox errors. */\nexport class SandboxError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/** Base class for all sandbox errors. */\nexport class SandboxError extends Error {\n constructor(message: string, opts?: ErrorOptions) {\n super(message, opts);\n this.name = new.target.name;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n/**\n * Thrown when render() does not receive a 'ready' signal from the sandbox document\n * within the timeout window. The document is most likely missing the bridge script —\n * use buildDocument() to generate documents that include it.\n */\nexport class SandboxTimeoutError extends SandboxError {}\n\n/** Thrown when Sandbox configuration cannot produce a valid document or CSP policy. */\nexport class SandboxConfigurationError extends SandboxError {}\n"],"mappings":";AACA,IAAa,IAAb,cAAkC,MAAM;CACtC,YAAY,GAAiB,GAAqB;EAGhD,AAFA,MAAM,GAAS,CAAI,GACnB,KAAK,OAAO,WAAW,MACvB,OAAO,eAAe,MAAM,WAAW,SAAS;CAClD;AACF,GAOa,IAAb,cAAyC,EAAa,CAAC,GAG1C,IAAb,cAA+C,EAAa,CAAC"}
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./errors.cjs"),t=require("./_policy.cjs"),n=require("./_document.cjs"),r=require("./_runtime.cjs");exports.SandboxConfigurationError=e.SandboxConfigurationError,exports.SandboxError=e.SandboxError,exports.SandboxTimeoutError=e.SandboxTimeoutError,exports.buildCsp=t.buildCsp,exports.buildDocument=n.buildDocument,exports.createSandbox=r.createSandbox;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { buildDocument } from './_document.js';
|
|
2
|
+
export { buildCsp } from './_policy.js';
|
|
3
|
+
export { createSandbox } from './_runtime.js';
|
|
2
4
|
export { SandboxConfigurationError, SandboxError, SandboxTimeoutError } from './errors.js';
|
|
3
5
|
export type { SandboxBridge, SandboxHandle, SandboxMessage, SandboxOptions, SandboxStateUpdateDetail, Unsubscribe, } from './types.js';
|
|
4
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,yBAAyB,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,YAAY,EACV,aAAa,EACb,aAAa,EACb,cAAc,EACd,cAAc,EACd,wBAAwB,EACxB,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SandboxConfigurationError as e, SandboxError as t, SandboxTimeoutError as n } from "./errors.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
export { e as SandboxConfigurationError, t as SandboxError, n as SandboxTimeoutError,
|
|
2
|
+
import { buildCsp as r } from "./_policy.js";
|
|
3
|
+
import { buildDocument as i } from "./_document.js";
|
|
4
|
+
import { createSandbox as a } from "./_runtime.js";
|
|
5
|
+
export { e as SandboxConfigurationError, t as SandboxError, n as SandboxTimeoutError, r as buildCsp, i as buildDocument, a as createSandbox };
|
package/dist/sandbox.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});function e(e){return`
|
|
2
2
|
window.__sandboxChannel = ${JSON.stringify(e.channel)};
|
|
3
3
|
window.__sandboxGeneration = ${String(e.generation)};
|
|
4
4
|
const __sandboxChannel = window.__sandboxChannel;
|
|
@@ -63,24 +63,24 @@ if (typeof ResizeObserver !== 'undefined') {
|
|
|
63
63
|
post({ type: 'resize', height: h });
|
|
64
64
|
}).observe(document.body);
|
|
65
65
|
}
|
|
66
|
-
`.trim()}function m(e){return e.replace(/<\/style/gi,`\\3C /style`)}function
|
|
67
|
-
`),
|
|
68
|
-
`),
|
|
69
|
-
<html lang="${
|
|
66
|
+
`.trim()}var t=class extends Error{constructor(e,t){super(e,t),this.name=new.target.name,Object.setPrototypeOf(this,new.target.prototype)}},n=class extends t{},r=class extends t{},i=/^[A-Za-z][A-Za-z0-9_-]*$/,a=/^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8})*$/,o=/^[A-Za-z0-9+/_-]+={0,2}$/;function s(e,t){throw new r(`${e} is invalid: ${String(t)}`)}function c(e,t){let n;try{n=new URL(e)}catch{return s(t,e)}return n.protocol!==`http:`&&n.protocol!==`https:`||n.username||n.password||n.pathname!==`/`||n.search||n.hash?s(t,e):n.origin}function l(e,t){return(e??[]).map(e=>c(e,t))}function u(e){let t;try{t=new URL(e)}catch{return s(`scripts`,e)}return t.protocol!==`http:`&&t.protocol!==`https:`?s(`scripts`,e):t.href}function d(e){let t={};for(let[n,r]of Object.entries(e??{}))(!i.test(n)||typeof r!=`string`)&&s(`namedStyles`,n),t[n]=r;return t}function f(e={}){let t=e.lang??`en`;a.test(t)||s(`lang`,t),e.nonce!==void 0&&(!o.test(e.nonce)||e.nonce.length===0)&&s(`nonce`,e.nonce),e.title!==void 0&&typeof e.title!=`string`&&s(`title`,e.title);let n=(e.scripts??[]).map(u);return{allowedFontOrigins:l(e.allowedFontOrigins,`allowedFontOrigins`),allowedImageOrigins:l(e.allowedImageOrigins,`allowedImageOrigins`),allowedScriptOrigins:l(e.allowedScriptOrigins,`allowedScriptOrigins`),allowedStyleOrigins:l(e.allowedStyleOrigins,`allowedStyleOrigins`),lang:t,namedStyles:d(e.namedStyles),nonce:e.nonce,scripts:n,title:e.title??``}}function p(e){let t=[`'unsafe-inline'`,...e.nonce?[`'nonce-${e.nonce}'`]:[],...e.allowedScriptOrigins,...e.scripts.map(e=>new URL(e).origin)].join(` `),n=[`'unsafe-inline'`,...e.allowedStyleOrigins].join(` `),r=[`data:`,...e.allowedImageOrigins].join(` `),i=e.allowedFontOrigins.join(` `)||`'none'`;return[`default-src 'none'`,`script-src ${t}`,`style-src ${n}`,`img-src ${r}`,`font-src ${i}`,`connect-src 'none'`,`form-action 'none'`,`base-uri 'none'`].join(`; `)}function m(e={}){return p(f(e))}function h(e){return e.replace(/<\/style/gi,`\\3C /style`)}function g(e){return e.replace(/&/g,`&`).replace(/"/g,`"`).replace(/</g,`<`).replace(/>/g,`>`)}function _(e){return e.replace(/&/g,`&`).replace(/</g,`<`).replace(/>/g,`>`)}function v(t,n,r){let i=g(p(n)),a=Object.entries(n.namedStyles).map(([e,t])=>`<style id="${g(e)}">${h(t)}</style>`).join(`
|
|
67
|
+
`),o=n.scripts.map(e=>`<script crossorigin="anonymous" src="${g(e)}"><\/script>`).join(`
|
|
68
|
+
`),s=n.nonce?` nonce="${g(n.nonce)}"`:``,c=`<script${s}>window.__sandboxChannel=${JSON.stringify(r.channel)};window.__sandboxGeneration=${r.generation};<\/script>`;return`<!doctype html>
|
|
69
|
+
<html lang="${g(n.lang)}">
|
|
70
70
|
<head>
|
|
71
|
-
<meta http-equiv="Content-Security-Policy" content="${
|
|
72
|
-
${
|
|
71
|
+
<meta http-equiv="Content-Security-Policy" content="${i}">
|
|
72
|
+
${c}
|
|
73
73
|
<meta charset="utf-8">
|
|
74
74
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
75
|
-
<title>${
|
|
76
|
-
${
|
|
75
|
+
<title>${_(n.title)}</title>
|
|
76
|
+
${a}
|
|
77
77
|
</head>
|
|
78
78
|
<body>
|
|
79
|
-
${
|
|
80
|
-
${
|
|
81
|
-
<script${
|
|
82
|
-
${
|
|
79
|
+
${o}
|
|
80
|
+
${t}
|
|
81
|
+
<script${s}>
|
|
82
|
+
${e(r)}
|
|
83
83
|
<\/script>
|
|
84
84
|
</body>
|
|
85
|
-
</html>`}function
|
|
85
|
+
</html>`}function y(e,t={}){return v(e,f(t),{channel:``,generation:0})}var b=`custom`,x=`error`,S=`html-replace`,C=`ready`,w=`resize`,T=`state-update`,E=`state-update-all`,D=`style-patch`;function O(e,t){return typeof e==`object`&&!!e&&typeof e.channel==`string`&&e.channel===t.channel&&typeof e.generation==`number`&&e.generation===t.generation&&typeof e.type==`string`}function k(){if(typeof crypto.randomUUID==`function`)return crypto.randomUUID();let e=crypto.getRandomValues(new Uint32Array(4));return Array.from(e,e=>e.toString(16).padStart(8,`0`)).join(``)}function A(e,t){return{...t,channel:e.channel,generation:e.generation}}var j=5e3;function M(e,t={}){let r=f(t),i=k(),a={...r.namedStyles},o=new Set,s=new AbortController,c=null,l=!1,u=!1,d=0,p=null,m=null,h,g=new Promise(e=>{h=e});function _(){return{channel:i,generation:d}}function y(){p!==null&&(clearTimeout(p),p=null)}function M(){y(),m?.resolve(),m=null,u=!1}function N(e){for(let t of o)t(e)}function P(e){if(!c||e.source!==c.contentWindow)return;let t=_();if(O(e.data,t))switch(e.data.type){case b:typeof e.data.event==`string`&&N({detail:e.data.detail,event:e.data.event,type:b});break;case x:typeof e.data.message==`string`&&N({message:e.data.message,...typeof e.data.stack==`string`?{stack:e.data.stack}:{},type:x});break;case C:M(),h(),u=!0;break;case w:typeof e.data.height==`number`&&Number.isFinite(e.data.height)&&e.data.height>=0&&N({height:e.data.height,type:w})}}function F(){return c||(c=document.createElement(`iframe`),c.setAttribute(`sandbox`,`allow-scripts`),c.setAttribute(`referrerpolicy`,`no-referrer`),c.dataset.sandboxChannel=i,e.appendChild(c),window.addEventListener(`message`,P),c)}function I(){l||(l=!0,M(),s.abort(),h(),c&&=(window.removeEventListener(`message`,P),c.remove(),null),o.clear())}function L(e){return l?()=>{}:(o.add(e),()=>o.delete(e))}function R(e,t){if(l||t?.signal?.aborted)return Promise.resolve();e.trim(),M(),d+=1;let i=F(),o=_(),s={...r,namedStyles:{...a}};i.dataset.sandboxGeneration=String(d),i.srcdoc=v(e,s,o);let c=new Promise((e,t)=>{m={reject:t,resolve:e}});return p=setTimeout(()=>{m&&(m.reject(new n(`render() did not receive a 'ready' signal from the sandbox document within ${j}ms. The document is likely missing the bridge script — use buildDocument() to generate documents that include it.`)),m=null,p=null)},j),c}function z(e){c?.contentWindow?.postMessage(A(_(),e),`*`)}function B(e){l||!u||!c?.contentWindow||z({html:e,type:S})}function V(e,t){l||c?.contentWindow&&z({key:e,type:T,value:t})}function H(e){l||c?.contentWindow&&z({record:e,type:E})}function U(e,t){l||(a[e]=t,u&&c?.contentWindow&&z({css:t,id:e,type:D}))}return{get disposalSignal(){return s.signal},dispose:I,get disposed(){return l},onMessage:L,ready:g,render:R,replaceBody:B,setState:V,setStateAll:H,[Symbol.dispose](){I()},updateStyle:U}}exports.SandboxConfigurationError=r,exports.SandboxError=t,exports.SandboxTimeoutError=n,exports.buildCsp=m,exports.buildDocument=y,exports.createSandbox=M;
|
|
86
86
|
//# sourceMappingURL=sandbox.cjs.map
|