@tinycloud/share-sdk 1.2.0-beta.6 → 1.2.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/filename-policy.ts","../src/html-bundle/bundle.ts","../src/html-bundle/folder.ts"],"sourcesContent":["/**\n * Characters that can hide or visually reorder a filename: every Unicode\n * control, format and surrogate code point, plus U+2028/U+2029. Matches the\n * share viewer's `src/filename-policy.ts`.\n */\nconst UNSAFE_FILENAME_CODE_POINT = /[\\p{Cc}\\p{Cf}\\p{Cs}\\u2028\\u2029]/u;\n\nexport function hasUnsafeFilenameCodePoint(value: string): boolean {\n return UNSAFE_FILENAME_CODE_POINT.test(value);\n}\n\n/** A single display/download filename, never a path. Returns the NFC form. */\nexport function canonicalShareFilename(value: string): string {\n const canonical = value.normalize(\"NFC\");\n if (\n canonical.length === 0\n || canonical === \".\"\n || canonical === \"..\"\n || canonical.includes(\"/\")\n || canonical.includes(\"\\\\\")\n || hasUnsafeFilenameCodePoint(canonical)\n ) {\n throw new TypeError(\"share filename is unsafe\");\n }\n return canonical;\n}\n","import { hasUnsafeFilenameCodePoint } from \"../filename-policy.js\";\n\nexport const ARTIFACT_ENTRY = \"index.html\";\nexport const MAX_ARTIFACT_FILES = 1_000;\nexport const MAX_ARTIFACT_SOURCE_BYTES = 100 * 1024 * 1024;\nexport const MAX_ARTIFACT_RENDER_BYTES = 10 * 1024 * 1024;\nexport const MAX_ARTIFACT_TEXT_BYTES = 5 * 1024 * 1024;\nexport const MAX_ARTIFACT_REFERENCES = 2_000;\nexport const MAX_ARTIFACT_CSS_IMPORT_DEPTH = 16;\n/** Comments in one page, and attributes on one element: a page over either is refused before it is parsed (`limit`). */\nexport const MAX_ARTIFACT_COMMENTS = 20_000;\nexport const MAX_ARTIFACT_ATTRIBUTES_PER_ELEMENT = 5_000;\n\nexport type ArtifactFailureKind = \"malformed\" | \"missing\" | \"unsupported\" | \"limit\";\n\nexport class ArtifactBundleError extends Error {\n /**\n * `path` is the bundle file being processed when the refusal happened; `reference` is the reference text inside it\n * that was refused, when there is one. Both are the folder's own text: print them through a terminal-safe printer.\n */\n constructor(readonly kind: ArtifactFailureKind, message: string, readonly path?: string, readonly reference?: string) {\n super(message);\n this.name = \"ArtifactBundleError\";\n }\n}\n\n/** Options of `prepareHtmlArtifact`. */\nexport interface PrepareHtmlArtifactOptions {\n /**\n * Parses one HTML document with the HTML5 tree-building algorithm. Defaults to the browser's `DOMParser`; a Node\n * caller passes a spec-compliant parser (the CLI uses jsdom, which is built on parse5), so the rewriter sees the same\n * tree a browser builds.\n */\n readonly parseHtml?: (html: string) => Document;\n /**\n * Transform only the root `index.html` and refuse a link that points at another page. The result is one\n * self-contained document with no pages to navigate between.\n */\n readonly singlePage?: boolean;\n}\n\nexport interface ArtifactFile {\n readonly path: string;\n readonly bytes: Uint8Array;\n readonly mediaType?: string;\n}\n\nexport interface PreparedArtifact {\n readonly entry: string;\n readonly pages: Readonly<Record<string, string>>;\n readonly fileCount: number;\n readonly sourceBytes: number;\n}\n\nexport type ArtifactDetection =\n | { readonly kind: \"html\"; readonly entry: typeof ARTIFACT_ENTRY }\n | { readonly kind: \"folder\"; readonly reason: \"missing-root-index\" };\n\nconst MIME_BY_EXTENSION: Readonly<Record<string, string>> = Object.freeze({\n html: \"text/html;charset=utf-8\",\n htm: \"text/html;charset=utf-8\",\n css: \"text/css;charset=utf-8\",\n js: \"text/javascript;charset=utf-8\",\n json: \"application/json;charset=utf-8\",\n txt: \"text/plain;charset=utf-8\",\n md: \"text/markdown;charset=utf-8\",\n svg: \"image/svg+xml\",\n png: \"image/png\",\n jpg: \"image/jpeg\",\n jpeg: \"image/jpeg\",\n gif: \"image/gif\",\n webp: \"image/webp\",\n avif: \"image/avif\",\n ico: \"image/x-icon\",\n woff: \"font/woff\",\n woff2: \"font/woff2\",\n ttf: \"font/ttf\",\n otf: \"font/otf\",\n mp3: \"audio/mpeg\",\n wav: \"audio/wav\",\n mp4: \"video/mp4\",\n webm: \"video/webm\",\n pdf: \"application/pdf\",\n});\n\nconst SCHEME = /^[a-z][a-z0-9+.-]*:/i;\nconst ENCODED_PATH_ALIAS = /%2f|%5c|%2e/i;\nconst SAFE_MEDIA_QUERY = /^[a-z0-9\\s,().:%\\-+/]+$/i;\nconst UNSAFE_CLASSIC_SCRIPT =\n /\\b(?:fetch|XMLHttpRequest|WebSocket|EventSource|Worker|SharedWorker|importScripts|sendBeacon)\\s*\\(|\\b(?:window|self|globalThis|top|parent|opener)\\s*\\.\\s*open\\s*\\(|\\b(?:window|document|globalThis|self|top|parent|opener)\\s*(?:\\.\\s*location|\\[\\s*[\"']location[\"']\\s*\\])|\\blocation\\s*(?:=|(?:\\.\\s*|\\[\\s*[\"'])href(?:[\"']\\s*\\])?|\\.assign\\s*\\(|\\.replace\\s*\\(|\\.reload\\s*\\()|\\bimport\\s*\\(|\\beval\\s*\\(|\\bWebAssembly\\b/;\n\nfunction fail(kind: ArtifactFailureKind, detail: string): never {\n throw new ArtifactBundleError(kind, detail);\n}\n\nfunction defaultParseHtml(html: string): Document {\n if (typeof DOMParser === \"undefined\") {\n throw new TypeError(\"html-bundle needs a DOM parser: pass parseHtml outside a browser\");\n }\n return new DOMParser().parseFromString(html, \"text/html\");\n}\n\nexport function canonicalArtifactPath(input: string): string {\n const value = input.normalize(\"NFC\");\n const encodedLength = new TextEncoder().encode(value).byteLength;\n if (\n value.length === 0\n || encodedLength > 4_096\n || value.startsWith(\"/\")\n || value.endsWith(\"/\")\n || value.includes(\"\\\\\")\n || hasUnsafeFilenameCodePoint(value)\n || ENCODED_PATH_ALIAS.test(value)\n ) {\n fail(\"malformed\", \"artifact path is not canonical\");\n }\n const segments = value.split(\"/\");\n if (segments.some((segment) => segment.length === 0 || segment === \".\" || segment === \"..\" || new TextEncoder().encode(segment).byteLength > 255)) {\n fail(\"malformed\", \"artifact path is not canonical\");\n }\n return segments.join(\"/\");\n}\n\nexport function artifactMediaType(path: string, supplied?: string): string {\n const normalized = supplied?.split(\";\")[0]?.trim().toLowerCase();\n if (normalized !== undefined && /^[a-z0-9!#$&^_.+-]+\\/[a-z0-9!#$&^_.+-]+$/.test(normalized)) {\n return supplied!.trim();\n }\n const extension = path.split(\".\").at(-1)?.toLowerCase() ?? \"\";\n return MIME_BY_EXTENSION[extension] ?? \"application/octet-stream\";\n}\n\ninterface ResolvedReference {\n readonly path: string;\n readonly fragment: string;\n readonly fragmentOnly: boolean;\n}\n\nexport function resolveArtifactReference(basePath: string, reference: string): ResolvedReference {\n // As a URL parser trims: controls and space only. `String.trim` also strips U+00A0 and other Unicode whitespace, which a\n // browser keeps as part of a relative URL (so `&nbsp;#c` is a path, not a fragment).\n const raw = trimUrl(reference);\n if (raw.length === 0) return { path: canonicalArtifactPath(basePath), fragment: \"\", fragmentOnly: true };\n if (raw.startsWith(\"#\")) {\n return { path: canonicalArtifactPath(basePath), fragment: raw, fragmentOnly: true };\n }\n if (raw.startsWith(\"//\") || raw.startsWith(\"/\") || SCHEME.test(raw)) {\n fail(\"unsupported\", \"external artifact reference\");\n }\n const hashAt = raw.indexOf(\"#\");\n const queryAt = raw.indexOf(\"?\");\n const end = [hashAt, queryAt].filter((value) => value >= 0).reduce((min, value) => Math.min(min, value), raw.length);\n const pathname = raw.slice(0, end);\n const fragment = hashAt >= 0 ? raw.slice(hashAt) : \"\";\n if (pathname.length === 0) return { path: canonicalArtifactPath(basePath), fragment, fragmentOnly: true };\n if (pathname.includes(\"\\\\\") || hasUnsafeFilenameCodePoint(pathname) || ENCODED_PATH_ALIAS.test(pathname)) {\n fail(\"malformed\", \"artifact reference is not canonical\");\n }\n const output = basePath.split(\"/\").slice(0, -1);\n for (const segment of pathname.normalize(\"NFC\").split(\"/\")) {\n if (segment === \"\" || segment === \".\") continue;\n if (segment === \"..\") {\n if (output.length === 0) fail(\"malformed\", \"artifact reference escapes its bundle\");\n output.pop();\n continue;\n }\n output.push(segment);\n }\n return { path: canonicalArtifactPath(output.join(\"/\")), fragment, fragmentOnly: false };\n}\n\nexport function detectHtmlArtifact(paths: readonly string[]): ArtifactDetection {\n const seen = new Set<string>();\n let rootCount = 0;\n for (const rawPath of paths) {\n const path = canonicalArtifactPath(rawPath);\n const key = path.toLowerCase();\n if (seen.has(key)) fail(\"malformed\", \"artifact paths collide after canonicalization\");\n seen.add(key);\n if (path === ARTIFACT_ENTRY) rootCount += 1;\n }\n if (rootCount === 1) return { kind: \"html\", entry: ARTIFACT_ENTRY };\n return { kind: \"folder\", reason: \"missing-root-index\" };\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n let binary = \"\";\n const chunk = 0x8000;\n for (let offset = 0; offset < bytes.length; offset += chunk) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunk));\n }\n return btoa(binary);\n}\n\n/**\n * Every use of a resource adds to one running total, checked BEFORE the encoded copy is built, so a page that refers to one\n * large file many times is refused at the reference that passes the render cap instead of after it has been built.\n */\nfunction chargeInlinedBytes(context: TransformContext, bytes: number): void {\n context.counter.inlinedBytes += bytes;\n if (context.counter.inlinedBytes > MAX_ARTIFACT_RENDER_BYTES) fail(\"limit\", \"artifact inlined resources exceed the render limit\");\n}\n\nfunction asDataUrl(file: ArtifactFile, context: TransformContext): string {\n if (file.bytes.byteLength > MAX_ARTIFACT_RENDER_BYTES) fail(\"limit\", \"artifact resource exceeds render limit\");\n const prefix = `data:${artifactMediaType(file.path, file.mediaType)};base64,`;\n chargeInlinedBytes(context, prefix.length + 4 * Math.ceil(file.bytes.byteLength / 3));\n return `${prefix}${toBase64(file.bytes)}`;\n}\n\nfunction decodeText(file: ArtifactFile, context?: TransformContext): string {\n if (file.bytes.byteLength > MAX_ARTIFACT_TEXT_BYTES) fail(\"limit\", \"artifact text file exceeds render limit\");\n if (context !== undefined) chargeInlinedBytes(context, file.bytes.byteLength);\n try {\n return new TextDecoder(\"utf-8\", { fatal: true }).decode(file.bytes);\n } catch {\n return fail(\"malformed\", \"artifact text is not utf-8\");\n }\n}\n\nfunction assertClassicScript(source: string): void {\n if (UNSAFE_CLASSIC_SCRIPT.test(source)) fail(\"unsupported\", \"artifact script uses a blocked browser capability\");\n}\n\nfunction normalizeMediaQuery(media: string | null | undefined, detail = \"artifact uses an unsupported stylesheet media query\"): string | null {\n const value = media?.trim() ?? \"\";\n if (value.length === 0 || value.toLowerCase() === \"all\") return null;\n if (/[\\u0000-\\u001f\\u007f<>{};\"'`\\\\]/.test(value) || !SAFE_MEDIA_QUERY.test(value)) fail(\"unsupported\", detail);\n return value;\n}\n\nfunction wrapMediaCss(source: string, media: string | null | undefined, detail?: string): string {\n const value = normalizeMediaQuery(media, detail);\n if (value === null) return source;\n return `@media ${value} {\\n${source}\\n}`;\n}\n\nfunction classifyLinkRelation(rel: string | null): \"stylesheet\" | \"icon\" | null {\n const tokens = (rel?.trim().toLowerCase().split(/\\s+/).filter(Boolean) ?? []);\n if (tokens.length === 0) return null;\n const tokenSet = new Set(tokens);\n if (tokenSet.has(\"stylesheet\") && [...tokenSet].every((token) => token === \"stylesheet\" || token === \"alternate\")) return \"stylesheet\";\n if ((tokenSet.has(\"icon\") || tokenSet.has(\"apple-touch-icon\")) && [...tokenSet].every((token) => token === \"icon\" || token === \"apple-touch-icon\" || token === \"shortcut\")) return \"icon\";\n return null;\n}\n\nconst SVG_NAMESPACE = \"http://www.w3.org/2000/svg\";\n\n/**\n * The document and the content of every `<template>` in it (nested ones too). `querySelectorAll` does not enter template\n * content, but a browser clones it into the live page and a declarative shadow root (`shadowrootmode`) attaches it while\n * parsing, so it is examined and rewritten like the rest of the page.\n */\nfunction documentRoots(doc: Document): ParentNode[] {\n const roots: ParentNode[] = [doc];\n for (let index = 0; index < roots.length; index += 1) {\n for (const template of roots[index]!.querySelectorAll<HTMLTemplateElement>(\"template\")) roots.push(template.content);\n }\n return roots;\n}\n\nfunction queryAll<T extends Element = Element>(roots: readonly ParentNode[], selector: string): T[] {\n return roots.flatMap((root) => [...root.querySelectorAll<T>(selector)]);\n}\n\n/**\n * Attributes whose value is a URL (or a list of them) that a browser may fetch or navigate to, or that names a resource:\n * the HTML attributes that do (`src`, `href`, `srcset`, `imagesrcset`, `poster`, `action`, `formaction`, `ping`,\n * `background`, `cite`, `data`, `codebase`, `archive`, `classid`, `profile`, `longdesc`, `usemap`, `manifest`, `icon`,\n * `lowsrc`, `dynsrc`, `itemtype`, `itemid`), the Attribution Reporting `attributionsrc`, and `xlink:href` (matched by its\n * local name, like `href` on SVG `<use>`, `<image>`, `<feImage>`, `<mpath>` and MathML). In the finished page each must be\n * a `data:` URL the rewriter wrote or a `#fragment`.\n */\nconst URL_ATTRIBUTES = new Set([\n \"href\", \"src\", \"srcset\", \"imagesrcset\", \"poster\", \"action\", \"formaction\", \"cite\", \"data\", \"codebase\", \"longdesc\", \"usemap\",\n \"ping\", \"background\", \"manifest\", \"icon\", \"archive\", \"classid\", \"profile\", \"lowsrc\", \"dynsrc\", \"attributionsrc\", \"itemtype\", \"itemid\",\n]);\n\n/**\n * A URL parser trims leading and trailing C0 controls and spaces and only those: not U+00A0, not Unicode whitespace\n * (`String.prototype.trim` strips both, which would turn `&nbsp;#c` into a fragment). Tabs and newlines inside are removed.\n */\nfunction trimUrl(value: string): string {\n // eslint-disable-next-line no-control-regex\n return value.replace(/^[\\u0000-\\u0020]+|[\\u0000-\\u0020]+$/g, \"\");\n}\n\nfunction urlText(value: string): string {\n return trimUrl(value).replace(/[\\t\\n\\r]/g, \"\");\n}\n\n/** A same-document fragment: `#` and then printable characters (no control, no space, no backslash). */\nfunction isFragmentOnly(trimmed: string): boolean {\n // eslint-disable-next-line no-control-regex\n return /^#[^\\u0000-\\u0020\\u007f-\\u009f\\\\]*$/.test(trimmed);\n}\n\n/** The shape of every `data:` URL the rewriter writes (once cut down by `withoutDataUris`), with an optional fragment. */\n// The comma is optional because a `srcset` list is split on commas, which strips the one that ends `data:;base64,`.\nconst INLINE_DATA_URL = /^data:;base64(?:,[A-Za-z0-9+/=]*)?(?:#[^\\u0000-\\u0020\\\\]*)?$/;\n\n/**\n * `data:` and `#fragment` are the only references the finished page may hold. Anything else is refused: a relative path\n * such as `other.png` resolves against the viewer's origin, and an empty value names the page itself.\n */\nfunction isInlineReference(value: string): boolean {\n const text = urlText(value);\n return isFragmentOnly(text) || INLINE_DATA_URL.test(text);\n}\n\nfunction assertInlineSrcset(value: string): void {\n // The list is split on ASCII whitespace, as a browser splits it.\n for (const raw of value.split(/[\\t\\n\\f\\r ]+/)) {\n const token = raw.replace(/,+$/, \"\");\n if (token === \"\" || /^\\d+(?:\\.\\d+)?[wx]$/i.test(token)) continue;\n if (!isInlineReference(token)) throw new ArtifactBundleError(\"unsupported\", \"artifact page still references a resource\", undefined, token);\n }\n}\n\n/**\n * The values of a `<script type>` that name JavaScript (the HTML spec's JavaScript MIME type essences). Any other type makes\n * the element a data block that the browser or a script reads, not a script that runs: `speculationrules` (a list of URLs\n * the browser prefetches or prerenders), `importmap`, `webbundle`, templates, JSON. A page of this kind has no use for them,\n * so each is refused. `module` is refused separately.\n */\nconst JAVASCRIPT_TYPES = new Set([\n \"application/ecmascript\", \"application/javascript\", \"application/x-ecmascript\", \"application/x-javascript\", \"text/ecmascript\",\n \"text/javascript\", \"text/javascript1.0\", \"text/javascript1.1\", \"text/javascript1.2\", \"text/javascript1.3\", \"text/javascript1.4\",\n \"text/javascript1.5\", \"text/jscript\", \"text/livescript\", \"text/x-ecmascript\", \"text/x-javascript\",\n]);\n\n/** An absent or empty `type`, or a JavaScript MIME type (parameters such as `;charset=utf-8` are not part of the type). */\nfunction isJavaScriptType(value: string | null | undefined): boolean {\n const type = (value ?? \"\").replace(/^[\\t\\n\\f\\r ]+|[\\t\\n\\f\\r ]+$/g, \"\").toLowerCase();\n if (type === \"\") return true;\n return JAVASCRIPT_TYPES.has(type.split(\";\")[0]!.replace(/[\\t\\n\\f\\r ]+$/g, \"\"));\n}\n\nconst BLOCKED_ELEMENTS = \"base, form, iframe, frame, frameset, object, embed, portal, noscript, plaintext, xmp, noembed, noframes, applet, area[href], link:not([href]), [ping]\";\n\n/**\n * The `data:` URLs the rewriter wrote, cut down to `data:;base64,`. They are the only large things in a finished page and\n * the only references it may hold, so the checks below read the page without them: parsing a multi-megabyte `style=`\n * value is what costs memory and time, and their content is base64 that no check looks at. Only text of the exact shape\n * `data:<type>;base64,<base64 characters>` is cut, so nothing that could carry markup or a URL is hidden.\n */\nconst DATA_URI = /data:[a-z0-9!#$&^_.+/-]*(?:;[a-z0-9!#$&^_.+=-]+)*;base64,[A-Za-z0-9+/=]*/gi;\n\nfunction withoutDataUris(html: string): string {\n return html.replace(DATA_URI, \"data:;base64,\");\n}\n\n/** Attributes that carry text, not a URL a browser fetches or follows. Every other attribute may not look like a URL. */\nconst TEXT_ATTRIBUTES = /^(?:alt|title|placeholder|value|label|content|name|id|class|lang|summary|abbr|datetime|pattern|xmlns(?::[\\w.-]+)?|aria-[\\w.:-]*|data-[\\w.:-]*)$/;\n\n/** Text that a browser would take for a URL to fetch or follow: a network or script scheme, a `//host`, or a path. */\nfunction looksLikeUrl(raw: string): boolean {\n // A browser reads a backslash as a slash in the URLs of the special schemes (`\\\\host/x` is `//host/x`).\n const value = raw.replace(/\\\\/g, \"/\");\n return /(?:^|[^a-z0-9+.-])(?:https?|ftps?|wss?|file|javascript|vbscript|blob|about|view-source|filesystem):/i.test(value)\n || /(?:^|[\\s,;(=\"'])\\/\\/\\S/.test(value)\n || /:\\/\\//.test(value)\n || /^\\s*\\.{0,2}\\/[^\\s]/.test(value);\n}\n\nconst NAMED_CHARACTERS: Readonly<Record<string, string>> = {\n amp: \"&\", quot: '\"', apos: \"'\", lt: \"<\", gt: \">\", nbsp: \"\\u00a0\", colon: \":\", sol: \"/\", bsol: \"\\\\\", period: \".\", comma: \",\", semi: \";\",\n equals: \"=\", num: \"#\", quest: \"?\", lpar: \"(\", rpar: \")\", tab: \"\\t\", newline: \"\\n\",\n};\n\n/** The character references a page may still hold in an attribute value, decoded the way a browser decodes them. */\nfunction decodeAttributeValue(value: string): string {\n return value.replace(/&(?:#[xX]([0-9a-fA-F]{1,6})|#([0-9]{1,7})|([A-Za-z]{2,8}));?/g, (whole, hex: string | undefined, decimal: string | undefined, name: string | undefined) => {\n if (name !== undefined) return NAMED_CHARACTERS[name.toLowerCase()] ?? whole;\n const point = Number.parseInt(hex ?? decimal ?? \"\", hex === undefined ? 10 : 16);\n return point > 0 && point <= 0x10ffff && !(point >= 0xd800 && point <= 0xdfff) ? String.fromCodePoint(point) : \"\\ufffd\";\n });\n}\n\nconst MARKUP_BLOCKED_NAMES = new Set([\"base\", \"form\", \"iframe\", \"frame\", \"frameset\", \"object\", \"embed\", \"portal\", \"noscript\", \"plaintext\", \"xmp\", \"noembed\", \"noframes\", \"applet\"]);\n\nfunction unsupportedOutput(detail: string, reference?: string): never {\n throw new ArtifactBundleError(\"unsupported\", detail, undefined, reference);\n}\n\n/** An SVG animation element (`<set>`, `<animate>`, ...) whose `attributeName` is `href` or `xlink:href`: it writes a URL into the page. */\nfunction isHrefAnimation(tag: string, attributeName: string, value: string): boolean {\n return /^(?:animate|set|animatetransform|animatemotion)$/i.test(tag) && attributeName.toLowerCase() === \"attributename\" && /^(?:xlink:)?href$/i.test(trimUrl(value));\n}\n\nfunction checkAttribute(name: string, decoded: string): void {\n const local = name.slice(name.lastIndexOf(\":\") + 1);\n if (/^on/.test(name)) unsupportedOutput(\"artifact output contains a blocked html feature\");\n if (name === \"style\") {\n assertOnlyInlineCssReferences(decoded);\n return;\n }\n if (local === \"srcset\" || local === \"imagesrcset\") {\n assertInlineSrcset(decoded);\n return;\n }\n if (URL_ATTRIBUTES.has(local)) {\n if (!isInlineReference(decoded)) unsupportedOutput(\"artifact page still references a resource\", decoded);\n return;\n }\n if (TEXT_ATTRIBUTES.test(name)) return;\n // Any other attribute: a name no list here knows may still be one a browser fetches, so a value that reads as a URL is\n // refused whatever the name is.\n if (looksLikeUrl(urlText(decoded))) unsupportedOutput(\"artifact page still references a resource\", decoded);\n // CSS in an attribute that is not `style` (an SVG presentation attribute, for one): the same checks, escapes included.\n if (/url\\s*\\(|image-set|@import|\\\\/i.test(decoded) || /(?:^|[^\\w-])src\\s*\\(/i.test(decoded)) assertOnlyInlineCssReferences(decoded);\n}\n\n/**\n * The only `<meta http-equiv>` a finished page may hold is the rewriter's own Content-Security-Policy. Every other one\n * either acts like a response header (`refresh`, `Link`, `Set-Cookie`, `Default-Style`, `Content-Security-Policy` of the\n * author) or is not needed in a page that is already one UTF-8 document, so the rewriter drops them all.\n */\nfunction isOwnPolicyMeta(httpEquiv: string, content: string | null): boolean {\n return httpEquiv.trim().toLowerCase() === \"content-security-policy\" && content === INNER_CSP;\n}\n\n/** HTML's whitespace: space, tab, newline, form feed, carriage return. A tag or attribute name never ends at U+00A0 or other Unicode whitespace. */\nconst HTML_SPACE = \"\\\\t\\\\n\\\\f\\\\r \";\nconst TAG_NAME = new RegExp(`[^${HTML_SPACE}/>]*`, \"y\");\nconst ATTRIBUTE_NAME = new RegExp(`=?[^${HTML_SPACE}/>=]*`, \"y\");\nconst UNQUOTED_VALUE = new RegExp(`[^${HTML_SPACE}>]*`, \"y\");\nconst SKIPPED = new RegExp(`[${HTML_SPACE}/]`);\nconst SPACE = new RegExp(`[${HTML_SPACE}]`);\n/** Unicode whitespace and invisible characters that are never part of a tag name a page means. */\nconst ODD_TAG_NAME = /[\\u00a0\\u1680\\u180e\\u2000-\\u200f\\u2028-\\u202f\\u205f-\\u2064\\u3000\\ufeff]/;\nconst COMMENT_END = /--!?>/g;\nconst SCRIPT_END = /<\\/script/gi;\nconst STYLE_END = /<\\/style/gi;\n\ninterface ScanOptions {\n /**\n * `true` (a finished page): every reference is checked and a malformed tag is refused. `false` (a source page, before it\n * is parsed): only the comment and attribute limits are enforced, and a malformed tag ends the scan.\n */\n readonly references: boolean;\n}\n\n/**\n * A scan of a page's text that shares nothing with the DOM parser: it finds the tags and attributes itself, so a difference\n * in how a parser reads some markup (jsdom against a browser) cannot hide a reference from both checks. Scripts are the\n * author's code and are skipped (a script may hold the text `https://` as data; what scripts may do is the sandbox's and the\n * CSP's job, with the capability scan on their source); `<style>` text is checked as CSS and then read as markup like\n * everything else, so nothing after a `<` is ever skipped except a script's source and a comment. A tag found in text that\n * is really not one (inside an `<xmp>` or a comment-like string) can only cause a refusal, never a miss. Names end at\n * HTML whitespace only, as a browser ends them.\n *\n * Both modes count comments and the attributes of each tag and refuse (`limit`) a page over `MAX_ARTIFACT_COMMENTS` or\n * `MAX_ARTIFACT_ATTRIBUTES_PER_ELEMENT`, so the DOM parser is never given a page whose comments or attributes would take\n * minutes to parse.\n */\nfunction scanMarkup(html: string, options: ScanOptions): void {\n const checkReferences = options.references;\n const length = html.length;\n let index = 0;\n let comments = 0;\n /** A malformed page: refused when references are checked; in the pre-parse mode the scan simply ends. */\n const malformed = (detail: string): boolean => {\n if (checkReferences) unsupportedOutput(detail);\n return true;\n };\n const countComment = (): void => {\n comments += 1;\n if (comments > MAX_ARTIFACT_COMMENTS) fail(\"limit\", \"artifact page has too many comments\");\n };\n while (index < length) {\n const open = html.indexOf(\"<\", index);\n if (open === -1) return;\n index = open + 1;\n const next = html[index] ?? \"\";\n if (html.startsWith(\"!--\", index)) {\n countComment();\n let end: number;\n if (html[index + 3] === \">\") end = index + 4;\n else if (html.startsWith(\"->\", index + 3)) end = index + 5;\n else {\n // The first `-->` or `--!>`, found in one pass.\n COMMENT_END.lastIndex = index + 3;\n const close = COMMENT_END.exec(html);\n if (close === null) {\n if (malformed(\"artifact output has an unterminated comment\")) return;\n return;\n }\n end = close.index + close[0].length;\n }\n index = end;\n continue;\n }\n if (next === \"!\" || next === \"?\" || next === \"/\") {\n // A doctype, a bogus comment or an end tag ends at the first `>`; an end tag's attributes are never used.\n if (next === \"?\" || (next === \"!\" && !/^!doctype/i.test(html.slice(index, index + 8)))) countComment();\n const close = html.indexOf(\">\", index);\n if (close === -1) {\n if (malformed(\"artifact output has an unterminated tag\")) return;\n return;\n }\n index = close + 1;\n continue;\n }\n if (!/[A-Za-z]/.test(next)) continue;\n TAG_NAME.lastIndex = index;\n const rawTag = TAG_NAME.exec(html)![0];\n const tag = rawTag.toLowerCase();\n index = TAG_NAME.lastIndex;\n if (checkReferences) {\n if (ODD_TAG_NAME.test(rawTag)) unsupportedOutput(\"artifact output has a tag name with an unexpected character\");\n if (MARKUP_BLOCKED_NAMES.has(tag)) unsupportedOutput(\"artifact output contains a blocked html feature\");\n }\n const attributes = new Map<string, string>();\n let attributeCount = 0;\n for (;;) {\n while (index < length && SKIPPED.test(html[index]!)) index += 1;\n if (index >= length) {\n if (malformed(\"artifact output has an unterminated tag\")) return;\n return;\n }\n if (html[index] === \">\") {\n index += 1;\n break;\n }\n ATTRIBUTE_NAME.lastIndex = index;\n const rawName = ATTRIBUTE_NAME.exec(html)![0];\n index = ATTRIBUTE_NAME.lastIndex;\n while (index < length && SPACE.test(html[index]!)) index += 1;\n let rawValue = \"\";\n if (html[index] === \"=\") {\n index += 1;\n while (index < length && SPACE.test(html[index]!)) index += 1;\n const quote = html[index];\n if (quote === '\"' || quote === \"'\") {\n const close = html.indexOf(quote, index + 1);\n if (close === -1) {\n if (malformed(\"artifact output has an unterminated attribute\")) return;\n return;\n }\n rawValue = html.slice(index + 1, close);\n index = close + 1;\n } else {\n UNQUOTED_VALUE.lastIndex = index;\n rawValue = UNQUOTED_VALUE.exec(html)![0];\n index = UNQUOTED_VALUE.lastIndex;\n }\n }\n if (rawName.length > 0) {\n attributeCount += 1;\n if (attributeCount > MAX_ARTIFACT_ATTRIBUTES_PER_ELEMENT) fail(\"limit\", \"artifact element has too many attributes\");\n if (!checkReferences) continue;\n const name = rawName.toLowerCase();\n const decoded = decodeAttributeValue(rawValue);\n checkAttribute(name, decoded);\n if (isHrefAnimation(tag, name, decoded)) unsupportedOutput(\"artifact svg animates a resource reference\");\n // A repeated attribute: a browser keeps the first, so only the first is the one that counts for the tag-level checks.\n if (!attributes.has(name)) attributes.set(name, decoded);\n } else if (index < length && html[index] !== \">\" && !SKIPPED.test(html[index]!)) {\n // A lone quote or other character that starts no name: step over it so the scan always moves forward.\n index += 1;\n }\n }\n if (checkReferences) {\n // The same elements and attributes the DOM pass refuses by selector (`BLOCKED_ELEMENTS`), so neither pass depends on the other.\n if ((tag === \"area\" && attributes.has(\"href\")) || attributes.has(\"ping\") || (tag === \"link\" && !attributes.has(\"href\"))) {\n unsupportedOutput(\"artifact output contains a blocked html feature\");\n }\n if (tag === \"meta\" && attributes.has(\"http-equiv\") && !isOwnPolicyMeta(attributes.get(\"http-equiv\")!, attributes.get(\"content\") ?? null)) {\n unsupportedOutput(\"artifact output contains a meta http-equiv\", attributes.get(\"http-equiv\"));\n }\n if (tag === \"script\" && !isJavaScriptType(attributes.get(\"type\"))) {\n unsupportedOutput(\"artifact output holds a script type that is not JavaScript\", attributes.get(\"type\"));\n }\n }\n if (tag === \"script\") {\n SCRIPT_END.lastIndex = index;\n const close = SCRIPT_END.exec(html);\n if (close === null) return;\n index = close.index;\n } else if (tag === \"style\" && checkReferences) {\n STYLE_END.lastIndex = index;\n const close = STYLE_END.exec(html);\n assertOnlyInlineCssReferences(html.slice(index, close === null ? length : close.index));\n }\n }\n}\n\nexport interface AssertSelfContainedOptions {\n /** Parses HTML with the HTML5 tree builder. Defaults to the browser's `DOMParser`. */\n readonly parseHtml?: (html: string) => Document;\n /**\n * Run only one of the two passes: `\"bytes\"` (the scan with its own tokenizer) or `\"dom\"` (the DOM parser's view). Both run\n * by default; the option exists so each pass can be tested alone.\n */\n readonly only?: \"bytes\" | \"dom\";\n}\n\n/**\n * The last check, on a finished page and independent of the rewriting that made it: the page is read without its\n * `data:` URLs by a scan that has its own tokenizer and then by the DOM parser, and refused (`unsupported`) if anything in it\n * could still fetch or navigate to something other than a `data:` URL the rewriter wrote or a `#fragment` of the page.\n *\n * What it enforces (each class is refused, not rewritten):\n * - every URL-bearing attribute (`URL_ATTRIBUTES`: `href`, `xlink:href`, `src`, `srcset`, `imagesrcset`, `poster`, `ping`,\n * `attributionsrc`, `background`, `formaction`, `cite`, `data`, `codebase`, `archive`, `profile`, `longdesc`, `usemap`,\n * `manifest`, `lowsrc`, `dynsrc`, `itemtype`, ...) holds only `data:;base64,...` or `#fragment`, after the value is read the way\n * a browser reads it (entities decoded, tabs and newlines removed, controls and spaces trimmed, U+00A0 and other Unicode\n * whitespace not trimmed): a relative path, an empty value, `&nbsp;#c` and `\\host/x` are all refused;\n * - any other attribute outside a text allow-list (`title`, `alt`, `aria-*`, `data-*`, `content`, `xmlns`, ...) whose value\n * reads as a URL (a network or script scheme, `//host`, `\\host`, a path) is refused;\n * - CSS in `<style>` and in attributes: no `@import`, `image-set()` or `src()`, and every `url()` is `data:` or `#fragment`,\n * backslash escapes decoded first;\n * - no `<meta http-equiv>` except the rewriter's own Content-Security-Policy, no event handler, no `<base>`, `<form>`,\n * frames, `<object>`, `<embed>`, `<noscript>`, `<xmp>`, `<plaintext>`, `<area href>`, no `ping`, no SVG `<script>`.\n *\n * What it does not enforce: what a page's own script does (the scripts are scanned for blocked capabilities at rewrite\n * time, and the viewer's sandbox and Content-Security-Policy are the second line), and text that is not an attribute or\n * `<style>` (a script or a text node may hold `https://` as data).\n */\nexport function assertSelfContainedPage(output: string, options: AssertSelfContainedOptions = {}): void {\n const page = withoutDataUris(output);\n if (options.only !== \"dom\") scanMarkup(page, { references: true });\n if (options.only === \"bytes\") return;\n const doc = (options.parseHtml ?? defaultParseHtml)(page);\n const roots = documentRoots(doc);\n if (queryAll(roots, BLOCKED_ELEMENTS).length > 0) fail(\"unsupported\", \"artifact output contains a blocked html feature\");\n for (const meta of queryAll<HTMLMetaElement>(roots, \"meta[http-equiv]\")) {\n if (!isOwnPolicyMeta(meta.getAttribute(\"http-equiv\") ?? \"\", meta.getAttribute(\"content\"))) fail(\"unsupported\", \"artifact output contains a meta http-equiv\");\n }\n if (queryAll(roots, \"script[src]\").length > 0) fail(\"unsupported\", \"artifact output still loads a script\");\n for (const script of queryAll(roots, \"script\")) {\n if (!isJavaScriptType(script.getAttribute(\"type\"))) fail(\"unsupported\", \"artifact output holds a script type that is not JavaScript\");\n }\n for (const style of queryAll(roots, \"style\")) assertOnlyInlineCssReferences(style.textContent ?? \"\");\n for (const element of queryAll(roots, \"*\")) {\n const inSvg = element.namespaceURI === SVG_NAMESPACE;\n if (inSvg && element.localName === \"script\") fail(\"unsupported\", \"artifact svg contains a script\");\n for (const name of element.getAttributeNames()) {\n const lower = name.toLowerCase();\n const local = lower.slice(lower.lastIndexOf(\":\") + 1);\n // The DOM already holds the decoded value.\n const value = element.getAttribute(name) ?? \"\";\n if (/^on/.test(lower)) fail(\"unsupported\", \"artifact output contains a blocked html feature\");\n if (URL_ATTRIBUTES.has(local)) {\n if (local === \"srcset\" || local === \"imagesrcset\") assertInlineSrcset(value);\n else if (!isInlineReference(value)) throw new ArtifactBundleError(\"unsupported\", \"artifact page still references a resource\", undefined, value);\n } else if (lower !== \"style\" && !TEXT_ATTRIBUTES.test(lower) && looksLikeUrl(urlText(value))) {\n // Any other attribute outside the text allow-list whose value reads as a URL, whatever its name.\n throw new ArtifactBundleError(\"unsupported\", \"artifact page still references a resource\", undefined, value);\n }\n if (lower === \"style\" || inSvg) assertOnlyInlineCssReferences(value);\n if (isHrefAnimation(element.localName, lower, value)) fail(\"unsupported\", \"artifact svg animates a resource reference\");\n }\n }\n}\n\nfunction verifySelfContained(output: string, context: TransformContext): void {\n assertSelfContainedPage(output, { parseHtml: context.parseHtml });\n}\n\n/**\n * Inline SVG elements (`<image>`, `<use>`, `<script>`, `<feImage>`, ...) reference resources through `href` or\n * `xlink:href`, which the HTML resource list above does not cover. Only same-document `#fragment` references are\n * allowed; a plain `href` on `<a>` is handled with the other anchors.\n */\nfunction rejectSvgResourceReferences(roots: readonly ParentNode[]): void {\n for (const element of queryAll(roots, \"*\")) {\n if (element.namespaceURI !== SVG_NAMESPACE) continue;\n const animatesHref = /^(?:animate|set|animatetransform|animatemotion)$/i.test(element.localName)\n && element.getAttributeNames().some((name) => name.toLowerCase() === \"attributename\" && /^(?:xlink:)?href$/i.test(trimUrl(element.getAttribute(name) ?? \"\")));\n if (animatesHref) fail(\"unsupported\", \"artifact svg animates a resource reference\");\n // An SVG `<script>` is read as markup by a browser's tokenizer, not as script text, so what is in it cannot be checked like a page script.\n if (element.localName === \"script\") fail(\"unsupported\", \"artifact svg contains a script\");\n for (const attributeName of element.getAttributeNames()) {\n if (attributeName !== \"href\" && !attributeName.endsWith(\":href\")) continue;\n if (element.localName === \"a\" && attributeName === \"href\") continue;\n if (!isFragmentOnly(urlText(element.getAttribute(attributeName) ?? \"\"))) fail(\"unsupported\", \"artifact svg references a resource\");\n }\n }\n}\n\nfunction rejectEventHandlerAttributes(roots: readonly ParentNode[]): void {\n for (const element of queryAll(roots, \"*\")) {\n for (const attributeName of element.getAttributeNames()) {\n if (/^on/i.test(attributeName)) fail(\"unsupported\", \"artifact contains a blocked html feature\");\n }\n }\n}\n\nfunction replaceAsync(\n input: string,\n expression: RegExp,\n replacer: (...match: string[]) => Promise<string>,\n): Promise<string> {\n const matches = [...input.matchAll(expression)];\n return matches.reduceRight(\n async (next, match) => {\n const value = await next;\n const replacement = await replacer(...match.map((entry) => entry ?? \"\"));\n return `${value.slice(0, match.index)}${replacement}${value.slice((match.index ?? 0) + match[0].length)}`;\n },\n Promise.resolve(input),\n );\n}\n\ninterface TransformContext {\n readonly files: ReadonlyMap<string, ArtifactFile>;\n readonly cssStack: readonly string[];\n readonly counter: { references: number; inlinedBytes: number };\n readonly parseHtml: (html: string) => Document;\n readonly singlePage: boolean;\n /** Set while rewriting a `style=` attribute: inlined URLs are parked here and swapped back after serialization (see `Deferred`). */\n readonly deferred?: Deferred;\n}\n\n/**\n * Large `data:` URLs written into a `style=` attribute are parked behind a placeholder and put back in the serialized page.\n * A DOM that parses the value as CSS (jsdom does, on every set) takes seconds and gigabytes for a few megabytes of\n * base64, which no check needs to see: the placeholder has the same shape (`data:;base64,...`) and is replaced by exactly\n * the URL that was parked, through a per-page random token, so page text cannot collide with it.\n */\ninterface Deferred {\n readonly token: string;\n readonly urls: string[];\n}\n\nfunction newDeferred(): Deferred {\n const bytes = new Uint8Array(8);\n if (globalThis.crypto?.getRandomValues !== undefined) globalThis.crypto.getRandomValues(bytes);\n else for (let index = 0; index < bytes.length; index += 1) bytes[index] = Math.floor(Math.random() * 256);\n return { token: Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\"), urls: [] };\n}\n\nfunction parkUrl(deferred: Deferred, url: string): string {\n deferred.urls.push(url);\n return `data:;base64,TCPH${deferred.token}x${deferred.urls.length - 1}x`;\n}\n\nfunction restoreParkedUrls(page: string, deferred: Deferred): string {\n if (deferred.urls.length === 0) return page;\n const pattern = new RegExp(`data:;base64,TCPH${deferred.token}x(\\\\d+)x`, \"g\");\n return page.replace(pattern, (_whole, index: string) => deferred.urls[Number(index)]!);\n}\n\n/** `resolveArtifactReference`, with a refusal naming the file and the reference text that caused it. */\nfunction resolveReferenceFrom(basePath: string, reference: string): ResolvedReference {\n try {\n return resolveArtifactReference(basePath, reference);\n } catch (error) {\n if (error instanceof ArtifactBundleError) throw new ArtifactBundleError(error.kind, error.message, basePath, reference);\n throw error;\n }\n}\n\nfunction requiredFile(context: TransformContext, basePath: string, reference: string): { file: ArtifactFile; resolved: ResolvedReference } {\n context.counter.references += 1;\n if (context.counter.references > MAX_ARTIFACT_REFERENCES) fail(\"limit\", \"artifact has too many resource references\");\n const resolved = resolveReferenceFrom(basePath, reference);\n const file = context.files.get(resolved.path);\n if (file === undefined) throw new ArtifactBundleError(\"missing\", \"artifact resource is missing\", basePath, reference);\n return { file, resolved };\n}\n\n/** The CSS names that start a reference. A backslash escape in one of them would hide it from the expressions below. */\nconst CSS_REFERENCE_NAMES = new Set([\"url\", \"image-set\", \"-webkit-image-set\", \"src\", \"import\"]);\n\nfunction isCssIdentifierCode(code: number): boolean {\n return code >= 0x80 || (code >= 0x30 && code <= 0x39) || (code >= 0x41 && code <= 0x5a) || (code >= 0x61 && code <= 0x7a) || code === 0x5f || code === 0x2d;\n}\n\n/**\n * Decode the backslash escapes of function names and at-keywords that start a reference (`u\\72l(`, `\\75rl(`,\n * `@\\69mport`), so the expressions that find `url()`, `@import`, `image-set()` and `src()` see the name a CSS parser\n * sees. Any other identifier (a selector such as `.sm\\:flex`), string, comment and url token is copied unchanged, so the\n * result means what the source meant.\n */\nexport function normalizeCssEscapes(source: string): string {\n let output = \"\";\n let index = 0;\n const length = source.length;\n while (index < length) {\n const char = source[index]!;\n if (char === \"/\" && source[index + 1] === \"*\") {\n const end = source.indexOf(\"*/\", index + 2);\n const stop = end === -1 ? length : end + 2;\n output += source.slice(index, stop);\n index = stop;\n continue;\n }\n if (char === '\"' || char === \"'\") {\n let cursor = index + 1;\n while (cursor < length && source[cursor] !== char && source[cursor] !== \"\\n\") cursor += source[cursor] === \"\\\\\" ? 2 : 1;\n const stop = Math.min(source[cursor] === char ? cursor + 1 : cursor, length);\n output += source.slice(index, stop);\n index = stop;\n continue;\n }\n if (char === \"\\\\\" || isCssIdentifierCode(source.charCodeAt(index))) {\n let cursor = index;\n let decoded = \"\";\n let escaped = false;\n while (cursor < length) {\n if (source[cursor] === \"\\\\\") {\n const next = source[cursor + 1];\n if (next === undefined) {\n decoded += \"\\ufffd\";\n escaped = true;\n cursor += 1;\n break;\n }\n if (next === \"\\n\" || next === \"\\r\" || next === \"\\f\") break;\n escaped = true;\n const hex = /^[0-9a-fA-F]{1,6}/.exec(source.slice(cursor + 1, cursor + 7));\n if (hex !== null) {\n const point = Number.parseInt(hex[0], 16);\n cursor += 1 + hex[0].length;\n if (source[cursor] === \"\\r\" && source[cursor + 1] === \"\\n\") cursor += 2;\n else if (/[ \\t\\n\\r\\f]/.test(source[cursor] ?? \"\")) cursor += 1;\n decoded += point === 0 || point > 0x10ffff || (point >= 0xd800 && point <= 0xdfff) ? \"\\ufffd\" : String.fromCodePoint(point);\n } else {\n const point = source.codePointAt(cursor + 1)!;\n decoded += String.fromCodePoint(point);\n cursor += 1 + (point > 0xffff ? 2 : 1);\n }\n } else if (isCssIdentifierCode(source.charCodeAt(cursor))) {\n decoded += source[cursor];\n cursor += 1;\n } else break;\n }\n const raw = source.slice(index, cursor);\n const startsReference = escaped && (source[cursor] === \"(\" || output.endsWith(\"@\")) && CSS_REFERENCE_NAMES.has(decoded.toLowerCase());\n output += startsReference ? decoded : raw;\n index = cursor;\n continue;\n }\n output += char;\n index += 1;\n }\n return output;\n}\n\n/**\n * Whatever CSS is in the finished page: no `@import`, `image-set()` or `src()`, and every `url()` is a `data:` URL or a\n * `#fragment` (what this rewriter writes). Escapes in the names are decoded first.\n */\nfunction assertOnlyInlineCssReferences(css: string): void {\n const text = normalizeCssEscapes(css);\n if (/@import/i.test(text)) fail(\"unsupported\", \"artifact css still imports a stylesheet\");\n if (/(?:^|[^\\w-])(?:-webkit-)?image-set\\s*\\(/i.test(text) || /(?:^|[^\\w-])src\\s*\\(/i.test(text)) fail(\"unsupported\", \"artifact css uses an unsupported resource function\");\n const opened = text.match(/url\\(/gi)?.length ?? 0;\n let read = 0;\n // CSS whitespace is space, tab, newline, carriage return and form feed: not U+00A0, which stays part of the URL.\n for (const match of text.matchAll(/url\\([ \\t\\n\\r\\f]*(?:\"([^\"]*)\"|'([^']*)'|([^)\"' \\t\\n\\r\\f]*))[ \\t\\n\\r\\f]*\\)/gi)) {\n read += 1;\n const value = match[1] ?? match[2] ?? match[3] ?? \"\";\n if (!isInlineReference(value) || value.includes(\"\\\\\")) {\n throw new ArtifactBundleError(\"unsupported\", \"artifact css references a resource\", undefined, value);\n }\n }\n if (read !== opened) fail(\"unsupported\", \"artifact css has a url() that cannot be read\");\n}\n\nasync function transformCss(sourceText: string, basePath: string, context: TransformContext): Promise<string> {\n if (context.cssStack.length > MAX_ARTIFACT_CSS_IMPORT_DEPTH) fail(\"limit\", \"artifact stylesheet import depth exceeded\");\n const source = normalizeCssEscapes(sourceText);\n const imported = await replaceAsync(\n source,\n /@import\\s+(?:url\\(\\s*(?:([\"'])([^\"']+)\\1|([^\"')\\s]+))\\s*\\)|([\"'])([^\"']+)\\4)\\s*([^;]*);/gi,\n async (_whole, _urlQuote, quotedUrl, unquotedUrl, _quote, quotedReference, media) => {\n const reference = quotedUrl || unquotedUrl || quotedReference;\n if (/^(?:layer|supports)\\b/i.test(media.trim()) || /\\b(?:layer|supports)\\b/i.test(media)) fail(\"unsupported\", \"artifact uses an unsupported stylesheet import condition\");\n const { file, resolved } = requiredFile(context, basePath, reference);\n if (context.cssStack.includes(resolved.path)) fail(\"unsupported\", \"artifact stylesheet import cycle\");\n const css = await transformCss(decodeText(file, context), resolved.path, { ...context, cssStack: [...context.cssStack, resolved.path] });\n return wrapMediaCss(css, media, \"artifact uses an unsupported stylesheet import condition\");\n },\n );\n return replaceAsync(\n imported,\n /url\\(\\s*([\"']?)([^\"')]+)\\1\\s*\\)/gi,\n async (_whole, _quote, reference) => {\n if (trimUrl(reference).startsWith(\"#\")) return `url(\"${trimUrl(reference)}\")`;\n const { file, resolved } = requiredFile(context, basePath, reference);\n const dataUrl = asDataUrl(file, context);\n return `url(\"${context.deferred === undefined ? dataUrl : parkUrl(context.deferred, dataUrl)}${resolved.fragment}\")`;\n },\n );\n}\n\nfunction serializeSrcset(value: string, basePath: string, context: TransformContext): string {\n return value.split(\",\").map((candidate) => {\n const trimmed = candidate.trim();\n const separator = trimmed.search(/\\s/);\n const reference = separator === -1 ? trimmed : trimmed.slice(0, separator);\n const descriptor = separator === -1 ? \"\" : trimmed.slice(separator).trim();\n const { file, resolved } = requiredFile(context, basePath, reference);\n return `${asDataUrl(file, context)}${resolved.fragment}${descriptor.length === 0 ? \"\" : ` ${descriptor}`}`;\n }).join(\", \");\n}\n\nconst CHILD_BOOTSTRAP = `(function(){\n \"use strict\";\n document.addEventListener(\"click\",function(event){\n var target=event.target instanceof Element?event.target.closest(\"a[data-tc-artifact-path]\"):null;\n if(!target)return;\n event.preventDefault();\n window.parent.postMessage({type:\"navigate\",path:target.getAttribute(\"data-tc-artifact-path\"),fragment:target.getAttribute(\"data-tc-artifact-fragment\")||\"\"},\"*\");\n },true);\n window.addEventListener(\"message\",function(event){\n if(event.source!==window.parent||event.origin!==\"null\"||!event.data||event.data.type!==\"artifact-fragment\"||typeof event.data.fragment!==\"string\")return;\n var fragment=event.data.fragment;\n if(!/^#[^\\\\u0000-\\\\u001f\\\\u007f]{1,1024}$/.test(fragment))return;\n try{var target=document.getElementById(decodeURIComponent(fragment.slice(1)));if(target)target.scrollIntoView();}catch(_){}\n });\n window.parent.postMessage({type:\"artifact-ready\"},\"*\");\n})();`;\n\nconst INNER_CSP = [\n \"default-src 'none'\",\n \"script-src 'unsafe-inline'\",\n \"style-src 'unsafe-inline'\",\n \"img-src data: blob:\",\n \"font-src data: blob:\",\n \"media-src data: blob:\",\n \"connect-src 'none'\",\n \"frame-src 'none'\",\n \"child-src 'none'\",\n \"object-src 'none'\",\n \"base-uri 'none'\",\n \"form-action 'none'\",\n].join(\"; \");\n\nasync function transformHtml(path: string, file: ArtifactFile, context: TransformContext): Promise<string> {\n const text = decodeText(file);\n // Before the DOM parser sees the page: the comment and attribute limits, which keep it from being given a page it would\n // take minutes to parse.\n scanMarkup(text, { references: false });\n const doc = context.parseHtml(text);\n const roots = documentRoots(doc);\n const deferred = newDeferred();\n if (doc.querySelector(\"parsererror\") !== null) fail(\"malformed\", \"artifact html is malformed\");\n // `noscript` is refused outright: a parser with scripting off (jsdom's) and the viewer's frame (scripting on) read its\n // content differently, so what is in it cannot be checked consistently.\n if (queryAll(roots, BLOCKED_ELEMENTS).length > 0) {\n fail(\"unsupported\", \"artifact contains a blocked html feature\");\n }\n rejectEventHandlerAttributes(roots);\n rejectSvgResourceReferences(roots);\n const inlineStyles = queryAll<HTMLStyleElement>(roots, \"style\");\n // Every author `<meta http-equiv>` is dropped: they act like response headers (`refresh`, `Link`, `Set-Cookie`, the author's own\n // Content-Security-Policy), and the finished page carries only the rewriter's own policy.\n for (const meta of queryAll<HTMLMetaElement>(roots, \"meta[http-equiv]\")) meta.remove();\n for (const link of queryAll<HTMLLinkElement>(roots, \"link[href]\")) {\n const relation = classifyLinkRelation(link.getAttribute(\"rel\"));\n if (relation === \"stylesheet\") {\n const { file: stylesheet, resolved } = requiredFile(context, path, link.getAttribute(\"href\") ?? \"\");\n const style = doc.createElement(\"style\");\n style.textContent = wrapMediaCss(await transformCss(decodeText(stylesheet, context), resolved.path, { ...context, cssStack: [resolved.path] }), link.getAttribute(\"media\"));\n link.replaceWith(style);\n continue;\n }\n if (relation === \"icon\") {\n const { file: icon, resolved } = requiredFile(context, path, link.getAttribute(\"href\") ?? \"\");\n link.href = `${asDataUrl(icon, context)}${resolved.fragment}`;\n continue;\n }\n fail(\"unsupported\", \"artifact contains an unsupported link relation\");\n }\n for (const style of inlineStyles) {\n style.textContent = wrapMediaCss(await transformCss(style.textContent ?? \"\", path, { ...context, cssStack: [] }), style.getAttribute(\"media\"));\n }\n for (const element of queryAll<HTMLElement>(roots, \"[style]\")) {\n const value = element.getAttribute(\"style\");\n if (value !== null) element.setAttribute(\"style\", await transformCss(value, path, { ...context, cssStack: [], deferred }));\n }\n for (const script of queryAll<HTMLScriptElement>(roots, \"script\")) {\n // `getAttribute`, not `script.type`: an SVG `<script>` has no `type` property in every DOM (jsdom has no SVGScriptElement).\n if ((script.getAttribute(\"type\") ?? \"\").trim().toLowerCase() === \"module\" || script.hasAttribute(\"async\") || script.hasAttribute(\"defer\")) {\n fail(\"unsupported\", \"artifact uses an unsupported script mode\");\n }\n if (!isJavaScriptType(script.getAttribute(\"type\"))) fail(\"unsupported\", \"artifact uses a script type that is not JavaScript\");\n let source = script.textContent ?? \"\";\n const reference = script.getAttribute(\"src\");\n if (reference !== null) {\n const { file: scriptFile } = requiredFile(context, path, reference);\n source = decodeText(scriptFile, context);\n script.removeAttribute(\"src\");\n }\n assertClassicScript(source);\n script.textContent = source.replace(/<\\/script/gi, \"<\\\\/script\");\n }\n const resourceAttributes: ReadonlyArray<readonly [string, string]> = [\n [\"img[src]\", \"src\"], [\"source[src]\", \"src\"], [\"video[src]\", \"src\"], [\"video[poster]\", \"poster\"],\n [\"audio[src]\", \"src\"], [\"track[src]\", \"src\"], [\"input[type=image][src]\", \"src\"],\n ];\n for (const [selector, attribute] of resourceAttributes) {\n for (const element of queryAll<HTMLElement>(roots, selector)) {\n const reference = element.getAttribute(attribute);\n if (reference === null) continue;\n const { file: resource, resolved } = requiredFile(context, path, reference);\n element.setAttribute(attribute, `${asDataUrl(resource, context)}${resolved.fragment}`);\n }\n }\n for (const element of queryAll<HTMLElement>(roots, \"[srcset]\")) {\n const value = element.getAttribute(\"srcset\");\n if (value !== null) element.setAttribute(\"srcset\", serializeSrcset(value, path, context));\n }\n for (const anchor of queryAll<HTMLAnchorElement>(roots, \"a[href]\")) {\n anchor.removeAttribute(\"target\");\n anchor.removeAttribute(\"download\");\n const reference = anchor.getAttribute(\"href\") ?? \"\";\n if (reference.startsWith(\"#\")) continue;\n const resolved = resolveReferenceFrom(path, reference);\n if (context.singlePage) throw new ArtifactBundleError(\"unsupported\", \"artifact links to another page\", path, reference);\n if (!context.files.has(resolved.path) || !/\\.html?$/i.test(resolved.path)) fail(\"unsupported\", \"artifact link leaves its html bundle\");\n anchor.href = \"#\";\n anchor.dataset.tcArtifactPath = resolved.path;\n if (resolved.fragment.length > 0) anchor.dataset.tcArtifactFragment = resolved.fragment;\n }\n const head = doc.head ?? doc.documentElement.insertBefore(doc.createElement(\"head\"), doc.body);\n const csp = doc.createElement(\"meta\");\n csp.httpEquiv = \"Content-Security-Policy\";\n csp.content = INNER_CSP;\n const bootstrap = doc.createElement(\"script\");\n bootstrap.textContent = CHILD_BOOTSTRAP;\n head.prepend(bootstrap);\n head.prepend(csp);\n const output = restoreParkedUrls(`<!DOCTYPE html>\\n${doc.documentElement.outerHTML}`, deferred);\n verifySelfContained(output, context);\n return output;\n}\n\nexport async function prepareHtmlArtifact(input: readonly ArtifactFile[], options: PrepareHtmlArtifactOptions = {}): Promise<PreparedArtifact> {\n if (input.length === 0) fail(\"malformed\", \"artifact bundle is empty\");\n if (input.length > MAX_ARTIFACT_FILES) fail(\"limit\", \"artifact has too many files\");\n const files = new Map<string, ArtifactFile>();\n const aliases = new Set<string>();\n let sourceBytes = 0;\n for (const candidate of input) {\n let path: string;\n try {\n path = canonicalArtifactPath(candidate.path);\n } catch (error) {\n if (error instanceof ArtifactBundleError) throw new ArtifactBundleError(error.kind, error.message, candidate.path);\n throw error;\n }\n const alias = path.toLowerCase();\n if (aliases.has(alias)) throw new ArtifactBundleError(\"malformed\", \"artifact paths collide after canonicalization\", path);\n aliases.add(alias);\n sourceBytes += candidate.bytes.byteLength;\n if (!Number.isSafeInteger(sourceBytes) || sourceBytes > MAX_ARTIFACT_SOURCE_BYTES) throw new ArtifactBundleError(\"limit\", \"artifact source exceeds limit\", path);\n files.set(path, { ...candidate, path });\n }\n const detection = detectHtmlArtifact([...files.keys()]);\n if (detection.kind !== \"html\") fail(\"malformed\", \"artifact root index is missing\");\n const renderBytes = [...files.values()]\n .filter((file) => /^(?:text\\/|application\\/(?:javascript|json)|image\\/svg\\+xml)/i.test(artifactMediaType(file.path, file.mediaType)))\n .reduce((total, file) => total + file.bytes.byteLength, 0);\n if (renderBytes > MAX_ARTIFACT_RENDER_BYTES) fail(\"limit\", \"artifact render aggregate exceeds limit\");\n const context: TransformContext = {\n files,\n cssStack: [],\n counter: { references: 0, inlinedBytes: 0 },\n parseHtml: options.parseHtml ?? defaultParseHtml,\n singlePage: options.singlePage === true,\n };\n const pages: Record<string, string> = {};\n let renderedBytes = 0;\n for (const [path, file] of files) {\n if (!/\\.html?$/i.test(path)) continue;\n if (context.singlePage && path !== ARTIFACT_ENTRY) continue;\n let page: string;\n try {\n page = await transformHtml(path, file, context);\n } catch (error) {\n if (error instanceof ArtifactBundleError && error.path === undefined) throw new ArtifactBundleError(error.kind, error.message, path, error.reference);\n throw error;\n }\n renderedBytes += new TextEncoder().encode(page).byteLength;\n if (!Number.isSafeInteger(renderedBytes) || renderedBytes > MAX_ARTIFACT_RENDER_BYTES) {\n fail(\"limit\", \"artifact rendered output exceeds limit\");\n }\n pages[path] = page;\n }\n return { entry: ARTIFACT_ENTRY, pages: Object.freeze(pages), fileCount: files.size, sourceBytes };\n}\n","import {\n ARTIFACT_ENTRY,\n ArtifactBundleError,\n MAX_ARTIFACT_FILES,\n MAX_ARTIFACT_SOURCE_BYTES,\n canonicalArtifactPath,\n prepareHtmlArtifact,\n type ArtifactFile,\n type PrepareHtmlArtifactOptions,\n} from \"./bundle.js\";\n\n/**\n * Passive files (the T8 \"artifact to app\" hook). A folder published as one self-contained page may also carry a\n * `manifest.json` at its root and files under `knowledge/`. They describe the page (an app manifest, its knowledge\n * bundle); they are not part of it. `inlineHtmlFolder` therefore never inlines them, never lets the page reference them\n * (a reference to one is refused like any missing file), and hands them back, unchanged, in `passive`, for a publisher\n * that can store sidecar files next to the page. This module defines the split only: it does not store anything.\n *\n * The match is on the canonical path and case-insensitive, like the path-collision rule, so `Knowledge/a.md` and\n * `MANIFEST.JSON` are passive as well.\n */\nexport function isPassiveArtifactPath(canonicalPath: string): boolean {\n const lower = canonicalPath.toLowerCase();\n return lower === \"manifest.json\" || lower.startsWith(\"knowledge/\");\n}\n\nexport interface InlinedHtmlFolder {\n readonly entry: typeof ARTIFACT_ENTRY;\n /** The one self-contained document (UTF-8). Self-contained: it fetches nothing and links nowhere at render time (see `docs/share-html-bundle.md`). */\n readonly html: Uint8Array;\n /** `manifest.json` and `knowledge/**`, byte for byte, in path order. See `isPassiveArtifactPath`. */\n readonly passive: readonly ArtifactFile[];\n /** Every file the folder held, passive ones included. */\n readonly fileCount: number;\n readonly sourceBytes: number;\n}\n\nfunction canonicalWithPath(path: string): string {\n try {\n return canonicalArtifactPath(path);\n } catch (error) {\n if (error instanceof ArtifactBundleError) throw new ArtifactBundleError(error.kind, error.message, path);\n throw error;\n }\n}\n\n/**\n * Inline a folder (a root `index.html` and the files it uses) into one self-contained HTML document, under the rules of\n * `prepareHtmlArtifact` and with `singlePage`: the stylesheets, scripts, images and fonts the page uses are inlined as\n * `<style>`, `<script>` and `data:` URLs, and everything else is refused (external references, `<base>`, frames,\n * forms, event-handler attributes, modules, links to other pages, ...). Files the page does not use are left out. Nothing\n * outside `files` is read.\n *\n * Refusals are `ArtifactBundleError`s; `path` and `reference` name the offending input.\n */\nexport async function inlineHtmlFolder(files: readonly ArtifactFile[], options: Omit<PrepareHtmlArtifactOptions, \"singlePage\"> = {}): Promise<InlinedHtmlFolder> {\n if (files.length === 0) throw new ArtifactBundleError(\"malformed\", \"artifact bundle is empty\");\n if (files.length > MAX_ARTIFACT_FILES) throw new ArtifactBundleError(\"limit\", \"artifact has too many files\");\n const canonical = new Map<string, ArtifactFile>();\n const aliases = new Map<string, string>();\n let sourceBytes = 0;\n for (const candidate of files) {\n const path = canonicalWithPath(candidate.path);\n const alias = path.toLowerCase();\n if (aliases.has(alias)) throw new ArtifactBundleError(\"malformed\", \"artifact paths collide after canonicalization\", path);\n aliases.set(alias, path);\n sourceBytes += candidate.bytes.byteLength;\n if (!Number.isSafeInteger(sourceBytes) || sourceBytes > MAX_ARTIFACT_SOURCE_BYTES) {\n throw new ArtifactBundleError(\"limit\", \"artifact source exceeds limit\", path);\n }\n canonical.set(path, { ...candidate, path });\n }\n if (!canonical.has(ARTIFACT_ENTRY)) throw new ArtifactBundleError(\"missing\", \"artifact root index is missing\", ARTIFACT_ENTRY);\n const active: ArtifactFile[] = [];\n const passive: ArtifactFile[] = [];\n for (const file of canonical.values()) (isPassiveArtifactPath(file.path) ? passive : active).push(file);\n const prepared = await prepareHtmlArtifact(active, { ...options, singlePage: true });\n passive.sort((left, right) => (left.path < right.path ? -1 : left.path > right.path ? 1 : 0));\n return {\n entry: ARTIFACT_ENTRY,\n html: new TextEncoder().encode(prepared.pages[ARTIFACT_ENTRY]!),\n passive,\n fileCount: canonical.size,\n sourceBytes,\n };\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tinycloud/share-sdk",
3
- "version": "1.2.0-beta.6",
3
+ "version": "1.2.0",
4
4
  "description": "Canonical headless TinyCloud Share operations for browser and Node.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -21,6 +21,12 @@
21
21
  "require": "./dist/artifact.cjs",
22
22
  "default": "./dist/artifact.js"
23
23
  },
24
+ "./html-bundle": {
25
+ "types": "./dist/html-bundle.d.ts",
26
+ "import": "./dist/html-bundle.js",
27
+ "require": "./dist/html-bundle.cjs",
28
+ "default": "./dist/html-bundle.js"
29
+ },
24
30
  "./share-root": {
25
31
  "types": "./dist/share-root.d.ts",
26
32
  "browser": "./dist/share-root.js",
@@ -48,11 +54,12 @@
48
54
  "dependencies": {
49
55
  "@noble/curves": "^1.9.2",
50
56
  "@noble/hashes": "^1.8.0",
51
- "@tinycloud/share-envelope": "1.2.0-beta.0",
57
+ "@tinycloud/share-envelope": "1.2.0",
52
58
  "multiformats": "^13.3.6"
53
59
  },
54
60
  "devDependencies": {
55
61
  "@types/node": "^20",
62
+ "jsdom": "26.1.0",
56
63
  "tsup": "^8.0.0",
57
64
  "typescript": "^5.9.3",
58
65
  "vitest": "^3.2.4"