@artinstack/migrator 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +30 -1
- package/dist/{chunk-CIOYDRY5.js → chunk-ALLFBWBO.js} +115 -2
- package/dist/chunk-ALLFBWBO.js.map +1 -0
- package/dist/{chunk-XQVKA54A.js → chunk-CB5KRANW.js} +247 -59
- package/dist/chunk-CB5KRANW.js.map +1 -0
- package/dist/chunk-EJTWYEAX.js +1 -0
- package/dist/chunk-EJTWYEAX.js.map +1 -0
- package/dist/{chunk-EXYXTAZM.js → chunk-KYNKJ4XV.js} +39 -6
- package/dist/chunk-KYNKJ4XV.js.map +1 -0
- package/dist/{chunk-XYP3VYDH.js → chunk-WHGUE5FC.js} +111 -3
- package/dist/chunk-WHGUE5FC.js.map +1 -0
- package/dist/chunk-XRCF73DA.js +24 -0
- package/dist/chunk-XRCF73DA.js.map +1 -0
- package/dist/{chunk-IPYHS5R2.js → chunk-Z3L6N63Y.js} +45 -34
- package/dist/chunk-Z3L6N63Y.js.map +1 -0
- package/dist/cli/index.js +7 -5
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +5 -17
- package/dist/index.js +38 -9
- package/dist/lib/index.d.ts +7 -25
- package/dist/lib/index.js +32 -3
- package/dist/media-urls-w46-CWUp.d.ts +74 -0
- package/dist/rewrite-inline-images-DyxKUNs3.d.ts +45 -0
- package/dist/sinks/index.d.ts +3 -2
- package/dist/sinks/index.js +4 -3
- package/dist/transformers/index.d.ts +15 -2
- package/dist/transformers/index.js +11 -4
- package/package.json +1 -1
- package/dist/chunk-CIOYDRY5.js.map +0 -1
- package/dist/chunk-EXYXTAZM.js.map +0 -1
- package/dist/chunk-IPYHS5R2.js.map +0 -1
- package/dist/chunk-XQVKA54A.js.map +0 -1
- package/dist/chunk-XYP3VYDH.js.map +0 -1
- package/dist/rewrite-inline-images-DPoxyzVC.d.ts +0 -21
package/README.md
CHANGED
|
@@ -15,7 +15,9 @@ src/
|
|
|
15
15
|
normalizer/ Canonical DTOs + portable idempotency types
|
|
16
16
|
sinks/ filesystem export, MigrationSink interface
|
|
17
17
|
cli/ artinstack-migrate
|
|
18
|
-
transformers/ HtmlToGrapes, css-to-styles, rewrite
|
|
18
|
+
transformers/ HtmlToGrapes, css-to-styles, inline image rewrite, media ref expand
|
|
19
|
+
lib/ media-urls, utility (shared helpers)
|
|
20
|
+
test/ unit tests (mirrors src/ layout; vitest only)
|
|
19
21
|
```
|
|
20
22
|
|
|
21
23
|
## Install
|
|
@@ -114,6 +116,31 @@ Each file contains an array of normalized DTOs (`NormalizedPost`, `NormalizedPag
|
|
|
114
116
|
|
|
115
117
|
Per-platform export file formats and API client usage are documented in [docs/architecture.md](./docs/architecture.md).
|
|
116
118
|
|
|
119
|
+
## Migration media refs
|
|
120
|
+
|
|
121
|
+
WordPress `contentHtml` is stamped with `artinstack-migration://asset/…` refs by default (not CDN URLs). Rationale, ref format, and OSS/host split: [docs/architecture.md § Migration media refs](./docs/architecture.md#migration-media-refs).
|
|
122
|
+
|
|
123
|
+
**Host — expand refs before persist** (`htmlToGrapes`, hero promotion, sink write):
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import {
|
|
127
|
+
expandMigrationMediaRefs,
|
|
128
|
+
formatMigrationMediaRef,
|
|
129
|
+
isMigrationMediaRef,
|
|
130
|
+
parseMigrationMediaRef,
|
|
131
|
+
rewriteInlineImages,
|
|
132
|
+
stampMigrationMediaRefs,
|
|
133
|
+
} from "@artinstack/migrator";
|
|
134
|
+
|
|
135
|
+
const { html, unresolved } = expandMigrationMediaRefs(contentHtml, (sourceId) =>
|
|
136
|
+
lookupPublicUrl(sourceId), // migration_entities → CDN
|
|
137
|
+
);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
**CLI / JSON export:** use `--rewrite-gateway` + `--rewrite-public` so gateway uploads normalize before refs are stamped. Unresolved upload URLs stay in HTML and appear in `conflicts.json` as `unresolvedInlineImages`.
|
|
141
|
+
|
|
142
|
+
**Tests:** `fixtures/wordpress/pages-export.test.ts` (naikonpixels pages WXR).
|
|
143
|
+
|
|
117
144
|
## Development
|
|
118
145
|
|
|
119
146
|
```bash
|
|
@@ -129,6 +156,8 @@ pnpm dev # watch build
|
|
|
129
156
|
|-------|------------------------|------------------|
|
|
130
157
|
| Parsers + normalizer DTOs | Yes | No |
|
|
131
158
|
| WordPress builder flattening + origin URL rewrite (pre-DTO) | Yes | Optional same config on adapter input |
|
|
159
|
+
| Stamp `artinstack-migration://asset/…` refs in content HTML | Yes | No |
|
|
160
|
+
| Expand refs → CDN URLs at persist | Exported helper | Call site + DB lookup |
|
|
132
161
|
| CLI + filesystem JSON export | Yes | No |
|
|
133
162
|
| `MigrationSink` interface | Yes | Implementation |
|
|
134
163
|
| Dynamic shortcodes (`[portfolio]`, `[recent_posts]`), forms, sanitize | No | Yes |
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isMigrationMediaRef,
|
|
3
|
+
parseMigrationMediaRef
|
|
4
|
+
} from "./chunk-WHGUE5FC.js";
|
|
5
|
+
|
|
1
6
|
// src/transformers/html-to-grapes/index.ts
|
|
2
7
|
import * as cheerio from "cheerio";
|
|
3
8
|
|
|
@@ -98,6 +103,10 @@ var DEFAULT_TYPES = {
|
|
|
98
103
|
img: "image"
|
|
99
104
|
};
|
|
100
105
|
var LAYOUT_DATA_ATTR = "data-layout";
|
|
106
|
+
var WP_WIDGET_ATTR = "data-wp-widget";
|
|
107
|
+
var DEFAULT_WP_WIDGET_TYPE = "wp-widget";
|
|
108
|
+
var EMBED_IFRAME_TYPE = "embed";
|
|
109
|
+
var EMBED_IFRAME_SRC = /google\.com\/maps\/embed|youtube\.com\/embed|youtube-nocookie\.com\/embed|player\.vimeo\.com\/video/i;
|
|
101
110
|
var DEFAULT_LAYOUT_TYPE_MAP = {
|
|
102
111
|
section: "section",
|
|
103
112
|
row: "row",
|
|
@@ -111,6 +120,17 @@ function parseLayoutKind(attributes) {
|
|
|
111
120
|
function resolveLayoutComponentType(kind, options) {
|
|
112
121
|
return options.layoutTypeMap?.[kind] ?? DEFAULT_LAYOUT_TYPE_MAP[kind];
|
|
113
122
|
}
|
|
123
|
+
function resolveWidgetComponentType(options) {
|
|
124
|
+
return options.widgetComponentType ?? DEFAULT_WP_WIDGET_TYPE;
|
|
125
|
+
}
|
|
126
|
+
function isWpWidgetMarker(attributes) {
|
|
127
|
+
return Boolean(attributes?.[WP_WIDGET_ATTR]);
|
|
128
|
+
}
|
|
129
|
+
function isPreservedEmbedIframe(tagName, attributes) {
|
|
130
|
+
if (tagName !== "iframe") return false;
|
|
131
|
+
const src = attributes?.src ?? "";
|
|
132
|
+
return EMBED_IFRAME_SRC.test(src);
|
|
133
|
+
}
|
|
114
134
|
function layoutAttributesForComponent(attributes) {
|
|
115
135
|
if (!attributes) return void 0;
|
|
116
136
|
const { [LAYOUT_DATA_ATTR]: _layout, ...rest } = attributes;
|
|
@@ -213,6 +233,25 @@ function walkNode($, $el, options) {
|
|
|
213
233
|
}
|
|
214
234
|
return component2;
|
|
215
235
|
}
|
|
236
|
+
if (isWpWidgetMarker(meta.attributes)) {
|
|
237
|
+
return applyElementMeta(
|
|
238
|
+
{
|
|
239
|
+
type: resolveWidgetComponentType(options),
|
|
240
|
+
tagName
|
|
241
|
+
},
|
|
242
|
+
meta
|
|
243
|
+
);
|
|
244
|
+
}
|
|
245
|
+
if (isPreservedEmbedIframe(tagName, meta.attributes)) {
|
|
246
|
+
return applyElementMeta(
|
|
247
|
+
{
|
|
248
|
+
type: EMBED_IFRAME_TYPE,
|
|
249
|
+
tagName,
|
|
250
|
+
void: true
|
|
251
|
+
},
|
|
252
|
+
meta
|
|
253
|
+
);
|
|
254
|
+
}
|
|
216
255
|
if (VOID_TAGS.has(tagName)) {
|
|
217
256
|
return applyElementMeta(
|
|
218
257
|
{
|
|
@@ -835,6 +874,79 @@ function validateTiptapDoc(doc, options = {}) {
|
|
|
835
874
|
return { ok: true, issues: [] };
|
|
836
875
|
}
|
|
837
876
|
|
|
877
|
+
// src/transformers/expand-migration-media-refs.ts
|
|
878
|
+
import * as cheerio3 from "cheerio";
|
|
879
|
+
var BACKGROUND_IMAGE_URL_PATTERN = /background(?:-image)?\s*:[^;]*?url\s*\(\s*(['"]?)([^'")]+)\1\s*\)/gi;
|
|
880
|
+
function tryExpandRef(value, resolvePublicUrl, unresolved) {
|
|
881
|
+
if (!isMigrationMediaRef(value)) return void 0;
|
|
882
|
+
const sourceId = parseMigrationMediaRef(value);
|
|
883
|
+
if (!sourceId) {
|
|
884
|
+
unresolved.add(value);
|
|
885
|
+
return void 0;
|
|
886
|
+
}
|
|
887
|
+
const publicUrl = resolvePublicUrl(sourceId);
|
|
888
|
+
if (!publicUrl) {
|
|
889
|
+
unresolved.add(value);
|
|
890
|
+
return void 0;
|
|
891
|
+
}
|
|
892
|
+
return publicUrl;
|
|
893
|
+
}
|
|
894
|
+
function expandBackgroundUrlsInStyle(style, resolvePublicUrl, unresolved) {
|
|
895
|
+
return style.replace(BACKGROUND_IMAGE_URL_PATTERN, (full, quote, rawUrl) => {
|
|
896
|
+
const expanded = tryExpandRef(rawUrl.trim(), resolvePublicUrl, unresolved);
|
|
897
|
+
if (!expanded) return full;
|
|
898
|
+
const urlCall = quote ? `url(${quote}${expanded}${quote})` : `url(${expanded})`;
|
|
899
|
+
return full.replace(/url\s*\(\s*(['"]?)([^'")]+)\1\s*\)/i, urlCall);
|
|
900
|
+
});
|
|
901
|
+
}
|
|
902
|
+
function expandSrcset(srcset, resolvePublicUrl, unresolved) {
|
|
903
|
+
return srcset.split(",").map((entry) => {
|
|
904
|
+
const trimmed = entry.trim();
|
|
905
|
+
if (!trimmed) return entry;
|
|
906
|
+
const [urlPart, descriptor] = trimmed.split(/\s+/, 2);
|
|
907
|
+
const expanded = tryExpandRef(urlPart ?? "", resolvePublicUrl, unresolved);
|
|
908
|
+
if (!expanded) return entry;
|
|
909
|
+
return descriptor ? `${expanded} ${descriptor}` : expanded;
|
|
910
|
+
}).join(", ");
|
|
911
|
+
}
|
|
912
|
+
function expandMigrationMediaRefs(html, resolvePublicUrl) {
|
|
913
|
+
if (!html.trim()) {
|
|
914
|
+
return { html, unresolved: [] };
|
|
915
|
+
}
|
|
916
|
+
const $ = cheerio3.load(html, { xml: false });
|
|
917
|
+
const unresolved = /* @__PURE__ */ new Set();
|
|
918
|
+
$("img").each((_, element) => {
|
|
919
|
+
const img = $(element);
|
|
920
|
+
const src = img.attr("src")?.trim();
|
|
921
|
+
if (src) {
|
|
922
|
+
const expanded = tryExpandRef(src, resolvePublicUrl, unresolved);
|
|
923
|
+
if (expanded) img.attr("src", expanded);
|
|
924
|
+
}
|
|
925
|
+
const srcset = img.attr("srcset")?.trim();
|
|
926
|
+
if (srcset) {
|
|
927
|
+
img.attr("srcset", expandSrcset(srcset, resolvePublicUrl, unresolved));
|
|
928
|
+
}
|
|
929
|
+
});
|
|
930
|
+
$("[data-bg-image]").each((_, element) => {
|
|
931
|
+
const node = $(element);
|
|
932
|
+
const bgImage = node.attr("data-bg-image")?.trim();
|
|
933
|
+
if (!bgImage) return;
|
|
934
|
+
const expanded = tryExpandRef(bgImage, resolvePublicUrl, unresolved);
|
|
935
|
+
if (expanded) node.attr("data-bg-image", expanded);
|
|
936
|
+
});
|
|
937
|
+
$("[style]").each((_, element) => {
|
|
938
|
+
const node = $(element);
|
|
939
|
+
const style = node.attr("style");
|
|
940
|
+
if (!style?.includes("background")) return;
|
|
941
|
+
const rewritten = expandBackgroundUrlsInStyle(style, resolvePublicUrl, unresolved);
|
|
942
|
+
if (rewritten !== style) node.attr("style", rewritten);
|
|
943
|
+
});
|
|
944
|
+
return {
|
|
945
|
+
html: $.root().html() ?? html,
|
|
946
|
+
unresolved: [...unresolved]
|
|
947
|
+
};
|
|
948
|
+
}
|
|
949
|
+
|
|
838
950
|
export {
|
|
839
951
|
cssToStyles,
|
|
840
952
|
htmlToGrapes,
|
|
@@ -846,6 +958,7 @@ export {
|
|
|
846
958
|
tiptapMarkSchema,
|
|
847
959
|
tiptapNodeSchema,
|
|
848
960
|
tiptapDocSchema,
|
|
849
|
-
validateTiptapDoc
|
|
961
|
+
validateTiptapDoc,
|
|
962
|
+
expandMigrationMediaRefs
|
|
850
963
|
};
|
|
851
|
-
//# sourceMappingURL=chunk-
|
|
964
|
+
//# sourceMappingURL=chunk-ALLFBWBO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/transformers/html-to-grapes/index.ts","../src/transformers/css-to-styles/index.ts","../src/transformers/html-to-grapes/walk.ts","../src/transformers/html-to-tiptap/index.ts","../src/transformers/html-to-tiptap/walk.ts","../src/transformers/validate-snapshot.ts","../src/transformers/validate-tiptap-doc.ts","../src/transformers/expand-migration-media-refs.ts"],"sourcesContent":["import * as cheerio from \"cheerio\";\n\nimport { cssToStyles } from \"../css-to-styles/index.js\";\nimport type { GrapesProjectSnapshot, HtmlToGrapesOptions } from \"./types.js\";\nimport { walkHtmlToComponents } from \"./walk.js\";\n\nexport type {\n GrapesComponent,\n GrapesProjectSnapshot,\n GrapesStyleRule,\n HtmlToGrapesOptions,\n LayoutKind,\n LayoutTypeMap,\n} from \"./types.js\";\n\n/** Cheerio HTML walk → Grapes `content` + root `styles`. */\nexport function htmlToGrapes(html: string, options: HtmlToGrapesOptions = {}): GrapesProjectSnapshot {\n const trimmed = html.trim();\n if (!trimmed) {\n return { content: [], styles: [] };\n }\n\n const $ = cheerio.load(trimmed, { xml: false });\n const styleBlocks: string[] = [];\n\n $(\"style\").each((_, element) => {\n styleBlocks.push($(element).html() ?? \"\");\n $(element).remove();\n });\n\n const contentCss = styleBlocks.join(\"\\n\").trim();\n const styles = cssToStyles(contentCss);\n const content = walkHtmlToComponents($, options);\n const contentHtml = serializeContentHtml($);\n\n return {\n content,\n styles,\n ...(contentHtml ? { contentHtml } : {}),\n ...(contentCss ? { contentCss } : {}),\n };\n}\n\nfunction serializeContentHtml($: cheerio.CheerioAPI): string | undefined {\n const body = $(\"body\");\n if (body.length) {\n const html = body.html()?.trim();\n return html || undefined;\n }\n\n const rootHtml = $.root().html()?.trim();\n return rootHtml || undefined;\n}\n","import type { GrapesStyleRule } from \"../html-to-grapes/types.js\";\n\nfunction stripCssComments(css: string): string {\n return css.replace(/\\/\\*[\\s\\S]*?\\*\\//g, \"\");\n}\n\nfunction parseDeclarations(block: string): Record<string, string> {\n const style: Record<string, string> = {};\n for (const declaration of block.split(\";\")) {\n const trimmed = declaration.trim();\n if (!trimmed) continue;\n const separator = trimmed.indexOf(\":\");\n if (separator === -1) continue;\n const property = trimmed.slice(0, separator).trim();\n const value = trimmed.slice(separator + 1).trim();\n if (!property || !value) continue;\n style[property] = value;\n }\n return style;\n}\n\n/** Parse `<style>` blocks and class rules into Grapes root `styles[]`. */\nexport function cssToStyles(css: string): GrapesStyleRule[] {\n const cleaned = stripCssComments(css);\n const rules: GrapesStyleRule[] = [];\n const rulePattern = /([^{]+)\\{([^}]*)\\}/g;\n\n for (const match of cleaned.matchAll(rulePattern)) {\n const selectorText = match[1]?.trim() ?? \"\";\n const declarationBlock = match[2] ?? \"\";\n if (!selectorText || selectorText.startsWith(\"@\")) continue;\n\n const style = parseDeclarations(declarationBlock);\n if (Object.keys(style).length === 0) continue;\n\n const selectors = selectorText\n .split(\",\")\n .map((selector) => selector.trim())\n .filter(Boolean);\n\n if (selectors.length === 0) continue;\n rules.push({ selectors, style });\n }\n\n return rules;\n}\n","import type { Cheerio, CheerioAPI } from \"cheerio\";\nimport type { AnyNode } from \"domhandler\";\n\nimport type { GrapesComponent, HtmlToGrapesOptions, LayoutKind } from \"./types.js\";\n\ntype CheerioSelection = Cheerio<AnyNode>;\n\nconst INLINE_TAGS = new Set([\n \"a\",\n \"abbr\",\n \"b\",\n \"br\",\n \"cite\",\n \"code\",\n \"del\",\n \"em\",\n \"i\",\n \"img\",\n \"ins\",\n \"mark\",\n \"q\",\n \"s\",\n \"small\",\n \"span\",\n \"strong\",\n \"sub\",\n \"sup\",\n \"u\",\n \"wbr\",\n]);\n\nconst VOID_TAGS = new Set([\n \"area\",\n \"base\",\n \"br\",\n \"col\",\n \"embed\",\n \"hr\",\n \"img\",\n \"input\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n\nconst TEXT_CONTAINER_TAGS = new Set([\n \"blockquote\",\n \"figcaption\",\n \"h1\",\n \"h2\",\n \"h3\",\n \"h4\",\n \"h5\",\n \"h6\",\n \"label\",\n \"li\",\n \"p\",\n \"pre\",\n \"td\",\n \"th\",\n]);\n\nconst SKIP_TAGS = new Set([\"script\", \"style\", \"noscript\", \"template\"]);\n\nconst DEFAULT_TYPES: Record<string, string> = {\n a: \"link\",\n img: \"image\",\n};\n\nconst LAYOUT_DATA_ATTR = \"data-layout\";\nconst WP_WIDGET_ATTR = \"data-wp-widget\";\nconst DEFAULT_WP_WIDGET_TYPE = \"wp-widget\";\nconst EMBED_IFRAME_TYPE = \"embed\";\n\nconst EMBED_IFRAME_SRC =\n /google\\.com\\/maps\\/embed|youtube\\.com\\/embed|youtube-nocookie\\.com\\/embed|player\\.vimeo\\.com\\/video/i;\n\nconst DEFAULT_LAYOUT_TYPE_MAP: Record<LayoutKind, string> = {\n section: \"section\",\n row: \"row\",\n column: \"column\",\n};\n\nfunction parseLayoutKind(attributes: Record<string, string> | undefined): LayoutKind | undefined {\n const value = attributes?.[LAYOUT_DATA_ATTR];\n if (value === \"section\" || value === \"row\" || value === \"column\") return value;\n return undefined;\n}\n\nfunction resolveLayoutComponentType(kind: LayoutKind, options: HtmlToGrapesOptions): string {\n return options.layoutTypeMap?.[kind] ?? DEFAULT_LAYOUT_TYPE_MAP[kind];\n}\n\nfunction resolveWidgetComponentType(options: HtmlToGrapesOptions): string {\n return options.widgetComponentType ?? DEFAULT_WP_WIDGET_TYPE;\n}\n\nfunction isWpWidgetMarker(attributes: Record<string, string> | undefined): boolean {\n return Boolean(attributes?.[WP_WIDGET_ATTR]);\n}\n\nfunction isPreservedEmbedIframe(\n tagName: string | undefined,\n attributes: Record<string, string> | undefined,\n): boolean {\n if (tagName !== \"iframe\") return false;\n const src = attributes?.src ?? \"\";\n return EMBED_IFRAME_SRC.test(src);\n}\n\nfunction layoutAttributesForComponent(\n attributes: Record<string, string> | undefined,\n): Record<string, string> | undefined {\n if (!attributes) return undefined;\n const { [LAYOUT_DATA_ATTR]: _layout, ...rest } = attributes;\n return Object.keys(rest).length > 0 ? rest : undefined;\n}\n\nfunction tagNameOf($el: CheerioSelection): string | undefined {\n const raw = $el.prop(\"tagName\");\n return typeof raw === \"string\" ? raw.toLowerCase() : undefined;\n}\n\nfunction applyElementMeta(\n component: GrapesComponent,\n meta: Pick<GrapesComponent, \"attributes\" | \"classes\">,\n): GrapesComponent {\n if (meta.attributes) component.attributes = meta.attributes;\n if (meta.classes) component.classes = meta.classes;\n return component;\n}\n\nfunction pickElementMeta($el: CheerioSelection): Pick<GrapesComponent, \"attributes\" | \"classes\"> {\n const attributes: Record<string, string> = {};\n const classes: string[] = [];\n\n if (typeof $el.attr() === \"object\") {\n for (const [key, value] of Object.entries($el.attr() ?? {})) {\n if (key === \"class\") {\n classes.push(...value.split(/\\s+/).filter(Boolean));\n continue;\n }\n attributes[key] = value;\n }\n }\n\n return {\n attributes: Object.keys(attributes).length > 0 ? attributes : undefined,\n classes: classes.length > 0 ? classes : undefined,\n };\n}\n\nfunction resolveComponentType(\n tagName: string,\n classes: string[] | undefined,\n options: HtmlToGrapesOptions,\n fallback = \"default\",\n): string {\n if (options.componentMap && classes) {\n for (const className of classes) {\n const mapped = options.componentMap[className];\n if (mapped) return mapped;\n }\n }\n const tagMapped = options.tagMap?.[tagName];\n if (tagMapped) return tagMapped;\n return DEFAULT_TYPES[tagName] ?? fallback;\n}\n\nfunction hasOnlyInlineContent($: CheerioAPI, $el: CheerioSelection): boolean {\n let inlineOnly = true;\n\n $el.contents().each((_, node) => {\n if (!inlineOnly) return;\n const $child = $(node);\n if ($child.get(0)?.type === \"text\") return;\n const childTag = tagNameOf($child);\n if (!childTag || !INLINE_TAGS.has(childTag)) {\n inlineOnly = false;\n return;\n }\n if (!hasOnlyInlineContent($, $child)) {\n inlineOnly = false;\n }\n });\n\n return inlineOnly;\n}\n\nfunction walkChildren(\n $: CheerioAPI,\n $el: CheerioSelection,\n options: HtmlToGrapesOptions,\n): GrapesComponent[] {\n const components: GrapesComponent[] = [];\n\n $el.contents().each((_, node) => {\n const walked = walkNode($, $(node), options);\n if (!walked) return;\n if (Array.isArray(walked)) {\n components.push(...walked);\n } else {\n components.push(walked);\n }\n });\n\n return components;\n}\n\nfunction walkNode(\n $: CheerioAPI,\n $el: CheerioSelection,\n options: HtmlToGrapesOptions,\n): GrapesComponent | GrapesComponent[] | null {\n const node = $el.get(0);\n if (!node) return null;\n\n if (node.type === \"text\") {\n const text = \"data\" in node ? String(node.data ?? \"\") : \"\";\n if (!text.trim()) return null;\n return { type: \"textnode\", content: text };\n }\n\n if (node.type !== \"tag\") return null;\n\n const tagName = tagNameOf($el);\n if (!tagName || SKIP_TAGS.has(tagName)) return null;\n\n const meta = pickElementMeta($el);\n\n const layoutKind = parseLayoutKind(meta.attributes);\n if (layoutKind) {\n const components = walkChildren($, $el, options);\n const component = applyElementMeta(\n {\n type: resolveLayoutComponentType(layoutKind, options),\n tagName,\n },\n {\n attributes: layoutAttributesForComponent(meta.attributes),\n classes: meta.classes,\n },\n );\n if (components.length > 0) {\n component.components = components;\n }\n return component;\n }\n\n // OSS-13 — atomic widget blocks (do not merge into preceding text / inline walks).\n if (isWpWidgetMarker(meta.attributes)) {\n return applyElementMeta(\n {\n type: resolveWidgetComponentType(options),\n tagName,\n },\n meta,\n );\n }\n\n if (isPreservedEmbedIframe(tagName, meta.attributes)) {\n return applyElementMeta(\n {\n type: EMBED_IFRAME_TYPE,\n tagName,\n void: true,\n },\n meta,\n );\n }\n\n if (VOID_TAGS.has(tagName)) {\n return applyElementMeta(\n {\n type: resolveComponentType(tagName, meta.classes, options),\n tagName,\n void: true,\n },\n meta,\n );\n }\n\n if (TEXT_CONTAINER_TAGS.has(tagName) && hasOnlyInlineContent($, $el)) {\n return applyElementMeta(\n {\n type: resolveComponentType(tagName, meta.classes, options, \"text\"),\n tagName,\n content: $el.html() ?? \"\",\n },\n meta,\n );\n }\n\n if (INLINE_TAGS.has(tagName)) {\n return applyElementMeta(\n {\n type: \"text\",\n content: $.html($el) ?? \"\",\n },\n meta,\n );\n }\n\n const components = walkChildren($, $el, options);\n const component = applyElementMeta(\n {\n type: resolveComponentType(tagName, meta.classes, options),\n tagName,\n },\n meta,\n );\n\n if (components.length > 0) {\n component.components = components;\n }\n\n return component;\n}\n\nfunction appendWalked(\n content: GrapesComponent[],\n walked: GrapesComponent | GrapesComponent[] | null,\n): void {\n if (!walked) return;\n if (Array.isArray(walked)) {\n content.push(...walked);\n return;\n }\n content.push(walked);\n}\n\nfunction walkNodes(\n $: CheerioAPI,\n $nodes: CheerioSelection,\n content: GrapesComponent[],\n options: HtmlToGrapesOptions,\n): void {\n $nodes.each((_, node) => {\n appendWalked(content, walkNode($, $(node), options));\n });\n}\n\nexport function walkHtmlToComponents(\n $: CheerioAPI,\n options: HtmlToGrapesOptions = {},\n): GrapesComponent[] {\n const content: GrapesComponent[] = [];\n const body = $(\"body\");\n\n if (body.length) {\n walkNodes($, body.contents(), content, options);\n return content;\n }\n\n const children = $.root().children();\n if (children.length) {\n walkNodes($, children, content, options);\n } else {\n walkNodes($, $.root().contents(), content, options);\n }\n\n return content;\n}\n","import * as cheerio from \"cheerio\";\n\nimport type { HtmlToTiptapOptions, TiptapDoc } from \"./types.js\";\nimport { prepareHtmlForTiptap, walkHtmlToTiptapDoc } from \"./walk.js\";\n\nexport type { HtmlToTiptapOptions, TiptapDoc, TiptapMark, TiptapNode } from \"./types.js\";\n\n/** Cheerio HTML walk → Tiptap / ProseMirror `doc` JSON for blog `content_json`. */\nexport function htmlToTiptap(html: string, options: HtmlToTiptapOptions = {}): TiptapDoc {\n const trimmed = html.trim();\n if (!trimmed) {\n return { type: \"doc\", content: [{ type: \"paragraph\" }] };\n }\n\n const $ = cheerio.load(trimmed, { xml: false });\n prepareHtmlForTiptap($);\n return walkHtmlToTiptapDoc($, options);\n}\n","import type { Cheerio, CheerioAPI } from \"cheerio\";\nimport type { AnyNode, Element } from \"domhandler\";\n\nimport type { HtmlToTiptapOptions, TiptapDoc, TiptapMark, TiptapNode } from \"./types.js\";\n\ntype CheerioSelection = Cheerio<AnyNode>;\n\nconst SKIP_TAGS = new Set([\"script\", \"style\", \"noscript\", \"template\"]);\nconst HEADING_TAGS = new Set([\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"]);\nconst UNWRAP_TAGS = new Set([\n \"article\",\n \"aside\",\n \"div\",\n \"figure\",\n \"footer\",\n \"header\",\n \"main\",\n \"nav\",\n \"section\",\n \"span\",\n]);\n\nconst INLINE_TAGS = new Set([\n \"a\",\n \"abbr\",\n \"b\",\n \"br\",\n \"cite\",\n \"code\",\n \"del\",\n \"em\",\n \"i\",\n \"ins\",\n \"mark\",\n \"q\",\n \"s\",\n \"small\",\n \"strong\",\n \"sub\",\n \"sup\",\n \"u\",\n \"wbr\",\n]);\n\nconst LAYOUT_ATTR = \"data-layout\";\n\nfunction tagNameOf($el: CheerioSelection): string | undefined {\n const raw = $el.prop(\"tagName\");\n return typeof raw === \"string\" ? raw.toLowerCase() : undefined;\n}\n\nfunction headingLevel(tagName: string): number {\n const level = Number.parseInt(tagName.slice(1), 10);\n return Number.isFinite(level) ? level : 1;\n}\n\nfunction isLayoutMarker($el: CheerioSelection, options: HtmlToTiptapOptions): boolean {\n if (options.unwrapLayoutMarkers === false) return false;\n return $el.attr(LAYOUT_ATTR) !== undefined;\n}\n\nfunction hasOnlyInlineContent($: CheerioAPI, $el: CheerioSelection): boolean {\n let inlineOnly = true;\n\n $el.contents().each((_, node) => {\n if (!inlineOnly) return;\n const $child = $(node);\n if ($child.get(0)?.type === \"text\") return;\n const childTag = tagNameOf($child);\n if (!childTag || childTag === \"br\" || childTag === \"img\") return;\n if (!INLINE_TAGS.has(childTag)) {\n inlineOnly = false;\n return;\n }\n if (!hasOnlyInlineContent($, $child)) {\n inlineOnly = false;\n }\n });\n\n return inlineOnly;\n}\n\nfunction hasBlockChild($: CheerioAPI, $el: CheerioSelection): boolean {\n let hasBlock = false;\n $el.contents().each((_, node) => {\n if (hasBlock) return;\n const $child = $(node);\n if ($child.get(0)?.type === \"text\") return;\n const childTag = tagNameOf($child);\n if (!childTag) return;\n if (\n HEADING_TAGS.has(childTag) ||\n childTag === \"p\" ||\n childTag === \"ul\" ||\n childTag === \"ol\" ||\n childTag === \"blockquote\" ||\n childTag === \"pre\" ||\n childTag === \"hr\" ||\n childTag === \"img\" ||\n childTag === \"table\" ||\n isLayoutMarker($child, { unwrapLayoutMarkers: true }) ||\n (UNWRAP_TAGS.has(childTag) && hasBlockChild($, $child))\n ) {\n hasBlock = true;\n }\n });\n return hasBlock;\n}\n\nfunction textNode(text: string, marks: TiptapMark[] = []): TiptapNode {\n const node: TiptapNode = { type: \"text\", text };\n if (marks.length > 0) node.marks = marks;\n return node;\n}\n\nfunction paragraph(content: TiptapNode[]): TiptapNode {\n return content.length > 0 ? { type: \"paragraph\", content } : { type: \"paragraph\" };\n}\n\nfunction appendMarks(existing: TiptapMark[], added: TiptapMark): TiptapMark[] {\n if (existing.some((mark) => mark.type === added.type)) return existing;\n return [...existing, added];\n}\n\nfunction marksForTag(tagName: string, $el: CheerioSelection): TiptapMark[] {\n switch (tagName) {\n case \"strong\":\n case \"b\":\n return [{ type: \"bold\" }];\n case \"em\":\n case \"i\":\n return [{ type: \"italic\" }];\n case \"s\":\n case \"del\":\n case \"strike\":\n return [{ type: \"strike\" }];\n case \"u\":\n return [{ type: \"underline\" }];\n case \"code\":\n return [{ type: \"code\" }];\n case \"a\": {\n const href = $el.attr(\"href\");\n if (!href) return [];\n const attrs: Record<string, string> = { href };\n const target = $el.attr(\"target\");\n if (target) attrs.target = target;\n const rel = $el.attr(\"rel\");\n if (rel) attrs.rel = rel;\n return [{ type: \"link\", attrs }];\n }\n default:\n return [];\n }\n}\n\nfunction imageNode($el: CheerioSelection): TiptapNode | null {\n const src = $el.attr(\"src\");\n if (!src) return null;\n const attrs: Record<string, unknown> = { src };\n const alt = $el.attr(\"alt\");\n if (alt !== undefined) attrs.alt = alt;\n const title = $el.attr(\"title\");\n if (title) attrs.title = title;\n return { type: \"image\", attrs };\n}\n\nfunction parseInlineContent(\n $: CheerioAPI,\n $el: CheerioSelection,\n marks: TiptapMark[] = [],\n): TiptapNode[] {\n const rootTag = tagNameOf($el);\n if (rootTag && INLINE_TAGS.has(rootTag) && rootTag !== \"br\") {\n marks = marksForTag(rootTag, $el).reduce((acc, mark) => appendMarks(acc, mark), marks);\n }\n\n const nodes: TiptapNode[] = [];\n\n $el.contents().each((_, node) => {\n if (node.type === \"text\") {\n const text = String(node.data ?? \"\");\n if (text) nodes.push(textNode(text, marks));\n return;\n }\n\n if (node.type !== \"tag\") return;\n\n const $child = $(node);\n const tagName = tagNameOf($child);\n if (!tagName || SKIP_TAGS.has(tagName)) return;\n\n if (tagName === \"br\") {\n nodes.push({ type: \"hardBreak\" });\n return;\n }\n\n if (tagName === \"img\") {\n return;\n }\n\n const childMarks = marksForTag(tagName, $child);\n const combinedMarks = childMarks.reduce((acc, mark) => appendMarks(acc, mark), [...marks]);\n nodes.push(...parseInlineContent($, $child, combinedMarks));\n });\n\n return nodes;\n}\n\n/** Parse a block container that holds inline content (p, heading, etc.). Splits on nested block/img. */\nfunction parseMixedBlockContent(\n $: CheerioAPI,\n $el: CheerioSelection,\n options: HtmlToTiptapOptions,\n): TiptapNode[] {\n const blocks: TiptapNode[] = [];\n let inlineBuffer: TiptapNode[] = [];\n\n function flushInline(): void {\n if (inlineBuffer.length === 0) return;\n blocks.push(paragraph(inlineBuffer));\n inlineBuffer = [];\n }\n\n $el.contents().each((_, node) => {\n if (node.type === \"text\") {\n const text = String(node.data ?? \"\");\n if (text) inlineBuffer.push(textNode(text));\n return;\n }\n\n if (node.type !== \"tag\") return;\n\n const $child = $(node);\n const tagName = tagNameOf($child);\n if (!tagName || SKIP_TAGS.has(tagName)) return;\n\n if (tagName === \"br\") {\n inlineBuffer.push({ type: \"hardBreak\" });\n return;\n }\n\n if (tagName === \"img\") {\n flushInline();\n const image = imageNode($child);\n if (image) blocks.push(image);\n return;\n }\n\n if (INLINE_TAGS.has(tagName)) {\n inlineBuffer.push(...parseInlineContent($, $child));\n return;\n }\n\n flushInline();\n blocks.push(...walkBlockNodes($, $child, options));\n });\n\n flushInline();\n return blocks;\n}\n\nfunction walkListItem($: CheerioAPI, $el: CheerioSelection, options: HtmlToTiptapOptions): TiptapNode {\n const blocks = walkBlockNodes($, $el, options);\n if (blocks.length === 0) {\n return { type: \"listItem\", content: [{ type: \"paragraph\" }] };\n }\n\n const normalized: TiptapNode[] = [];\n for (const block of blocks) {\n if (\n block.type === \"paragraph\" ||\n block.type === \"image\" ||\n block.type === \"blockquote\" ||\n block.type === \"bulletList\" ||\n block.type === \"orderedList\"\n ) {\n normalized.push(block);\n continue;\n }\n normalized.push(paragraph(block.content ?? []));\n }\n\n return { type: \"listItem\", content: normalized };\n}\n\nfunction walkBlockNode(\n $: CheerioAPI,\n $el: CheerioSelection,\n options: HtmlToTiptapOptions,\n): TiptapNode[] {\n const node = $el.get(0);\n if (!node) return [];\n\n if (node.type === \"text\") {\n const text = String(node.data ?? \"\").trim();\n return text ? [paragraph([textNode(text)])] : [];\n }\n\n if (node.type !== \"tag\") return [];\n\n const tagName = tagNameOf($el);\n if (!tagName || SKIP_TAGS.has(tagName)) return [];\n\n if (isLayoutMarker($el, options)) {\n return walkBlockNodes($, $el, options);\n }\n\n if (UNWRAP_TAGS.has(tagName)) {\n if (hasBlockChild($, $el)) {\n return walkBlockNodes($, $el, options);\n }\n if (hasOnlyInlineContent($, $el)) {\n const inline = parseInlineContent($, $el);\n return inline.length > 0 ? [paragraph(inline)] : [];\n }\n return walkBlockNodes($, $el, options);\n }\n\n if (HEADING_TAGS.has(tagName)) {\n const content = parseInlineContent($, $el);\n if (content.length === 0) return [];\n return [{ type: \"heading\", attrs: { level: headingLevel(tagName) }, content }];\n }\n\n if (tagName === \"p\") {\n return parseMixedBlockContent($, $el, options);\n }\n\n if (tagName === \"ul\") {\n const items: TiptapNode[] = [];\n $el.children(\"li\").each((_, li) => {\n items.push(walkListItem($, $(li), options));\n });\n return items.length > 0 ? [{ type: \"bulletList\", content: items }] : [];\n }\n\n if (tagName === \"ol\") {\n const items: TiptapNode[] = [];\n $el.children(\"li\").each((_, li) => {\n items.push(walkListItem($, $(li), options));\n });\n return items.length > 0 ? [{ type: \"orderedList\", content: items }] : [];\n }\n\n if (tagName === \"li\") {\n return [walkListItem($, $el, options)];\n }\n\n if (tagName === \"blockquote\") {\n const blocks = walkBlockNodes($, $el, options);\n if (blocks.length === 0) return [];\n return [{ type: \"blockquote\", content: blocks }];\n }\n\n if (tagName === \"pre\") {\n const code = $el.find(\"code\").first();\n const text = (code.length ? code.text() : $el.text()).replace(/\\n$/, \"\");\n if (!text) return [];\n return [{ type: \"codeBlock\", content: [textNode(text)] }];\n }\n\n if (tagName === \"hr\") {\n return [{ type: \"horizontalRule\" }];\n }\n\n if (tagName === \"img\") {\n const image = imageNode($el);\n return image ? [image] : [];\n }\n\n if (tagName === \"table\") {\n const rows: string[] = [];\n $el.find(\"tr\").each((_, tr) => {\n const cells: string[] = [];\n $(tr)\n .find(\"th, td\")\n .each((__, cell) => {\n const text = $(cell).text().trim();\n if (text) cells.push(text);\n });\n if (cells.length > 0) rows.push(cells.join(\" | \"));\n });\n return rows.map((row) => paragraph([textNode(row)]));\n }\n\n return walkBlockNodes($, $el, options);\n}\n\nfunction walkBlockNodes(\n $: CheerioAPI,\n $el: CheerioSelection,\n options: HtmlToTiptapOptions,\n): TiptapNode[] {\n const blocks: TiptapNode[] = [];\n\n $el.contents().each((_, node) => {\n blocks.push(...walkBlockNode($, $(node), options));\n });\n\n return blocks;\n}\n\nfunction normalizeDocContent(content: TiptapNode[]): TiptapNode[] {\n const normalized: TiptapNode[] = [];\n\n for (const block of content) {\n if (block.type === \"paragraph\" && (!block.content || block.content.length === 0)) {\n continue;\n }\n normalized.push(block);\n }\n\n return normalized;\n}\n\nexport function walkHtmlToTiptapDoc(\n $: CheerioAPI,\n options: HtmlToTiptapOptions = {},\n): TiptapDoc {\n const resolved: HtmlToTiptapOptions = {\n unwrapLayoutMarkers: options.unwrapLayoutMarkers ?? true,\n };\n\n let content: TiptapNode[] = [];\n const body = $(\"body\");\n\n if (body.length) {\n content = walkBlockNodes($, body, resolved);\n } else {\n const children = $.root().children();\n if (children.length) {\n content = walkBlockNodes($, children, resolved);\n } else {\n content = walkBlockNodes($, $.root(), resolved);\n }\n }\n\n content = normalizeDocContent(content);\n if (content.length === 0) {\n content = [{ type: \"paragraph\" }];\n }\n\n return { type: \"doc\", content };\n}\n\n/** Strip layout/style noise before walking (mutates loaded DOM). */\nexport function prepareHtmlForTiptap($: CheerioAPI): void {\n $(\"style, script, noscript, template\").remove();\n}\n\nexport function isElementNode(node: AnyNode): node is Element {\n return node.type === \"tag\";\n}\n","import { z } from \"zod\";\n\nimport type { ValidationIssue, ValidationResult } from \"../normalizer/types.js\";\nimport type { GrapesComponent, GrapesProjectSnapshot } from \"./html-to-grapes/types.js\";\n\nexport const grapesStyleRuleSchema = z.object({\n selectors: z.array(z.string().min(1)).min(1),\n style: z.record(z.string(), z.string()),\n});\n\nexport const grapesComponentSchema: z.ZodType<GrapesComponent> = z.lazy(() =>\n z.object({\n type: z.string().min(1),\n tagName: z.string().optional(),\n attributes: z.record(z.string(), z.string()).optional(),\n classes: z.array(z.string()).optional(),\n components: z.array(grapesComponentSchema).optional(),\n content: z.string().optional(),\n void: z.boolean().optional(),\n }),\n);\n\nexport const grapesProjectSnapshotSchema = z.object({\n content: z.array(grapesComponentSchema),\n styles: z.array(grapesStyleRuleSchema),\n contentHtml: z.string().optional(),\n contentCss: z.string().optional(),\n});\n\nexport interface ValidateGrapesProjectSnapshotOptions {\n /** When set, every component `type` in the tree must be in this allowlist. */\n allowedComponentTypes?: string[];\n}\n\nfunction zodIssuesToValidationIssues(issues: z.ZodIssue[]): ValidationIssue[] {\n return issues.map((issue) => ({\n code: issue.code,\n message: issue.message,\n path: issue.path.length > 0 ? issue.path.join(\".\") : undefined,\n }));\n}\n\nfunction collectComponentTypes(components: GrapesComponent[]): string[] {\n const types: string[] = [];\n for (const component of components) {\n types.push(component.type);\n if (component.components?.length) {\n types.push(...collectComponentTypes(component.components));\n }\n }\n return types;\n}\n\nfunction validateAllowedComponentTypes(\n snapshot: GrapesProjectSnapshot,\n allowedComponentTypes: string[],\n): ValidationIssue[] {\n const allowlist = new Set(allowedComponentTypes);\n const issues: ValidationIssue[] = [];\n\n for (const componentType of collectComponentTypes(snapshot.content)) {\n if (!allowlist.has(componentType)) {\n issues.push({\n code: \"invalid_component_type\",\n message: `Component type \"${componentType}\" is not in allowedComponentTypes`,\n path: \"content\",\n });\n }\n }\n\n return issues;\n}\n\n/**\n * Opt-in structural check for a Grapes project snapshot (not a full Grapes editor project file).\n * Does not validate host-specific component registries unless `allowedComponentTypes` is passed.\n */\nexport function validateGrapesProjectSnapshot(\n snapshot: unknown,\n options: ValidateGrapesProjectSnapshotOptions = {},\n): ValidationResult {\n const result = grapesProjectSnapshotSchema.safeParse(snapshot);\n if (!result.success) {\n return { ok: false, issues: zodIssuesToValidationIssues(result.error.issues) };\n }\n\n if (options.allowedComponentTypes?.length) {\n const typeIssues = validateAllowedComponentTypes(result.data, options.allowedComponentTypes);\n if (typeIssues.length > 0) {\n return { ok: false, issues: typeIssues };\n }\n }\n\n return { ok: true, issues: [] };\n}\n","import { z } from \"zod\";\n\nimport type { ValidationIssue, ValidationResult } from \"../normalizer/types.js\";\nimport type { TiptapDoc, TiptapNode } from \"./html-to-tiptap/types.js\";\n\nexport const tiptapMarkSchema = z.object({\n type: z.string().min(1),\n attrs: z.record(z.string(), z.string()).optional(),\n});\n\nexport const tiptapNodeSchema: z.ZodType<TiptapNode> = z.lazy(() =>\n z.union([\n z.object({\n type: z.literal(\"text\"),\n text: z.string(),\n marks: z.array(tiptapMarkSchema).optional(),\n }),\n z.object({\n type: z.string().min(1),\n attrs: z.record(z.unknown()).optional(),\n content: z.array(tiptapNodeSchema).optional(),\n marks: z.array(tiptapMarkSchema).optional(),\n }),\n ]),\n);\n\nexport const tiptapDocSchema = z.object({\n type: z.literal(\"doc\"),\n content: z.array(tiptapNodeSchema),\n});\n\nexport interface ValidateTiptapDocOptions {\n /** When set, every node `type` in the tree must be in this allowlist. */\n allowedNodeTypes?: string[];\n /** When set, every mark `type` must be in this allowlist. */\n allowedMarkTypes?: string[];\n}\n\nfunction zodIssuesToValidationIssues(issues: z.ZodIssue[]): ValidationIssue[] {\n return issues.map((issue) => ({\n code: issue.code,\n message: issue.message,\n path: issue.path.length > 0 ? issue.path.join(\".\") : undefined,\n }));\n}\n\nfunction collectNodeTypes(nodes: TiptapNode[]): string[] {\n const types: string[] = [];\n for (const node of nodes) {\n types.push(node.type);\n if (node.content?.length) {\n types.push(...collectNodeTypes(node.content));\n }\n }\n return types;\n}\n\nfunction collectMarkTypes(nodes: TiptapNode[]): string[] {\n const types: string[] = [];\n for (const node of nodes) {\n if (node.marks?.length) {\n types.push(...node.marks.map((mark) => mark.type));\n }\n if (node.content?.length) {\n types.push(...collectMarkTypes(node.content));\n }\n }\n return types;\n}\n\nfunction validateAllowedTypes(\n doc: TiptapDoc,\n allowedNodeTypes: string[] | undefined,\n allowedMarkTypes: string[] | undefined,\n): ValidationIssue[] {\n const issues: ValidationIssue[] = [];\n\n if (allowedNodeTypes) {\n const allowlist = new Set(allowedNodeTypes);\n for (const nodeType of collectNodeTypes(doc.content)) {\n if (!allowlist.has(nodeType)) {\n issues.push({\n code: \"invalid_node_type\",\n message: `Node type \"${nodeType}\" is not in allowedNodeTypes`,\n path: \"content\",\n });\n }\n }\n }\n\n if (allowedMarkTypes) {\n const allowlist = new Set(allowedMarkTypes);\n for (const markType of collectMarkTypes(doc.content)) {\n if (!allowlist.has(markType)) {\n issues.push({\n code: \"invalid_mark_type\",\n message: `Mark type \"${markType}\" is not in allowedMarkTypes`,\n path: \"content\",\n });\n }\n }\n }\n\n return issues;\n}\n\n/** Opt-in structural check for a Tiptap / ProseMirror document. */\nexport function validateTiptapDoc(\n doc: unknown,\n options: ValidateTiptapDocOptions = {},\n): ValidationResult {\n const parsed = tiptapDocSchema.safeParse(doc);\n if (!parsed.success) {\n return { ok: false, issues: zodIssuesToValidationIssues(parsed.error.issues) };\n }\n\n const typeIssues = validateAllowedTypes(\n parsed.data,\n options.allowedNodeTypes,\n options.allowedMarkTypes,\n );\n if (typeIssues.length > 0) {\n return { ok: false, issues: typeIssues };\n }\n\n return { ok: true, issues: [] };\n}\n","import * as cheerio from \"cheerio\";\n\nimport { isMigrationMediaRef, parseMigrationMediaRef } from \"../lib/media-urls.js\";\n\nexport interface ExpandMigrationMediaRefsResult {\n html: string;\n unresolved: string[];\n}\n\n/** Inline CSS `background` / `background-image: url(…)` (quoted or bare). */\nconst BACKGROUND_IMAGE_URL_PATTERN =\n /background(?:-image)?\\s*:[^;]*?url\\s*\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/gi;\n\nfunction tryExpandRef(\n value: string,\n resolvePublicUrl: (sourceId: string) => string | undefined,\n unresolved: Set<string>,\n): string | undefined {\n if (!isMigrationMediaRef(value)) return undefined;\n const sourceId = parseMigrationMediaRef(value);\n if (!sourceId) {\n unresolved.add(value);\n return undefined;\n }\n const publicUrl = resolvePublicUrl(sourceId);\n if (!publicUrl) {\n unresolved.add(value);\n return undefined;\n }\n return publicUrl;\n}\n\nfunction expandBackgroundUrlsInStyle(\n style: string,\n resolvePublicUrl: (sourceId: string) => string | undefined,\n unresolved: Set<string>,\n): string {\n return style.replace(BACKGROUND_IMAGE_URL_PATTERN, (full, quote: string, rawUrl: string) => {\n const expanded = tryExpandRef(rawUrl.trim(), resolvePublicUrl, unresolved);\n if (!expanded) return full;\n\n const urlCall = quote ? `url(${quote}${expanded}${quote})` : `url(${expanded})`;\n return full.replace(/url\\s*\\(\\s*(['\"]?)([^'\")]+)\\1\\s*\\)/i, urlCall);\n });\n}\n\nfunction expandSrcset(\n srcset: string,\n resolvePublicUrl: (sourceId: string) => string | undefined,\n unresolved: Set<string>,\n): string {\n return srcset\n .split(\",\")\n .map((entry) => {\n const trimmed = entry.trim();\n if (!trimmed) return entry;\n const [urlPart, descriptor] = trimmed.split(/\\s+/, 2);\n const expanded = tryExpandRef(urlPart ?? \"\", resolvePublicUrl, unresolved);\n if (!expanded) return entry;\n return descriptor ? `${expanded} ${descriptor}` : expanded;\n })\n .join(\", \");\n}\n\n/**\n * Expand OSS-14 `artinstack-migration://asset/…` refs to host CDN URLs.\n * Lookup (`migration_entities` → `publicUrl`) is host-supplied via `resolvePublicUrl`.\n */\nexport function expandMigrationMediaRefs(\n html: string,\n resolvePublicUrl: (sourceId: string) => string | undefined,\n): ExpandMigrationMediaRefsResult {\n if (!html.trim()) {\n return { html, unresolved: [] };\n }\n\n const $ = cheerio.load(html, { xml: false });\n const unresolved = new Set<string>();\n\n $(\"img\").each((_, element) => {\n const img = $(element);\n const src = img.attr(\"src\")?.trim();\n if (src) {\n const expanded = tryExpandRef(src, resolvePublicUrl, unresolved);\n if (expanded) img.attr(\"src\", expanded);\n }\n\n const srcset = img.attr(\"srcset\")?.trim();\n if (srcset) {\n img.attr(\"srcset\", expandSrcset(srcset, resolvePublicUrl, unresolved));\n }\n });\n\n $(\"[data-bg-image]\").each((_, element) => {\n const node = $(element);\n const bgImage = node.attr(\"data-bg-image\")?.trim();\n if (!bgImage) return;\n const expanded = tryExpandRef(bgImage, resolvePublicUrl, unresolved);\n if (expanded) node.attr(\"data-bg-image\", expanded);\n });\n\n $(\"[style]\").each((_, element) => {\n const node = $(element);\n const style = node.attr(\"style\");\n if (!style?.includes(\"background\")) return;\n const rewritten = expandBackgroundUrlsInStyle(style, resolvePublicUrl, unresolved);\n if (rewritten !== style) node.attr(\"style\", rewritten);\n });\n\n return {\n html: $.root().html() ?? html,\n unresolved: [...unresolved],\n };\n}\n"],"mappings":"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","names":["components","component","cheerio","SKIP_TAGS","INLINE_TAGS","tagNameOf","hasOnlyInlineContent","z","zodIssuesToValidationIssues","cheerio"]}
|