@artinstack/migrator 0.1.7 → 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 CHANGED
@@ -16,7 +16,8 @@ src/
16
16
  sinks/ filesystem export, MigrationSink interface
17
17
  cli/ artinstack-migrate
18
18
  transformers/ HtmlToGrapes, css-to-styles, inline image rewrite, media ref expand
19
- lib/ content-asset-urls, migration-media-ref, origin-url-rewrite
19
+ lib/ media-urls, utility (shared helpers)
20
+ test/ unit tests (mirrors src/ layout; vitest only)
20
21
  ```
21
22
 
22
23
  ## Install
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  isMigrationMediaRef,
3
3
  parseMigrationMediaRef
4
- } from "./chunk-BOYB6XRA.js";
4
+ } from "./chunk-WHGUE5FC.js";
5
5
 
6
6
  // src/transformers/html-to-grapes/index.ts
7
7
  import * as cheerio from "cheerio";
@@ -103,6 +103,10 @@ var DEFAULT_TYPES = {
103
103
  img: "image"
104
104
  };
105
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;
106
110
  var DEFAULT_LAYOUT_TYPE_MAP = {
107
111
  section: "section",
108
112
  row: "row",
@@ -116,6 +120,17 @@ function parseLayoutKind(attributes) {
116
120
  function resolveLayoutComponentType(kind, options) {
117
121
  return options.layoutTypeMap?.[kind] ?? DEFAULT_LAYOUT_TYPE_MAP[kind];
118
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
+ }
119
134
  function layoutAttributesForComponent(attributes) {
120
135
  if (!attributes) return void 0;
121
136
  const { [LAYOUT_DATA_ATTR]: _layout, ...rest } = attributes;
@@ -218,6 +233,25 @@ function walkNode($, $el, options) {
218
233
  }
219
234
  return component2;
220
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
+ }
221
255
  if (VOID_TAGS.has(tagName)) {
222
256
  return applyElementMeta(
223
257
  {
@@ -927,4 +961,4 @@ export {
927
961
  validateTiptapDoc,
928
962
  expandMigrationMediaRefs
929
963
  };
930
- //# sourceMappingURL=chunk-S4XYG4SM.js.map
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"]}
@@ -1,48 +1,28 @@
1
1
  import {
2
2
  SquarespaceCollectionClient,
3
3
  WORDPRESS_BUILDER_REGISTRY,
4
+ WORDPRESS_WIDGET_REGISTRY,
5
+ WP_WIDGET_PLACEHOLDER,
4
6
  enumerateSquarespaceEntities,
5
- linkToPath,
6
- sanitizeSlug,
7
7
  summarizeSquarespaceExport,
8
8
  validateSquarespaceExportFile
9
- } from "./chunk-MDSY3FEZ.js";
9
+ } from "./chunk-Z3L6N63Y.js";
10
10
  import {
11
- buildMigrationMediaUrlIndex,
12
11
  stampMigrationMediaRefs
13
- } from "./chunk-BOYB6XRA.js";
12
+ } from "./chunk-KYNKJ4XV.js";
13
+ import {
14
+ linkToPath,
15
+ sanitizeSlug
16
+ } from "./chunk-XRCF73DA.js";
14
17
  import {
18
+ buildContentMediaUrlIndex,
19
+ canonicalizeInlineAssetUrl,
15
20
  discoverContentAssetUrls,
16
21
  normalizeAssetUrl,
17
- resolveFeaturedContentAssetUrl
18
- } from "./chunk-XYP3VYDH.js";
19
-
20
- // src/lib/origin-url-rewrite.ts
21
- function rewriteOriginUrlsInText(text, config) {
22
- if (!text || config.rules.length === 0) return text;
23
- let result = text;
24
- for (const rule of config.rules) {
25
- if (typeof rule.match === "string") {
26
- if (!rule.match) continue;
27
- result = result.split(rule.match).join(rule.replace);
28
- continue;
29
- }
30
- result = result.replace(rule.match, rule.replace);
31
- }
32
- return result;
33
- }
34
- function createWpContentGatewayRewrite(gatewayBase, publicOrigin) {
35
- const normalizedGateway = gatewayBase.replace(/\/$/, "");
36
- const normalizedPublic = publicOrigin.replace(/\/$/, "");
37
- return {
38
- rules: [
39
- {
40
- match: `${normalizedGateway}/wp-content/`,
41
- replace: `${normalizedPublic}/wp-content/`
42
- }
43
- ]
44
- };
45
- }
22
+ parseMigrationMediaRef,
23
+ resolveFeaturedContentAssetUrl,
24
+ rewriteOriginUrlsInText
25
+ } from "./chunk-WHGUE5FC.js";
46
26
 
47
27
  // src/parsers/wordpress/parse-wxr.ts
48
28
  import { readFile } from "fs/promises";
@@ -316,16 +296,195 @@ function stripLegacyTokens(content, tokens) {
316
296
  function detectThemes(content, registry) {
317
297
  return registry.filter((theme) => theme.detect.test(content));
318
298
  }
299
+ function extractBareOrQuotedParam(params, name) {
300
+ const quoted = extractQuotedParam(params, name);
301
+ if (quoted) return quoted;
302
+ const pattern = new RegExp(`\\b${escapeRegExp(name)}\\s*=\\s*([^\\s"'\\]]+)`, "i");
303
+ const match = pattern.exec(params);
304
+ return match?.[1]?.trim() || void 0;
305
+ }
306
+ function emitWidgetStub(widget, attrs, tag = "div") {
307
+ const parts = [`data-wp-widget="${escapeLayoutAttr(widget)}"`];
308
+ for (const [key, value] of Object.entries(attrs)) {
309
+ if (value) parts.push(`${key}="${escapeLayoutAttr(value)}"`);
310
+ }
311
+ return `<${tag} ${parts.join(" ")}>${WP_WIDGET_PLACEHOLDER}</${tag}>`;
312
+ }
313
+ function normalizeVideoEmbedUrl(raw) {
314
+ const trimmed = raw.trim();
315
+ if (!trimmed || trimmed.startsWith("data:")) return void 0;
316
+ try {
317
+ const url = new URL(trimmed.startsWith("//") ? `https:${trimmed}` : trimmed);
318
+ const host = url.hostname.replace(/^www\./, "").replace(/^m\./, "");
319
+ if (host === "youtu.be") {
320
+ const id = url.pathname.split("/").filter(Boolean)[0];
321
+ if (id) {
322
+ return { provider: "youtube", embedUrl: `https://www.youtube-nocookie.com/embed/${id}` };
323
+ }
324
+ }
325
+ if (host === "youtube.com" || host === "youtube-nocookie.com") {
326
+ const embedMatch = url.pathname.match(/\/embed\/([^/?#]+)/);
327
+ if (embedMatch?.[1]) {
328
+ const start = url.searchParams.get("start");
329
+ const suffix = start ? `?start=${start}` : "";
330
+ return {
331
+ provider: "youtube",
332
+ embedUrl: `https://www.youtube-nocookie.com/embed/${embedMatch[1]}${suffix}`
333
+ };
334
+ }
335
+ const videoId = url.searchParams.get("v");
336
+ if (videoId) {
337
+ const t = url.searchParams.get("t") ?? url.searchParams.get("start");
338
+ const startSeconds = t?.endsWith("s") ? t.slice(0, -1) : t;
339
+ const suffix = startSeconds ? `?start=${startSeconds}` : "";
340
+ return {
341
+ provider: "youtube",
342
+ embedUrl: `https://www.youtube-nocookie.com/embed/${videoId}${suffix}`
343
+ };
344
+ }
345
+ }
346
+ if (host === "vimeo.com") {
347
+ const segments = url.pathname.split("/").filter(Boolean);
348
+ const id = segments[segments.length - 1];
349
+ if (id && /^\d+$/.test(id)) {
350
+ return { provider: "vimeo", embedUrl: `https://player.vimeo.com/video/${id}` };
351
+ }
352
+ }
353
+ if (host === "player.vimeo.com") {
354
+ const match = url.pathname.match(/\/video\/(\d+)/);
355
+ if (match?.[1]) {
356
+ return { provider: "vimeo", embedUrl: `https://player.vimeo.com/video/${match[1]}` };
357
+ }
358
+ }
359
+ } catch {
360
+ return void 0;
361
+ }
362
+ return void 0;
363
+ }
364
+ function emitVideoWidgetFromParams(params, inner) {
365
+ const url = extractShortcodeParam(params, ["url", "src", "video", "link", "youtube_url", "vimeo_url"]) ?? inner.trim().match(/^https?:\/\/\S+/)?.[0];
366
+ if (!url) {
367
+ return emitWidgetStub("video", { "data-video-provider": "external" });
368
+ }
369
+ const normalized = normalizeVideoEmbedUrl(url);
370
+ if (normalized) {
371
+ return emitWidgetStub("video", {
372
+ "data-video-provider": normalized.provider,
373
+ "data-embed-url": normalized.embedUrl
374
+ });
375
+ }
376
+ if (/\.(mp4|webm|ogg)(\?|#|$)/i.test(url)) {
377
+ return emitHtmlTag("video", url);
378
+ }
379
+ return emitWidgetStub("video", {
380
+ "data-video-provider": "external",
381
+ "data-embed-url": url
382
+ });
383
+ }
384
+ function flattenMapShortcodes(content, widgetRegistry) {
385
+ let html = content;
386
+ for (const prefix of widgetRegistry.mapShortcodePrefixes) {
387
+ const pattern = new RegExp(
388
+ `\\[${escapeRegExp(prefix)}\\b([^\\]]*)\\]\\s*(?:\\[\\/${escapeRegExp(prefix)}\\b[^\\]]*\\])?`,
389
+ "gi"
390
+ );
391
+ html = html.replace(pattern, (_, params) => {
392
+ const embedUrl = extractShortcodeParam(params, ["embed_url", "url", "src", "map_url"]);
393
+ const query = extractBareOrQuotedParam(params, "address") ?? extractBareOrQuotedParam(params, "q");
394
+ return emitWidgetStub("map", {
395
+ ...embedUrl?.includes("google.com/maps") ? { "data-embed-url": embedUrl } : {},
396
+ ...query && !embedUrl ? { "data-wp-map-query": query } : {}
397
+ });
398
+ });
399
+ }
400
+ return html;
401
+ }
402
+ function flattenContactFormShortcodes(content, widgetRegistry) {
403
+ let html = content;
404
+ for (const rule of widgetRegistry.contactFormRules) {
405
+ const pattern = new RegExp(
406
+ `\\[${escapeRegExp(rule.tag)}\\b([^\\]]*)\\]\\s*(?:\\[\\/${escapeRegExp(rule.tag)}\\b[^\\]]*\\])?`,
407
+ "gi"
408
+ );
409
+ html = html.replace(pattern, (_, params) => {
410
+ const id = extractBareOrQuotedParam(params, rule.idParam);
411
+ return emitWidgetStub(
412
+ "contact-form",
413
+ {
414
+ "data-wp-form-source": rule.source,
415
+ ...id ? { "data-wp-form-id": id } : {}
416
+ },
417
+ "section"
418
+ );
419
+ });
420
+ }
421
+ return html;
422
+ }
423
+ function flattenGalleryShortcodes(content, widgetRegistry) {
424
+ const tag = escapeRegExp(widgetRegistry.galleryShortcode);
425
+ const pattern = new RegExp(`\\[${tag}\\b([^\\]]*)\\](?:\\s*\\[\\/${tag}\\])?`, "gi");
426
+ return content.replace(pattern, (_, params) => {
427
+ const ids = extractBareOrQuotedParam(params, "ids");
428
+ const idList = ids?.split(",").map((part) => part.trim()).filter((part) => /^\d+$/.test(part));
429
+ if (idList?.length) {
430
+ const images = idList.map((id) => `<img data-wp-attachment-id="${escapeLayoutAttr(id)}" alt="" />`).join("");
431
+ return `<figure data-wp-inline-gallery>${images}</figure>`;
432
+ }
433
+ const category = extractBareOrQuotedParam(params, "category") ?? extractBareOrQuotedParam(params, "type");
434
+ return emitWidgetStub("portfolio", {
435
+ "data-wp-gallery-dynamic": "1",
436
+ ...category ? { "data-wp-portfolio-category": category } : {}
437
+ });
438
+ });
439
+ }
440
+ function flattenPortfolioShortcodes(content, widgetRegistry) {
441
+ const tag = escapeRegExp(widgetRegistry.portfolioShortcode);
442
+ const pattern = new RegExp(`\\[${tag}\\b([^\\]]*)\\](?:\\s*\\[\\/${tag}\\])?`, "gi");
443
+ return content.replace(pattern, (_, params) => {
444
+ const category = extractBareOrQuotedParam(params, "category");
445
+ const slug = extractBareOrQuotedParam(params, "slug");
446
+ return emitWidgetStub("portfolio", {
447
+ ...category ? { "data-wp-portfolio-category": category } : {},
448
+ ...slug ? { "data-wp-portfolio-slug": slug } : {}
449
+ });
450
+ });
451
+ }
452
+ function flattenVideoShortcodes(content, widgetRegistry) {
453
+ let html = content;
454
+ for (const prefix of widgetRegistry.videoShortcodePrefixes) {
455
+ const wrapped = new RegExp(
456
+ `\\[${escapeRegExp(prefix)}\\b([^\\]]*)\\]([\\s\\S]*?)\\[\\/${escapeRegExp(prefix)}\\b[^\\]]*\\]`,
457
+ "gi"
458
+ );
459
+ html = html.replace(
460
+ wrapped,
461
+ (_, params, inner) => emitVideoWidgetFromParams(params, inner)
462
+ );
463
+ const selfClosing = new RegExp(
464
+ `\\[${escapeRegExp(prefix)}\\b([^\\]]*)\\]`,
465
+ "gi"
466
+ );
467
+ html = html.replace(selfClosing, (_, params) => emitVideoWidgetFromParams(params, ""));
468
+ }
469
+ return html;
470
+ }
471
+ function flattenWordPressWidgets(content, widgetRegistry = WORDPRESS_WIDGET_REGISTRY) {
472
+ let html = content;
473
+ html = flattenGalleryShortcodes(html, widgetRegistry);
474
+ html = flattenPortfolioShortcodes(html, widgetRegistry);
475
+ html = flattenMapShortcodes(html, widgetRegistry);
476
+ html = flattenContactFormShortcodes(html, widgetRegistry);
477
+ html = flattenVideoShortcodes(html, widgetRegistry);
478
+ return html;
479
+ }
319
480
  function flattenWordPressBuilders(content, options = {}) {
320
481
  if (!content.trim()) {
321
482
  return { html: content, detectedThemes: [] };
322
483
  }
323
484
  const registry = options.registry ?? WORDPRESS_BUILDER_REGISTRY;
324
485
  const themes = detectThemes(content, registry);
325
- if (themes.length === 0) {
326
- return { html: content, detectedThemes: [] };
327
- }
328
- let html = content;
486
+ const widgetRegistry = options.widgetRegistry ?? WORDPRESS_WIDGET_REGISTRY;
487
+ let html = flattenWordPressWidgets(content, widgetRegistry);
329
488
  for (const theme of themes) {
330
489
  for (const rule of theme.wrapperRules ?? []) {
331
490
  html = convertWrapperRule(html, rule);
@@ -439,11 +598,11 @@ function buildAttachmentIndex(items, originUrlRewrite) {
439
598
  for (const item of items) {
440
599
  if (textValue(item.post_type) !== "attachment") continue;
441
600
  const id = textValue(item.post_id);
442
- let url = textValue(item.attachment_url) || textValue(item.link);
443
- if (!id || !url) continue;
444
- if (originUrlRewrite) {
445
- url = rewriteOriginUrlsInText(url, originUrlRewrite);
446
- }
601
+ const rawUrl = textValue(item.attachment_url) || textValue(item.link);
602
+ if (!id || !rawUrl) continue;
603
+ const canonical = canonicalizeInlineAssetUrl(rawUrl, originUrlRewrite);
604
+ if (!canonical) continue;
605
+ const url = canonical.canonicalUrl;
447
606
  const filename = basename(new URL(url, "http://local.invalid").pathname) || `attachment-${id}`;
448
607
  index.set(id, {
449
608
  sourceUrl: url,
@@ -502,22 +661,24 @@ function collectTaxonomies(items) {
502
661
  }
503
662
  return { categories, tags };
504
663
  }
505
- function collectInlineAssets(html, attachmentIndex, seenUrls, exportedAt) {
664
+ function collectInlineAssets(html, attachmentIndex, seenUrls, exportedAt, originUrlRewrite) {
506
665
  const assets = [];
507
- for (const src of discoverContentAssetUrls(html)) {
508
- if (seenUrls.has(src)) continue;
509
- seenUrls.add(src);
666
+ for (const discovered of discoverContentAssetUrls(html)) {
667
+ const canonical = canonicalizeInlineAssetUrl(discovered, originUrlRewrite);
668
+ if (!canonical) continue;
669
+ if (seenUrls.has(canonical.canonicalUrl)) continue;
670
+ seenUrls.add(canonical.canonicalUrl);
510
671
  let filename;
511
672
  try {
512
- filename = basename(new URL(src, "http://local.invalid").pathname) || "inline-asset";
673
+ filename = basename(new URL(canonical.canonicalUrl, "http://local.invalid").pathname) || "inline-asset";
513
674
  } catch {
514
675
  filename = "inline-asset";
515
676
  }
516
677
  assets.push({
517
678
  type: "asset",
518
- source: sourceMeta(`url:${src}`, src, exportedAt),
519
- sourceId: `url:${src}`,
520
- sourceUrl: src,
679
+ source: sourceMeta(canonical.sourceId, canonical.canonicalUrl, exportedAt),
680
+ sourceId: canonical.sourceId,
681
+ sourceUrl: canonical.canonicalUrl,
521
682
  filename,
522
683
  mimeType: guessMime(filename)
523
684
  });
@@ -538,12 +699,15 @@ function preprocessContent(rawHtml, options) {
538
699
  }
539
700
  return html;
540
701
  }
541
- function resolveFeaturedAssetSourceId(thumbnailId, attachmentIndex, contentHtml) {
702
+ function resolveFeaturedAssetSourceId(thumbnailId, attachmentIndex, contentHtml, originUrlRewrite) {
542
703
  if (thumbnailId && attachmentIndex.has(thumbnailId)) {
543
704
  return thumbnailId;
544
705
  }
545
706
  const featuredUrl = resolveFeaturedContentAssetUrl(contentHtml);
546
- return featuredUrl ? `url:${featuredUrl}` : void 0;
707
+ if (!featuredUrl) return void 0;
708
+ const fromRef = parseMigrationMediaRef(featuredUrl);
709
+ if (fromRef) return fromRef;
710
+ return canonicalizeInlineAssetUrl(featuredUrl, originUrlRewrite)?.sourceId;
547
711
  }
548
712
  function maybeRewriteUrl(url, config) {
549
713
  if (!url) return void 0;
@@ -557,12 +721,6 @@ async function* enumerateWxrEntities(options) {
557
721
  const { categories, tags } = collectTaxonomies(items);
558
722
  const seenAssetUrls = /* @__PURE__ */ new Set();
559
723
  const emittedAttachmentIds = /* @__PURE__ */ new Set();
560
- const attachmentUrlIndex = buildMigrationMediaUrlIndex(
561
- [...attachmentIndex.entries()].map(([sourceId, entry]) => ({
562
- sourceId,
563
- sourceUrl: entry.sourceUrl
564
- }))
565
- );
566
724
  for (const category of categories.values()) {
567
725
  yield category;
568
726
  }
@@ -596,19 +754,30 @@ async function* enumerateWxrEntities(options) {
596
754
  contentHtml,
597
755
  attachmentIndex,
598
756
  seenAssetUrls,
599
- options.exportedAt
757
+ options.exportedAt,
758
+ options.originUrlRewrite
600
759
  );
601
760
  for (const asset of inlineAssets) {
602
761
  yield asset;
603
762
  }
604
763
  if (options.stampMigrationMediaRefs !== false) {
605
- const urlIndex = new Map(attachmentUrlIndex);
606
- for (const asset of inlineAssets) {
607
- urlIndex.set(asset.sourceUrl, asset.sourceId);
608
- const normalized = normalizeAssetUrl(asset.sourceUrl);
609
- if (normalized) urlIndex.set(normalized, asset.sourceId);
610
- }
611
- contentHtml = stampMigrationMediaRefs(contentHtml, { urlToSourceId: urlIndex }).html;
764
+ const urlIndex = buildContentMediaUrlIndex(
765
+ [
766
+ ...[...attachmentIndex.entries()].map(([sourceId, entry]) => ({
767
+ sourceId,
768
+ sourceUrl: entry.sourceUrl
769
+ })),
770
+ ...inlineAssets.map((asset) => ({
771
+ sourceId: asset.sourceId,
772
+ sourceUrl: asset.sourceUrl
773
+ }))
774
+ ],
775
+ options.originUrlRewrite
776
+ );
777
+ contentHtml = stampMigrationMediaRefs(contentHtml, {
778
+ urlToSourceId: urlIndex,
779
+ originUrlRewrite: options.originUrlRewrite
780
+ }).html;
612
781
  }
613
782
  const categorySlugs = [];
614
783
  const tagSlugs = [];
@@ -624,7 +793,8 @@ async function* enumerateWxrEntities(options) {
624
793
  const featuredAssetSourceId = resolveFeaturedAssetSourceId(
625
794
  thumbnailId,
626
795
  attachmentIndex,
627
- contentHtml
796
+ contentHtml,
797
+ options.originUrlRewrite
628
798
  );
629
799
  const post = {
630
800
  type: "post",
@@ -2680,8 +2850,6 @@ function getAdapter(platform) {
2680
2850
  }
2681
2851
 
2682
2852
  export {
2683
- rewriteOriginUrlsInText,
2684
- createWpContentGatewayRewrite,
2685
2853
  wordpressAdapter,
2686
2854
  SMUGMUG_API_BASE,
2687
2855
  SMUGMUG_OAUTH_ENDPOINTS,
@@ -2697,4 +2865,4 @@ export {
2697
2865
  wixAdapter,
2698
2866
  getAdapter
2699
2867
  };
2700
- //# sourceMappingURL=chunk-KF7G7DM6.js.map
2868
+ //# sourceMappingURL=chunk-CB5KRANW.js.map